为什么gcc4没有展开这个循环?

时间:2012-11-12 01:06:25

标签: c optimization gcc gcc4 loop-unrolling

gcc 4.4.6文档中说明:

-funroll-all-loops:
Unroll all loops, even if their number of iterations is uncertain 
when the loop isentered. 

我正在编译此代码:

int unroll(){
  int i = 0;
  int array[1000];
  do {
    use(i,array);
    i++;
  }while(i<1000);
  return(0);
}

void use(int i, int *array){
   int x = i*5;
   array[i] = x;
}

...一次使用funroll-all-loops优化,一次不使用:

OPT = -funroll-all-loops
NOOPT = -O0

然后我使用diff来比较每个的汇编代码(使用-S -fverbose-asm生成)。

生成的代码完全相同。

尝试将循环更改为do while; 调整循环计数器(最多100); 更改循环体内的语句。

我能错过什么?为什么这个循环没有展开?

更新

Nikos C建议使用--param max-unroll-times=N来提高循环注册参数,其中N是上限。 虽然这是一个明智的建议,但并没有改变行为。 我还将循环迭代降低到只有10。 还更新了代码以实际“做”某些事情,没有变化。

1 个答案:

答案 0 :(得分:3)

因为你已经在“OPT”情况下禁用了所有其他优化,你告诉编译器展开所有循环,然后拒绝他这样做的方法,比如循环归纳等。试试

NOOPT = -O2
OPT = -O2 -funroll-all-loops

如果我翻译片段(稍微更改为extern函数以避免任何内联和死代码消除)

void use(int i, int *array);

int unroll(){
  int i = 0;
  int array[1000];
  do {
    use(i,array);
    i++;
  }while(i<1000);
  return(0);
}
带有gcc -O2 -funroll-all-loops test.c -o test2.o -c

,生成的对象代码 被展开八次:

  0000000000000000 <unroll>:
  0:   53                      push   %rbx
  1:   31 db                   xor    %ebx,%ebx
  3:   48 81 ec a0 0f 00 00    sub    $0xfa0,%rsp
  a:   66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
  10:   89 df                   mov    %ebx,%edi
  12:   48 89 e6                mov    %rsp,%rsi
  15:   e8 00 00 00 00          callq  1a <unroll+0x1a>
  1a:   8d 7b 01                lea    0x1(%rbx),%edi
  1d:   48 89 e6                mov    %rsp,%rsi
  20:   e8 00 00 00 00          callq  25 <unroll+0x25>
  25:   8d 7b 02                lea    0x2(%rbx),%edi
  28:   48 89 e6                mov    %rsp,%rsi
  2b:   e8 00 00 00 00          callq  30 <unroll+0x30>
  30:   8d 7b 03                lea    0x3(%rbx),%edi
  33:   48 89 e6                mov    %rsp,%rsi
  36:   e8 00 00 00 00          callq  3b <unroll+0x3b>
  3b:   8d 7b 04                lea    0x4(%rbx),%edi
  3e:   48 89 e6                mov    %rsp,%rsi
  41:   e8 00 00 00 00          callq  46 <unroll+0x46>
  46:   8d 7b 05                lea    0x5(%rbx),%edi
  49:   48 89 e6                mov    %rsp,%rsi
  4c:   e8 00 00 00 00          callq  51 <unroll+0x51>
  51:   8d 7b 06                lea    0x6(%rbx),%edi
  54:   48 89 e6                mov    %rsp,%rsi
  57:   e8 00 00 00 00          callq  5c <unroll+0x5c>
  5c:   8d 7b 07                lea    0x7(%rbx),%edi
  5f:   48 89 e6                mov    %rsp,%rsi
  62:   83 c3 08                add    $0x8,%ebx
  65:   e8 00 00 00 00          callq  6a <unroll+0x6a>
  6a:   81 fb e8 03 00 00       cmp    $0x3e8,%ebx
  70:   75 9e                   jne    10 <unroll+0x10>
  72:   48 81 c4 a0 0f 00 00    add    $0xfa0,%rsp
  79:   31 c0                   xor    %eax,%eax
  7b:   5b                      pop    %rbx
  7c:   c3                      retq