2012-04-12 9 views
5

Ho appena notato che Clang compila questa dichiarazione (senza alcuna ottimizzazione, ovviamente):x86 addl vs subl

--x; /* int x; */ 

in:

addl $4294967295, %ecx  ## imm = 0xFFFFFFFF 

Perché? C'è qualche vantaggio nell'usare addl invece di "ovvio" subl? O è solo un fatto di implementazione?

Quali trucchi me è che questo:

x -= 1; 

diventa:

subl $1, %eax 

Clang informazioni:

 
Apple clang version 3.0 (tags/Apple/clang-211.12) (based on LLVM 3.0svn) 
Target: x86_64-apple-darwin11.2.0 
Thread model: posix 
+0

Probabilmente è solo l'implementazione e potrebbe cambiare con il livello di ottimizzazione. La cosa più interessante è che non usa 'dec', che può essere un'ottimizzazione perché' dec' non cambia tanti flag di stato, quindi dipende dalle istruzioni precedenti. – ughoavgfhw

+0

gcc produce lo stesso codice per entrambi 'x -' e 'x = -1' usando' subl'. È interessante notare che usa 'xorl' se abilito' -O3'. –

+5

Non c'è alcun vantaggio e non ci sono svantaggi. Entrambi sono 3 byte e hanno le stesse caratteristiche di prestazione. – harold

risposta

4

Questo comportamento ha a che fare con il modo in cui gestisce clangore pre- decrementa rispetto agli operatori binari come sub-and-assign. Nota che cercherò semplicemente di spiegare, a livello di clang, perché vedi questo comportamento. Non so perché è stato scelto per implementarlo in questo modo ma immagino sia stato solo per facilità di implementazione.

Tutte le funzioni di cui faccio riferimento sono reperibili nella classe ScalarExprEmitter all'interno di lib/CodeGen/CGExprScalar.cpp.

pre/post decremento/incremento sono tutti trattati allo stesso modo dalla funzione EmitScalarPrePostIncDec: un add istruzione LLVM viene emessa sia con 1 o -1 come secondo argomento, a seconda della un'espressione sia un incremento o un decremento rispettivamente.

Pertanto,

--x 

finirà, nel LLVM IR, come qualcosa di simile

add i32 %x, -1 

che, del tutto naturalmente, si traduce in 86 come qualcosa di simile

add $0xffffffff, %ecx 

Gli operatori binari, d'altra parte, sono tutti gestiti in modo diverso. Nel tuo caso,

x -= 1 

saranno trattati da EmitCompoundAssign, che a sua volta chiama EmitSub. Viene emesso qualcosa come il seguente LLVM IR:

sub i32 %x, 1 
+0

Grazie per la spiegazione e riferimenti di origine. Questo è quello che stavo cercando, ha senso e dimostra che è nelle conseguenze dell'implementazione. – sidyll