GCC未执行循环不变代码运动 [英] GCC not performing loop invariant code motion

查看:69
本文介绍了GCC未执行循环不变代码运动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我决定使用g ++检查循环不变代码运动优化的结果.但是,当我使用 -fmove-loop-invariants 编译以下代码并分析其汇编时,我发现 k + 17 计算仍在循环体内执行./p>

什么会阻止编译器对其进行优化?

也许编译器得出结论,重新计算 k + 17 效率更高?

  int main(){int k = 0;std :: cin>>k;为(int i = 0; i <10000; ++ i){整数n = k + 17;//没有移出循环printf(%d \ n",n);}返回0;} 

尝试 g ++ -O0 -fmove-loop-不变式 g ++ -O3 g ++ -O3 -fmove-loop-不变式g ++ 4.6.3和g ++ 4.8.3.

解决方案

编辑:忽略我以前的回答.您可以看到计算已被折叠为常数.因此,它 正在执行循环不变式优化.


由于如果"规则.简而言之,不允许编译器进行任何可能影响程序可观察到的行为的优化,在本例中为 printf .您可以看到如果使 n 易失并删除 printf :

会发生什么.

  for(int i = 0; i< 10000; ++ i){易失性int n = k + 17;//没有移出循环}//GCC 4.6.4的示例汇编输出//...movl $ 10000,%eaxaddl $ 17,%edx.L2:subl $ 1,%eaxmovl%edx,12(%rsp)//... 

I decided to check the result of loop invariant code motion optimization using g++. However, when I compiled the following code with -fmove-loop-invariants and analysed its assembly, I saw that k + 17 calculation is still performed in the loop body.

What could prevent the compiler from optimizing it?

May be the compiler concludes that it is more efficient to recalculate k + 17?

int main()
{
    int k = 0;
    std::cin >> k;

    for (int i = 0; i < 10000; ++i)
    {
        int n = k + 17; // not moved out of the loop
        printf("%d\n", n);
    }

    return 0;
}

Tried g++ -O0 -fmove-loop-invariants, g++ -O3 and g++ -O3 -fmove-loop-invariants using both g++ 4.6.3 and g++ 4.8.3.

解决方案

EDIT: Ignore my previous answer. You can see that the calculation has been folded into a constant. Therefore it is performing the loop invariant optimization.


Because of the as-if rule. Simply put, the compiler is not allowed to make any optimizations that may affect the observable behavior of the program, in this case the printf. You can see what happens if you make n volatile and remove the printf:

for (int i = 0; i < 10000; ++i)
{
    volatile int n = k + 17; // not moved out of the loop
}

// Example assembly output for GCC 4.6.4
// ...
        movl    $10000, %eax
        addl    $17, %edx
.L2:
        subl    $1, %eax
        movl    %edx, 12(%rsp)
// ...

这篇关于GCC未执行循环不变代码运动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆