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.
Riprovare con '-O3' –
Suoni come un bug _ ottimizzato di tipo _ ottimizzazione in gcc. @ M.M FYI, è lo stesso con '-O3' – Jester
Questo è un po 'deludente ... Mi aspettavo che facesse di meglio. –