为什么小于表达式在gcc中转换为小于或等于表达式
我正在进行代码优化和gcc内部研究。我在我的程序中编写了一个简单的表达式,我检查了该表达式的gimple表示,我被gcc为什么这样做所困扰。 假设我有一个表达:为什么小于表达式在gcc中转换为小于或等于表达式,c,optimization,gcc,gimple,C,Optimization,Gcc,Gimple,我正在进行代码优化和gcc内部研究。我在我的程序中编写了一个简单的表达式,我检查了该表达式的gimple表示,我被gcc为什么这样做所困扰。 假设我有一个表达: if(i < 9) if(i
if(i < 9)
if(i<9)
然后在gimple表示中,它将转换为
if(i <= 8)
如果(i考虑以下C代码:
int i = 10;
if(i < 9) {
puts("1234");
}
inti=10;
如果(i<9){
看跌期权(“1234”);
}
以及等效的C代码:
int i = 10;
if(i <= 8) {
puts("asdf");
}
inti=10;
如果(i标准化有助于检测常见的次表达式,例如:
#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-O2实际上会删除整个循环,并用一个赋值流替换它。我个人认为,编译器总是以这样的方式规范化代码是很有用的。否则,您会遇到两段看似相等的代码导致asm略有不同(可能性能不同)的情况,而认为自己比实际聪明得多的程序员则会比较asm并编写生成“更好”的代码形式asm而不是更能代表他们意图的代码形式。这导致了可怕的模糊代码。这个答案中的信息很少,文本太多。我无法回答为什么gcc会这样做,但我知道如果我在编写编译器,我为什么会这样做。将<转换为网络编译器更干净(在Pascal和Fortran中)也进行了这种优化。我认为他们更关心的是常量8
而不是9
,因为8
是通过移动1
(一个常量始终保存在寄存器中)生成的,而9
需要多次操作才能生成或(gasp)从内存常量获取。我想知道:如果(I<8)
,它对做同样的事情吗?是的,它对任何这样的表达式都做同样的事情
#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;
}
...
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
...