2012-04-12 5 views
5

Ich bemerke nur, dass Clang diese Aussage kompiliert (ohne Optimierung, natürlich):x86 addl vs subl

--x; /* int x; */ 

in:

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

Warum? Gibt es einen Vorteil der Verwendung von addl anstelle der "offensichtlichen" subl? Oder ist es nur eine Implementierung Tatsache?

Was für Tricks mich ist, dass diese:

x -= 1; 

wird:

subl $1, %eax 

Clang Info:

 
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

Es ist wahrscheinlich nur die Implementierung, und könnte mit Optimierungsebene ändern. Was interessanter ist, ist, dass es nicht "dec" verwendet, was eine Optimierung sein kann, da "dec" nicht so viele Statusflags ändert, so dass es von vorherigen Anweisungen abhängig ist. – ughoavgfhw

+0

gcc erzeugt den gleichen Code für 'x -' und 'x = -1' mit' subl'. Interessanterweise verwendet es 'xorl', wenn ich' -O3' aktiviere. –

+5

Es gibt keinen Vorteil, und es gibt keinen Nachteil. Beide sind 3 Bytes und haben die gleichen Leistungsmerkmale. – harold

Antwort

4

Dieses Verhalten mit der Art und Weise Klirren zu tun hat Griffe Pre- Dekrement im Gegensatz zu binären Operatoren wie Sub-und-Assign. Beachten Sie, dass ich nur versuchen werde, auf der Ebene des Clang zu erklären, warum Sie dieses Verhalten sehen. Ich weiß nicht, warum es so implementiert wurde, aber ich denke, es war nur für eine einfache Implementierung.

Alle hier aufgeführten Funktionen finden Sie in der Klasse ScalarExprEmitter innerhalb lib/CodeGen/CGExprScalar.cpp.

Pre/Post Dekrement/Inkrement ist alle auf die gleiche Weise durch die Funktion EmitScalarPrePostIncDec behandelt: eine LLVM add Anweisung mit entweder emittiert oder 1-1 als zweites Argument, abhängig von der Expression bzw. ein Inkrement oder ein Dekrement ist.

Daher

--x 

wird in der LLVM IR, so etwas wie am Ende,

add i32 %x, -1 

, die ganz natürlich, wie

auf x86 als etwas übersetzt
add $0xffffffff, %ecx 

Binäre Operatoren hingegen werden alle unterschiedlich gehandhabt. In Ihrem Fall

x -= 1 

wird von EmitCompoundAssign die wiederum EmitSub Anrufe behandelt werden. So etwas wie die folgende LLVM IR wird ausgegeben:

sub i32 %x, 1 
+0

Danke für die Erklärung und Quellenangaben. Das ist, was ich gesucht habe, es macht Sinn und beweist, dass es in der Umsetzung Konsequenz ist. – sidyll