2012-04-12 9 views
5

acabo cuenta de que Clang compila esta declaración (sin ningún tipo de optimización, por supuesto):x 86 supl vs subl

--x; /* int x; */ 

en:

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

¿Por qué? ¿Hay alguna ventaja de usar addl en lugar del subl "obvio"? ¿O es solo un hecho de implementación?

Qué trucos me importa es que éste:

x -= 1; 

se convierte en:

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

Probablemente sea solo la implementación, y podría cambiar con el nivel de optimización. Lo que es más interesante es que no usa 'dec', que puede ser una optimización porque' dec' no cambia tantas banderas de estado, por lo que depende de las instrucciones anteriores. – ughoavgfhw

+0

gcc produce el mismo código tanto para 'x -' como 'x = -1' usando' subl'. Curiosamente, usa 'xorl' si habilito' -O3'. –

+5

No hay ninguna ventaja, y no hay ninguna desventaja. Ambos tienen 3 bytes y tienen las mismas características de rendimiento. – harold

Respuesta

4

Este comportamiento tiene que ver con la forma en que maneja sonido metálico pre decremento en comparación con operadores binarios como sub-y-asignar. Tenga en cuenta que intentaré explicar, a nivel clang, por qué ve este comportamiento. No sé por qué fue elegido para implementarlo de esta manera, pero supongo que fue solo por la facilidad de implementación.

Todas las funciones que hago referencia aquí se pueden encontrar en la clase ScalarExprEmitter dentro de lib/CodeGen/CGExprScalar.cpp.

Pre/post decremento/incremento se manejan de la misma manera por la función EmitScalarPrePostIncDec: un add instrucción LLVM se emite ya sea con 1 o -1 como segundo argumento, en función de la expresión de ser un incremento o un decremento respectivamente.

Por lo tanto,

--x 

va a terminar, en el LLVM IR, como algo parecido

add i32 %x, -1 

que, naturalmente, se traduce en x86 como algo parecido

add $0xffffffff, %ecx 

Los operadores binarios, por otro lado, se manejan de manera diferente. En su caso,

x -= 1 

estará a cargo de EmitCompoundAssign que a su vez llama a EmitSub. Se emitirá algo como el siguiente LLVM IR:

sub i32 %x, 1 
+0

Gracias por la explicación y referencias de origen. Eso es lo que estaba buscando, tiene sentido y demuestra que está en consecuencia de implementación. – sidyll

Cuestiones relacionadas