This is distilled from PR42500. The same testcase doesn't show a problem if
compiled with a C compiler only.

Why does the gimple for the following testcase contain ? 

extern "C" void foo(int a[4]);
extern "C" void bar(int a, int b, int c, int d)
{
  int v[4] = { a, b, c, d};
     foo(v);
     foo(v);
}


in .004t.gimple

void bar(int, int, int, int) (int a, int b, int c, int d)
{
  int v[4];

  v = {};
  v[0] = a;
  v[1] = b;
  v[2] = c;
  v[3] = d;
  foo (&v[0]);
  foo (&v[0]);
}

even when all members of the array have been initialized  in your original
testcase. I wonder if this can be eliminated as a part of the lowering process
to GIMPLE in the C++ frontend rather than any other place. 

At -O2 the RTL optimizers remove 2 of the stores but there are unnecessary
stores of 0 to memory locations at [sp+8] , [sp+12] and the code generated is
as follows. (Instructions marked A and B below).

bar:
        stmfd   sp!, {r4, lr}
        .save {r4, lr}
.LCFI0:
        .pad #16
        sub     sp, sp, #16
.LCFI1:
        mov     lr, #0
        add     ip, sp, #8
        str     lr, [ip], #4  // A
        str     r0, [sp, #0] 
        mov     r0, sp
        str     lr, [ip, #0]  // B
        stmib   sp, {r1, r2, r3}        @ phole stm
        bl      foo
        mov     r0, sp
        mov     r4, sp             
        bl      foo
        add     sp, sp, #16
        ldmfd   sp!, {r4, lr}
        bx      lr




At -Os because the zero initializer is in the form of a memset - the RTL
optimizers don't remove anything and the code generated is as follows. 


bar:
        .fnstart
.LFB0:
        @ args = 0, pretend = 0, frame = 16
        @ frame_needed = 0, uses_anonymous_args = 0
        stmfd   sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, lr}
        .save {r0, r1, r2, r3, r4, r5, r6, r7, r8, lr}
.LCFI0:
        mov     r6, r0
        mov     r5, r1
        mov     r4, r2
        mov     r1, #0
        mov     r2, #16
        mov     r0, sp
        mov     r8, r3
        bl      memset
        mov     r0, sp
        str     r6, [sp, #0]
        str     r5, [sp, #4]
        mov     r7, sp
        str     r4, [sp, #8]
        str     r8, [sp, #12]
        bl      foo
        mov     r0, sp
        bl      foo
        ldmfd   sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, pc}



If I change the testcase to use the extended initializer list in c++0x and
gnu++0x . There is an unnecessary move from sp to r4 but that is the subject of
PR42500.


void foo(int a[4]);
void bar(int a, int b, int c, int d)
{
  int v[4] ;
  v = { a, b, c, d};
     foo(v);
     foo(v);
}
bar:
        .fnstart
.LFB0:
        @ args = 0, pretend = 0, frame = 16
        @ frame_needed = 0, uses_anonymous_args = 0
        stmfd   sp!, {r0, r1, r2, r3, r4, lr}
        .save {r0, r1, r2, r3, r4, lr}
.LCFI0:
        str     r0, [sp, #0]
        mov     r0, sp
        stmib   sp, {r1, r2, r3}        @ phole stm
        bl      foo
        mov     r0, sp
        mov     r4, sp
        bl      foo
        ldmfd   sp!, {r0, r1, r2, r3, r4, pc}
.LFE0:
        .fnend


cheers
Ramana


-- 
           Summary: Unnecessary generation of a zero initializer for array
                    with C++
           Product: gcc
           Version: 4.5.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: ramana at gcc dot gnu dot org
  GCC host triplet: x86_64 linux gnu
GCC target triplet: arm-eabi


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

Reply via email to