2015-12-21 30 views
7

E 'noto che alcune piccole strutture senza copy-ctor non banale e nessun dtor non banale sono passate nei registri.Perché gcc emette accessi non necessari alla memoria quando si passa a una struttura banale per valore?

Citando ARM Procedural Call Standard:

tipi fondamentali di dimensioni superiori a 32 bit possono essere passati come parametri a, o restituito come risultato di, chiamate di funzione. Quando questi tipi sono nei registri principali, si applicano le seguenti regole:  Un tipo di parola doppia viene passato in due registri consecutivi (ad es., R0 e r1 o r2 e r3). Il contenuto di registri è come se il valore fosse stato caricato dalla rappresentazione della memoria con una singola istruzione LDM.

E infatti, posso facilmente confermarlo con clang. gcc tuttavia emette una serie di carichi di memoria e memorizza per tale semplice frammento di codice:

struct Trivial { 
    int i1; 
    int i2; 
}; 

int foo(Trivial t) 
{ 
    return t.i1 + t.i2; 
} 

$ clang++ arm.cpp -O2 -mabi=aapcs -c -S && cat arm.s 

add r0, r0, r1 
bx lr 

$ g++ arm.cpp -O2 -mabi=aapcs -c -S && cat arm.s 

sub  sp, sp, #8 
add  r3, sp, #8 
stmdb r3, {r0, r1} 
ldmia sp, {r0, r3} 
add  r0, r0, r3 
add  sp, sp, #8 
bx  lr 

sto usando il gcc e clang forniti dagli ArchlinuxARM distribuzione, correndo su raspberry pi 2 (gcc 5.2), ma l'ho anche riprodotto con cross-compilers basati su gcc.

+1

Riprovare con '-O3' –

+3

Suoni come un bug _ ottimizzato di tipo _ ottimizzazione in gcc. @ M.M FYI, è lo stesso con '-O3' – Jester

+0

Questo è un po 'deludente ... Mi aspettavo che facesse di meglio. –

risposta

2

Questo è stato confermato come un bug gcc here, ora aspettiamo.