我决定使用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 ++ 4.6.3和g ++ 4.8.3尝试g++ -O0 -fmove-loop-invariants
,g++ -O3
和g++ -O3 -fmove-loop-invariants
。
答案 0 :(得分:1)
编辑:忽略我之前的回答。您可以看到计算已折叠为常量。因此 执行循环不变优化。
由于as-if rule。简单地说,不允许编译器进行任何可能影响程序的可观察行为的优化,在本例中为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)
// ...