我试图了解GCC在某些虚构代码中可以优化的内容。
在C代码函数中,b()
应该是a()
的语义等效重写。
如汇编程序中所示,输出b()
减少为单个puts()
,而a()
不是,并且仍然包含循环。
为什么GCC无法对a()
b()
应用相同的优化?
C代码
#include <stdio.h>
#include <limits.h>
static void a(){
unsigned int c = 0;
for(unsigned int a = 0; a < UINT_MAX; a++){
if(a == (UINT_MAX/2)){
puts("50");
}
c++;
}
}
static void b(){
unsigned int b = 0, c = 0;
for(; b<(UINT_MAX/2); b++){
c++;
}
puts("50");
for(; b < UINT_MAX; b++){
c++;
}
}
int main(){
a();
b();
return 0;
}
使用gcc 4.8.1进行编译
gcc -std=c99 -march=native -O3 -flto -fuse-linker-plugin test.c
给出了这些汇编指令
;function a()
<+0>: push %rbx
<+1>: mov $0x1,%ebx
<+6>: jmp 0x400453 <main+19>
<+8>: nopl 0x0(%rax,%rax,1)
<+16>: add $0x1,%ebx
<+19>: cmp $0x80000000,%ebx
<+25>: je 0x40046e <main+46>
<+27>: cmp $0xffffffff,%ebx
<+30>: jne 0x400450 <main+16>
<+32>: mov $0x400614,%edi
<+37>: callq 0x400410 <puts@plt>
<+42>: xor %eax,%eax
<+44>: pop %rbx
<+45>: retq
;function b()
<+46>: mov $0x400614,%edi
<+51>: callq 0x400410 <puts@plt>
<+56>: jmp 0x400450 <main+16>