5

我只是注意到 Clang 编译了这个语句(当然没有任何优化):

--x; /* int x; */

进入:

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

为什么?使用addl而不是“明显”有什么好处subl吗?或者它只是一个实施事实?

让我着迷的是这个:

x -= 1;

变成:

subl    $1, %eax

叮当信息:

Apple clang 3.0 版 (tags/Apple/clang-211.12) (基于 LLVM 3.0svn)
目标:x86_64-apple-darwin11.2.0
线程模型:posix
4

1 回答 1

4

这种行为与 clang 处理预减量的方式有关,而不是像 sub-and-assign 这样的二元运算符。请注意,我将尝试在 clang 级别解释为什么您会看到这种行为。我不知道为什么选择以这种方式实现它,但我想这只是为了便于实现。

我在这里引用的所有函数都可以在 class ScalarExprEmitterinside 中找到lib/CodeGen/CGExprScalar.cpp

该函数以相同的方式处理前/后减量/增量:根据表达式分别是增量还是减量,发出EmitScalarPrePostIncDecLLVMadd指令,其中一个1或作为第二个参数。-1

所以,

--x

最终会在 LLVM IR 中像

add i32 %x, -1

很自然地,它转换为 x86 就像

add $0xffffffff, %ecx

另一方面,二元运算符的处理方式都不同。在你的情况下,

x -= 1

将由EmitCompoundAssignwhich 依次调用来处理EmitSub。将发出类似于以下 LLVM IR 的内容:

sub i32 %x, 1
于 2012-04-25T07:31:37.047 回答