I add -Os -Wall flags to every avr-g++ command. During coding I've noticed g++
adds plenty of unnecessary assembly to output file. I'll try to check it with
gcc 4.x but currently I fail to compile it.

Problem is related to static initialization of template class/struct variable.
Following code snippet should explain the issue. I've tried to make it minimal.
I'd be happy even with some work-around like __attribute__ but not with 'use
macros instead' which I hear constantly...

Hope this helps someone.

/*
Reading specs from /usr/lib/gcc/avr/3.4.6/specs
Configured with:
/var/tmp/cross/avr/portage/cross-avr/gcc-3.4.6/work/gcc-3.4.6/configure
--prefix=/usr --bindir=/usr/x86_64-pc-linux-gnu/avr/gcc-bin/3.4.6
--includedir=/usr/lib/gcc/avr/3.4.6/include
--datadir=/usr/share/gcc-data/avr/3.4.6
--mandir=/usr/share/gcc-data/avr/3.4.6/man
--infodir=/usr/share/gcc-data/avr/3.4.6/info
--with-gxx-include-dir=/usr/lib/gcc/avr/3.4.6/include/g++-v3
--host=x86_64-pc-linux-gnu --target=avr --build=x86_64-pc-linux-gnu
--disable-altivec --enable-nls --without-included-gettext --with-system-zlib
--disable-checking --disable-werror --enable-secureplt
--disable-libunwind-exceptions --disable-libgcj --enable-languages=c,c++
--enable-shared --disable-threads
Thread model: single
gcc version 3.4.6 (Gentoo 3.4.6, ssp-3.4.5-1.0, pie-8.7.9)

(Can't successfully build 4.x yet)
i686 4.1.2 version also generates additional code in one case
but the code is much smaller.
*/

/* Declaration of Real */
struct stub {
        float D;

        stub() {}
        stub(float A) : D(A) {}

        inline operator float&() { return D; }
        inline operator const float&() const { return D; }
};

//typedef float Real;  /* No problems if real is simply a float */
typedef stub Real;

/*** Template using previously defined type ***/
#define OUTER 0 /* No problem if we use static variable not from the template
*/

#if OUTER == 1
static Real Result;
#endif

template<int Dummy>     /* When there's no template code is ok */
struct Avg {

#if OUTER == 0
        static Real Result;
#endif
        static const Real &Push(const Real Value) {
                Result *= Dummy;
//              Result *= 20 /* No problems if we won't touch dummy */
                return Result;
        }
};

#if OUTER == 0
template<int Dummy>
Real Avg<Dummy>::Result;
#endif

int main()
{
        Avg<20>::Push(1.0);
        return 0;
}


#if 0
Unnecessary code generated looks like this:

        .type   _GLOBAL__I_main, @function
_GLOBAL__I_main:
/* prologue: frame size=0 */
        push r2
        push r3
        push r4
        push r5
        push r6
        push r7
        push r8
        push r9
        push r10
        push r11
        push r12
        push r13
        push r14
        push r15
        push r16
        push r17
/* prologue end (size=16) */
        lds r18,_ZGVN3AvgILi20EE6ResultE
        lds r19,_ZGVN3AvgILi20EE6ResultE+1
        lds r20,_ZGVN3AvgILi20EE6ResultE+2
        lds r21,_ZGVN3AvgILi20EE6ResultE+3
        lds r22,_ZGVN3AvgILi20EE6ResultE+4
        lds r23,_ZGVN3AvgILi20EE6ResultE+5
        lds r24,_ZGVN3AvgILi20EE6ResultE+6
        lds r25,_ZGVN3AvgILi20EE6ResultE+7
        ldi r30,lo8(1)
        mov r2,r30
        clr r3
        mov r4,r3
        mov r5,r3
        mov r6,r3
        mov r7,r3
        mov r8,r3
        mov r9,r3
        mov r10,r18
        add r10,r2
        mov r30,r2
        cp r10,r18
        brlo .L7
        mov r30,r3
.L7:
        mov r11,r19
        add r11,r3
        ldi r26,lo8(1)
        cp r11,r19
        brlo .L8
        ldi r26,lo8(0)
.L8:
        add r30,r11
        ldi r31,lo8(1)
        cp r30,r11
        brlo .L9
        ldi r31,lo8(0)
.L9:
        or r26,r31
        mov r11,r30
        mov r12,r20
        add r12,r4
        ldi r27,lo8(1)
        cp r12,r20
        brlo .L10
        ldi r27,lo8(0)
.L10:
        mov r30,r26
        add r30,r12
        ldi r31,lo8(1)
        cp r30,r12
        brlo .L11
        ldi r31,lo8(0)
.L11:
        or r27,r31
        mov r12,r30
        mov r13,r21
        add r13,r5
        ldi r26,lo8(1)
        cp r13,r21
        brlo .L12
        ldi r26,lo8(0)
.L12:
        mov r30,r27
        add r30,r13
        ldi r31,lo8(1)
        cp r30,r13
        brlo .L13
        ldi r31,lo8(0)
.L13:
        or r26,r31
        mov r13,r30
        mov r14,r22
        add r14,r6
        ldi r27,lo8(1)
        cp r14,r22
        brlo .L14
        ldi r27,lo8(0)
.L14:
        mov r30,r26
        add r30,r14
        ldi r31,lo8(1)
        cp r30,r14
        brlo .L15
        ldi r31,lo8(0)
.L15:
        or r27,r31
        mov r14,r30
        mov r15,r23
        add r15,r7
        ldi r26,lo8(1)
        cp r15,r23
        brlo .L16
        ldi r26,lo8(0)
.L16:
        mov r30,r27
        add r30,r15
        ldi r31,lo8(1)
        cp r30,r15
        brlo .L17
        ldi r31,lo8(0)
.L17:
        or r26,r31
        mov r15,r30
        mov r16,r24
        add r16,r8
        ldi r27,lo8(1)
        cp r16,r24
        brlo .L18
        ldi r27,lo8(0)
.L18:
        mov r31,r26
        add r31,r16
        ldi r30,lo8(1)
        cp r31,r16
        brlo .L19
        ldi r30,lo8(0)
.L19:
        or r30,r27
        mov r17,r25
        add r17,r9
        add r30,r17
        sts _ZGVN3AvgILi20EE6ResultE,r10
        sts _ZGVN3AvgILi20EE6ResultE+1,r11
        sts _ZGVN3AvgILi20EE6ResultE+2,r12
        sts _ZGVN3AvgILi20EE6ResultE+3,r13
        sts _ZGVN3AvgILi20EE6ResultE+4,r14
        sts _ZGVN3AvgILi20EE6ResultE+5,r15
        sts _ZGVN3AvgILi20EE6ResultE+6,r31
        sts _ZGVN3AvgILi20EE6ResultE+7,r30
/* epilogue: frame size=0 */
        pop r17
        pop r16
        pop r15
        pop r14
        pop r13
        pop r12
        pop r11
        pop r10
        pop r9
        pop r8
        pop r7
        pop r6
        pop r5
        pop r4
        pop r3
        pop r2
        ret

#endif


-- 
           Summary: Lots of (possibly) unnecesary static initialization code
                    generated.
           Product: gcc
           Version: 3.4.6
            Status: UNCONFIRMED
          Severity: enhancement
          Priority: P3
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: bla at thera dot be
 GCC build triplet: x86_64-pc-linux-gnu
  GCC host triplet: x86_64-pc-linux-gnu
GCC target triplet: avr


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36310

Reply via email to