2015-12-21 21 views
7

Es ist bekannt, dass einige kleine Strukturen mit nicht-trivialen copy-ctor und nicht-trivialen dtor in Registern übergeben werden.Warum gibt Gcc unnötige Speicherzugriffe beim Übergeben von trivialer Struktur nach Wert aus?

Zitiert ARM Procedural Call Standard:

Grundtypen größer als 32 Bits als Parameter übergeben werden können, oder als Ergebnis, Funktionsaufrufe zurückgegeben. Wenn sich diese Typen in Kernregistern befinden, gelten die folgenden Regeln: ÷ Ein Doppelwort-Größen-Typ wird in zwei aufeinanderfolgenden Registern (z. B. r0 und r1 oder r2 und r3) übergeben. Der Inhalt von der Register ist so, als wäre der Wert aus der Speicherrepräsentation mit einem einzelnen LDM-Befehl geladen worden.

Und in der Tat kann ich dies leicht mit Klängen bestätigen. gcc emittiert jedoch eine Reihe von Speicher Lade- und Speichervorgänge für einen solchen einfachen Code-Schnipsel:

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 

ich den gcc und Klirren bin mit von ArchlinuxARM Distribution geliefert wird, läuft auf raspberry pi 2 (gcc 5.2), aber ich habe es auch mit gcc-based cross-compilern reproduziert.

+1

Versuchen Sie es erneut mit '-O3' –

+3

Klingt wie ein _missed Optimierungsfehler in gcc. @ M.M FYI, es ist das gleiche mit '-O3' – Jester

+0

Das ist ein bisschen enttäuschend ... Ich habe erwartet, dass es besser geht. –

Antwort

2

Dies wurde als gcc bug here bestätigt, jetzt warten wir.