This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: g++ not using ipa-sra for small struct / class
- From: Juan Cabrera <jjcp dot 91 at gmail dot com>
- To: wilhelm dot meier at hs-kl dot de
- Cc: gcc-help at gcc dot gnu dot org
- Date: Tue, 4 Jul 2017 10:18:30 -0300
- Subject: Re: g++ not using ipa-sra for small struct / class
- Authentication-results: sourceware.org; auth=none
- References: <6b855615-1ec4-fa20-6fd5-55942ee5a2ef@hs-kl.de>
Hello,
I tried compiling your code with g++ 7.1 and clang 4 and both generate
the same code (on Intel)
If you prepend `static` to the template declaration you'll get
something similar to what you want
(i.e: replace `void f(const T& x) __attribute__((noinline));` with
`static void f(const T& x) __attribute__((noinline));`)
Out of curiosity, why are you using the `noinline` attribute?
Regards,
Juan.
2017-06-28 5:56 GMT-03:00 Wilhelm Meier <wilhelm.meier@hs-kl.de>:
> Hi all,
>
> in the following example g++ (at least avr-g++) doesn't optimize the
> call f(n2) to use a single value register as in the case of f(n1). Is
> this a bug or can one use some option to enforce that.
>
> Version: gcc-7.1.0
>
> #include <cstdint>
> #include <type_traits>
>
> struct A {
> A() = default;
> A(const volatile A& o) : m1(o.m1) {}
> uint8_t m1{0};
> };
>
> volatile uint8_t v;
>
> template<typename T>
> void f(const T& x) __attribute__((noinline));
> template<typename T>
> void f(const T& x) {
> if constexpr(std::is_same<std::remove_cv_t<T>, A>::value) {
> v = x.m1;
> }
> else {
> v = x;
> }
> }
>
> volatile uint8_t v1;
> uint8_t n1;
>
> volatile A v2;
> A n2;
>
> int main() {
> f(v1);
> f(n1);
> f(v2);
> f(n2);
> }
>
> The generated machine code:
>
> .text
> .type void f<unsigned char>(unsigned char const&) [clone
> .isra.0], @function
> void f<unsigned char>(unsigned char const&) [clone .isra.0]:
> sts v,r24 ; v, ISRA.2
> ret
> .size void f<unsigned char>(unsigned char const&) [clone
> .isra.0], .-void f<unsigned char>(unsigned char const&) [clone .isra.
> 0]
> .section .text._Z1fIVhEvRKT_,"axG",@progbits,void
> f<unsigned char volatile>(unsigned char volatile const&),comdat
> .weak void f<unsigned char volatile>(unsigned char volatile
> const&)
> .type void f<unsigned char volatile>(unsigned char volatile
> const&), @function
> void f<unsigned char volatile>(unsigned char volatile const&):
> movw r30,r24 ; , x
> ld r24,Z ; _1, *x_3(D)
> sts v,r24 ; v, _1
> ret
> .size void f<unsigned char volatile>(unsigned char volatile
> const&), .-void f<unsigned char volatile>(unsigned char volatile c
> onst&)
> .section .text._Z1fIV1AEvRKT_,"axG",@progbits,void f<A
> volatile>(A volatile const&),comdat
> .weak void f<A volatile>(A volatile const&)
> .type void f<A volatile>(A volatile const&), @function
> void f<A volatile>(A volatile const&):
> movw r30,r24 ; , x
> ld r24,Z ; _1, x_3(D)->m1
> sts v,r24 ; v, _1
> ret
> .size void f<A volatile>(A volatile const&), .-void f<A
> volatile>(A volatile const&)
> .section .text._Z1fI1AEvRKT_,"axG",@progbits,void f<A>(A
> const&),comdat
> .weak void f<A>(A const&)
> .type void f<A>(A const&), @function
> void f<A>(A const&):
> movw r30,r24 ; , x
> ld r24,Z ; _1, x_3(D)->m1
> sts v,r24 ; v, _1
> ret
> .size void f<A>(A const&), .-void f<A>(A const&)
> .section .text.startup,"ax",@progbits
> .type main, @function
> main:
> ldi r24,lo8(v1) ; ,
> ldi r25,hi8(v1) ; ,
> call void f<unsigned char volatile>(unsigned char volatile
> const&) ;
> lds r24,n1 ; , n1
> call void f<unsigned char>(unsigned char const&) [clone .isra.0]
> ;
> ldi r24,lo8(v2) ; ,
> ldi r25,hi8(v2) ; ,
> call void f<A volatile>(A volatile const&) ;
> ldi r24,lo8(n2) ; ,
> ldi r25,hi8(n2) ; ,
> call void f<A>(A const&) ;
> ldi r25,0 ;
> ldi r24,0 ;
> ret
> .size main, .-main
> .section .bss
> .type n2, @object
> .size n2, 1
> n2:
> .zero 1
>