我只是注意到Clang编译了这个语句(当然没有任何优化):
--x; /* int x; */
成:
addl $4294967295, %ecx ## imm = 0xFFFFFFFF
为什么呢?使用addl
代替“明显的”subl
有什么好处吗?或者它只是一个实现事实?
让我觉得这个是:
x -= 1;
变为:
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 :(得分:4)
此行为与clang处理预递减的方式有关,而不是像sub-and-assign这样的二元运算符。请注意,我将尝试在clang级别解释您为何看到此行为。我不知道为什么选择以这种方式实现它,但我想这只是为了便于实现。
我在此处引用的所有功能都可以在ScalarExprEmitter
内的lib/CodeGen/CGExprScalar.cpp
课程中找到。
函数EmitScalarPrePostIncDec
以相同的方式处理前/后递减/递增:以add
或1
作为第二个参数发出LLVM -1
指令,取决于表达式分别是增量或减量。
因此,
--x
将在LLVM IR中以类似
的方式结束add i32 %x, -1
,很自然地,转换为x86就像
add $0xffffffff, %ecx
另一方面,二元运算符的处理方式各不相同。在你的情况下,
x -= 1
将由EmitCompoundAssign
处理,而EmitSub
又会调用sub i32 %x, 1
。将发出类似以下LLVM IR的内容:
{{1}}