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

この動作は、sub-and-assignのような二項演算子とは対照的に、clangが事前デクリメントを処理する方法と関係があります。なぜこの動作が見られるのかを、clangレベルで説明しようとしていることに注意してください。なぜこのように実装したのかはわかりませんが、実装を簡単にするためだったと思います。

ここで参照するすべての関数は、内のクラスScalarExprEmitterにあり lib/CodeGen/CGExprScalar.cppます。

プレ/ポストデクリメント/インクリメントはすべて関数によって同じように処理されますEmitScalarPrePostIncDec。LLVMadd命令は、それぞれインクリメントまたはデクリメントである式に応じて、2番目の引数のいずれか1または2番目の引数として発行されます。-1

したがって、

--x

LLVM IRでは、次のようになります

add i32 %x, -1

当然のことながら、これはx86に次のように変換されます。

add $0xffffffff, %ecx

一方、二項演算子はすべて異なる方法で処理されます。あなたの場合、

x -= 1

によって処理さEmitCompoundAssignれ、順番にを呼び出しますEmitSub。次のLLVMIRのようなものが発行されます。

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