3

我决定使用 g++ 检查循环不变代码运动优化的结果。但是,当我编译下面的代码-fmove-loop-invariants并分析它的程序集时,我看到k + 17计算仍然在循环体中执行。

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

可能是编译器得出的结论是重新计算更有效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;
}

尝试过g++ -O0 -fmove-loop-invariantsg++ -O3g++ -O3 -fmove-loop-invariants同时使用 g++ 4.6.3 和 g++ 4.8.3。

4

1 回答 1

1

编辑:忽略我之前的回答。你可以看到计算已经被折叠成一个常数。因此它正在执行循环不变优化。


因为as-if 规则。简而言之,不允许编译器进行任何可能影响程序可观察行为的优化,在这种情况下是printf. 您可以看到如果您n设置 volatile 并删除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)
// ...
于 2016-02-14T03:12:34.147 回答