2012-04-12 95 views
5

我只是注意到鏘編譯此語句(不使用任何優化,當然):86 ADDL VS subl

--x; /* int x; */ 

到:

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

爲什麼?是否有使用addl代替subl「顯而易見」的任何優勢?還是僅僅是一個實現事實?

什麼名堂我是這一個:

x -= 1; 

變爲:

subl $1, %eax 

鏘信息:

 
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

這可能只是實施,並可以與優化級別更改。更重要的是有趣的是,它不使用'dec',這可能是一種優化,因爲'dec'不會改變儘可能多的狀態標誌,因此依賴於以前的指令。 – ughoavgfhw 2012-04-12 15:44:44

+0

GCC產生相同碼兩個'X - '和'X = -1'使用'subl'。有趣的是,如果我啓用'-O3',它會使用'xorl'。 – 2012-04-12 15:49:28

+5

沒有優勢,也沒有劣勢。兩者都是3個字節,並具有相同的性能特徵。 – harold 2012-04-12 16:05:37

回答

4

這種行爲與方式鐺做前期處理遞減,而不是二進制運算符,如子和賦值。請注意,我將嘗試在叮叮級別解釋爲什麼你會看到這種行爲。我不知道爲什麼選擇這種方式來實現它,但我想這只是爲了便於實施。

我在這裏引用的所有功能都可以在ScalarExprEmitter類中lib/CodeGen/CGExprScalar.cpp被發現。

預/後遞減/增量都是由功能EmitScalarPrePostIncDec同樣的方式處理:一種LLVM add指令發出與任一1-1作爲第二個參數,這取決於表達被增量或分別遞減。

因此,

--x 

將結束,在LLVM IR,就像這樣

add i32 %x, -1 

其中,很自然地轉化爲x86架構類似

add $0xffffffff, %ecx 

另一方面,二元運算符的處理方式各不相同。在你的情況,

x -= 1 

EmitCompoundAssign進而調用EmitSub處理。類似下面的LLVM IR將發出:

sub i32 %x, 1 
+0

感謝您的解釋和來源參考。這就是我所尋找的,這是有道理的,並證明它在實施中的後果。 – sidyll 2012-04-25 10:36:56