Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么小于表达式在gcc中转换为小于或等于表达式_C_Optimization_Gcc_Gimple - Fatal编程技术网

为什么小于表达式在gcc中转换为小于或等于表达式

为什么小于表达式在gcc中转换为小于或等于表达式,c,optimization,gcc,gimple,C,Optimization,Gcc,Gimple,我正在进行代码优化和gcc内部研究。我在我的程序中编写了一个简单的表达式,我检查了该表达式的gimple表示,我被gcc为什么这样做所困扰。 假设我有一个表达: if(i < 9) if(i

我正在进行代码优化和gcc内部研究。我在我的程序中编写了一个简单的表达式,我检查了该表达式的gimple表示,我被gcc为什么这样做所困扰。 假设我有一个表达:

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
         ...