Compile the attached source code with options -Os -fpic -mthumb, gcc generates following code for the constructor:
push {r4, r5, r6, r7, lr} .LCFI2: .pad #12 sub sp, sp, #12 .LCFI3: str r3, [sp] add r3, sp, #32 //A, B ldrb r3, [r3] //A, B ldr r5, .L14 mov r4, r0 mov r7, r2 mov r6, r1 str r3, [sp, #4] //A bl _ZN1AC2Ev ldr r3, .L14+4 .LPIC2: add r5, pc ldr r3, [r5, r3] add r3, r3, #8 mov r1, sp //A str r3, [r4] add r2, r1, #4 //A, C mov r3, r4 add r3, r3, #42 ldrb r1, [r2] //A, C strb r7, [r3] add r3, r3, #1 // C strb r1, [r3] //A, C cmp r6, #0 beq .L9 ldr r2, [sp] mov r3, #2 cmp r2, #0 bne .L12 mov r3, #1 .L12: strh r3, [r4, #40] b .L11 .L9: strh r6, [r4, #40] .L11: add sp, sp, #12 mov r0, r4 @ sp needed for prologue pop {r4, r5, r6, r7} pop {r1} bx r1 1. The instructions marked A move a byte from parameter to the object body, but it first moves that parameter to stack [sp, 4], then move the value from [sp,4] to the target object. The move to [sp, 4] is redundant. 2. The Instructions marked B load a byte from the stack, then store the whole word into another place on the stack. Since later instructions load a byte from the new space, we can simply move the whole word at the first place, so instructions marked as B can be reduced to one instruction "ldr r3, [sp, 32]" 3. Instructions marked C can be simplified to ldrb r1, [r1, 4] strb r1, [r3, 1] 4. Why not use "pop {r4, r5, r6, r7, pc}" as the epilogue? -- Summary: redundant memory move from parameter space to spill space Product: gcc Version: 4.5.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: carrot at google dot com GCC build triplet: i686-linux GCC host triplet: i686-linux GCC target triplet: arm-eabi http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42235