sid*_*yll 5 c compiler-construction x86 assembly clang
我只是注意到Clang编译了这个语句(当然没有任何优化):
--x; /* int x; */
Run Code Online (Sandbox Code Playgroud)
成:
addl $4294967295, %ecx ## imm = 0xFFFFFFFF
Run Code Online (Sandbox Code Playgroud)
为什么?使用addl而不是"显而易见" 是否有任何优势subl?或者它只是一个实施事实?
欺骗我的是这一个:
x -= 1;
Run Code Online (Sandbox Code Playgroud)
变为:
subl $1, %eax
Run Code Online (Sandbox Code Playgroud)
铿锵信息:
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
这种行为与 clang 处理预减的方式有关,而不是像 sub 和 allocate 这样的二元运算符。请注意,我将尝试在 clang 级别解释为什么您会看到此行为。我不知道为什么选择以这种方式实现它,但我想这只是为了便于实现。
ScalarExprEmitter我在这里引用的所有函数都可以在类里面 找到lib/CodeGen/CGExprScalar.cpp。
函数以相同的方式处理前/后递减/递增EmitScalarPrePostIncDec:LLVM指令以或作为第二个参数add发出,具体取决于表达式分别是递增还是递减。1-1
所以,
--x
Run Code Online (Sandbox Code Playgroud)
最终会在 LLVM IR 中,像这样
add i32 %x, -1
Run Code Online (Sandbox Code Playgroud)
很自然地,它会转换为 x86,类似于
add $0xffffffff, %ecx
Run Code Online (Sandbox Code Playgroud)
另一方面,二元运算符的处理方式不同。就你而言,
x -= 1
Run Code Online (Sandbox Code Playgroud)
EmitCompoundAssign将依次调用来处理EmitSub。将发出类似以下 LLVM IR 的内容:
sub i32 %x, 1
Run Code Online (Sandbox Code Playgroud)