我正在从事代码优化工作,并深入了解了gcc的内部机制。我在我的程序中写了一个简单的表达式,我检查了这个表达式的gimple表示,我被困住了,为什么gcc会这样做。假设我有一个表达式:
if(i < 9)然后在gimple表示中,它将被转换为
if(i <= 8)我不知道为什么gcc要这样做。这是一种优化吗,如果是,那么谁能告诉我它是如何优化我们的程序的?
发布于 2012-07-11 22:07:13
规范化有助于检测CommonSubExpressions,例如:
#include <stdio.h>
int main(void)
{
unsigned u, pos;
char buff[40];
for (u=pos=0; u < 10; u++) {
buff[pos++] = (u <5) ? 'A' + u : 'a' + u;
buff[pos++] = (u <=4) ? '0' + u : 'A' + u;
}
buff[pos++] = 0;
printf("=%s=\n", buff);
return 0;
}GCC -O1会将其编译为:
...
movl $1, %edx
movl $65, %ecx
.L4:
cmpl $4, %eax
ja .L2
movb %cl, (%rsi)
leal 48(%rax), %r8d
jmp .L3
.L2:
leal 97(%rax), %edi
movb %dil, (%rsi)
movl %ecx, %r8d
.L3:
mov %edx, %edi
movb %r8b, (%rsp,%rdi)
addl $1, %eax
addl $1, %ecx
addl $2, %edx
addq $2, %rsi
cmpl $10, %eax
jne .L4
movb $0, 20(%rsp)
movq %rsp, %rdx
movl $.LC0, %esi
movl $1, %edi
movl $0, %eax
call __printf_chk
...实际上,GCC -O2将删除整个循环,并将其替换为赋值流。
发布于 2012-07-11 21:01:44
考虑下面的C代码:
int i = 10;
if(i < 9) {
puts("1234");
}还有等效的C代码:
int i = 10;
if(i <= 8) {
puts("asdf");
}在没有优化的情况下,两者生成完全相同的装配序列:
40052c: c7 45 fc 0a 00 00 00 movl $0xa,-0x4(%rbp)
400533: 83 7d fc 08 cmpl $0x8,-0x4(%rbp)
400537: 7f 0a jg 400543 <main+0x1f>
400539: bf 3c 06 40 00 mov $0x40063c,%edi
40053e: e8 d5 fe ff ff callq 400418 <puts@plt>
400543: .. .. .. .. .. .. ..因为我不熟悉GCC的实现,所以我只能猜测为什么要进行转换。也许它使代码生成器的工作变得更容易,因为它只需要处理单一的情况。我希望有人能给出一个更明确的答案。
https://stackoverflow.com/questions/11433073
复制相似问题