【问题标题】:Can the compiler optimize this snippet of code?编译器可以优化这段代码吗?
【发布时间】:2014-08-09 12:32:10
【问题描述】:

考虑下面的sn-p代码:

for(i = 0; i<10; i++)
{
    int n = a[i];//first loop statement

    //other statements
}

显然,编译器不会将第一条语句提升出循环。但是编译器只能在循环上方提升 n 的声明吗?换句话说,编译器是否也可以优化上述代码:

int n;

for(i = 0; i < 10; i++)
{
    n = a[i];//first loop statement
}

【问题讨论】:

  • 关心提供更多你关心的细节?
  • 您真的认为构建编译器的团队看不到一个立即想到的技巧吗?
  • 当然你假设声明会产生任何代码。请记住,提升适用于可执行代码。如果一个构造是不可执行的,那么就没有什么可以提升的了。 C/C++ 中的 int 变量声明本身通常导致零可执行代码。另外,您的问题太宽泛了,没有具体说明它适用于哪种语言,因为在某些语言中,声明可能必须做一些事情。

标签: optimization compiler-construction


【解决方案1】:

实际上,大多数编译器即使在-O0 也会这样做:

~ $ cat t.c
volatile int v;

int a[10];

void f(void)
{
  int n;
  int i;
  for(i = 0; i < 10; i++) {

    n = a[i];
    v = n;
  }
}
~ $ clang -S -O0 t.c
~ $ cat t.s
…
_f:                                     ## @f
    .cfi_startproc
## BB#0:
    pushq   %rbp
Ltmp2:
    .cfi_def_cfa_offset 16
Ltmp3:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp4:
    .cfi_def_cfa_register %rbp
    movl    $0, -8(%rbp)
LBB0_1:                                 ## =>This Inner Loop Header: Depth=1
    cmpl    $10, -8(%rbp)
    jge LBB0_4
## BB#2:                                ##   in Loop: Header=BB0_1 Depth=1
    movq    _v@GOTPCREL(%rip), %rax
    movq    _a@GOTPCREL(%rip), %rcx
    movslq  -8(%rbp), %rdx
    movl    (%rcx,%rdx,4), %esi
    movl    %esi, -4(%rbp)
    movl    -4(%rbp), %esi
    movl    %esi, (%rax)
## BB#3:                                ##   in Loop: Header=BB0_1 Depth=1
    movl    -8(%rbp), %eax
    addl    $1, %eax
    movl    %eax, -8(%rbp)
    jmp LBB0_1
LBB0_4:
    popq    %rbp
    ret
…
~ $ 

请注意,上面的循环主体内没有任何指令可以保留n。相反,相同的堆栈槽-4(%rbp) 被无缝重用。如果我用最轻微的优化进行编译,甚至不会有n 的堆栈槽:一个寄存器足以在它所拥有的短时间内保存它的值:

~ $ clang -S -O1 t.c
~ $ cat t.s
…
_f:                                     ## @f
    .cfi_startproc
## BB#0:
    pushq   %rbp
Ltmp2:
    .cfi_def_cfa_offset 16
Ltmp3:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp4:
    .cfi_def_cfa_register %rbp
    xorl    %eax, %eax
    movq    _a@GOTPCREL(%rip), %rcx
    movq    _v@GOTPCREL(%rip), %rdx
    .align  4, 0x90
LBB0_1:                                 ## =>This Inner Loop Header: Depth=1
    movl    (%rcx,%rax,4), %esi
    movl    %esi, (%rdx)
    incq    %rax
    cmpq    $10, %rax
    jne LBB0_1
## BB#2:
    popq    %rbp
    ret

在这个新编译的版本中,%esin


编译器实现“在循环外提升变量声明”优化的方式,即使是在最低级别的优化,也是通过将所有块范围自动变量的声明提升到函数范围。绝对没有什么。此外,如果对目标语言有最少的了解,那么关于编译器优化的讨论也没有多大意义,在目标语言中,变量声明不需要产生任何代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    相关资源
    最近更新 更多