為什么clang用-O0產(chǎn)生低效率的asm(對(duì)于這個(gè)簡(jiǎn)單的浮點(diǎn)數(shù)總和)?我正在llvm clang Apple LLVM版本8.0.0(clang-800.0.42.1)上反匯編以下代碼:int main() {
float a=0.151234;
float b=0.2;
float c=a+b;
printf("%f", c);}我沒有使用-O規(guī)范進(jìn)行編譯,但是我也嘗試使用-O0(給出相同的值)和-O2(實(shí)際上是計(jì)算值并將其存儲(chǔ)為預(yù)先計(jì)算的)產(chǎn)生的拆卸如下(我刪除了不相關(guān)的零件)-> 0x100000f30 <+0>: pushq %rbp 0x100000f31 <+1>: movq %rsp, %rbp 0x100000f34 <+4>: subq $0x10, %rsp 0x100000f38 <+8>: leaq 0x6d(%rip), %rdi
0x100000f3f <+15>: movss 0x5d(%rip), %xmm0
0x100000f47 <+23>: movss 0x59(%rip), %xmm1
0x100000f4f <+31>: movss %xmm1, -0x4(%rbp)
0x100000f54 <+36>: movss %xmm0, -0x8(%rbp)
0x100000f59 <+41>: movss -0x4(%rbp), %xmm0
0x100000f5e <+46>: addss -0x8(%rbp), %xmm0 0x100000f63 <+51>: movss %xmm0, -0xc(%rbp)
...顯然,它正在執(zhí)行以下操作:將兩個(gè)浮點(diǎn)數(shù)加載到寄存器xmm0和xmm1將它們放在堆棧中從堆棧中將一個(gè)值(不是xmm0之前的一個(gè)值)加載到xmm0執(zhí)行添加。將結(jié)果存儲(chǔ)回堆棧。我發(fā)現(xiàn)效率低下是因?yàn)椋阂磺卸伎梢栽谧?cè)表中完成。我以后不會(huì)使用a和b,因此它可以跳過涉及堆棧的任何操作。即使它想使用堆棧,如果以不同的順序執(zhí)行操作,也可以節(jié)省從堆棧中重新加載xmm0的時(shí)間??紤]到編譯器總是正確的,為什么選擇這種策略?
2 回答

ABOUTYOU
TA貢獻(xiàn)1812條經(jīng)驗(yàn) 獲得超5個(gè)贊
請(qǐng)注意,至少clang實(shí)際上是從每個(gè)變量開始的,每個(gè)變量在堆棧上為其分配了內(nèi)存。-O0
如果可能的話,第一個(gè)優(yōu)化過程之一(我想省略了)可以將它們變成一堆SSA變量。因此,至少在clang上,沒有進(jìn)行“反優(yōu)化”,只是關(guān)閉了正常的優(yōu)化。
- 2 回答
- 0 關(guān)注
- 821 瀏覽
添加回答
舉報(bào)
0/150
提交
取消