为什么clang用-O0产生低效率的asm(对于这个简单的浮点数总和)?我正在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规范进行编译,但是我也尝试使用-O0(给出相同的值)和-O2(实际上是计算值并将其存储为预先计算的)产生的拆卸如下(我删除了不相关的零件)-> 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)
...显然,它正在执行以下操作:将两个浮点数加载到寄存器xmm0和xmm1将它们放在堆栈中从堆栈中将一个值(不是xmm0之前的一个值)加载到xmm0执行添加。将结果存储回堆栈。我发现效率低下是因为:一切都可以在注册表中完成。我以后不会使用a和b,因此它可以跳过涉及堆栈的任何操作。即使它想使用堆栈,如果以不同的顺序执行操作,也可以节省从堆栈中重新加载xmm0的时间。考虑到编译器总是正确的,为什么选择这种策略?
2 回答
ABOUTYOU
TA贡献1812条经验 获得超5个赞
请注意,至少clang实际上是从每个变量开始的,每个变量在堆栈上为其分配了内存。-O0
如果可能的话,第一个优化过程之一(我想省略了)可以将它们变成一堆SSA变量。因此,至少在clang上,没有进行“反优化”,只是关闭了正常的优化。
- 2 回答
- 0 关注
- 763 浏览
添加回答
举报
0/150
提交
取消