C++ 中的文件范围变量在 gcc 和 clang 中进行了不同的优化
File scope variables in C++ optimised differently in gcc and clang
我正在玩 Godbolt,我惊讶地发现以下简单的 C++ 代码在 x86-64 gcc 10.2 and x86-64 clang 11.0.0 上具有不同的编译输出,并且具有 -O2
级优化。
static int x = 0;
int const y = x;
int main()
{
x = 0; // should be optimised out?
}
gcc:
main:
mov DWORD PTR x[rip], 0
xor eax, eax
ret
_GLOBAL__sub_I_main:
ret
叮当声:
main: # @main
xor eax, eax
ret
为什么clang可以证明x
未被使用并优化出来,而gcc却不能?
优化器只优化其中实现的内容。
在这种情况下,我相信 Clang 的优化是正确的,因为 main 中的初始化是发生在全局中的第一个赋值。
这个全局变量不能被触及,因为在多个编译单元上初始化全局变量不能依赖来自另一个编译单元的全局变量。
由于您没有初始化正在更改的任何其他全局变量 a
,赋值前该值为 0,不需要它。
我认为这只是 clang 建模导致优化代码的边缘情况。如果您使用更复杂的代码,这种优化很可能甚至无法衡量。
我正在玩 Godbolt,我惊讶地发现以下简单的 C++ 代码在 x86-64 gcc 10.2 and x86-64 clang 11.0.0 上具有不同的编译输出,并且具有 -O2
级优化。
static int x = 0;
int const y = x;
int main()
{
x = 0; // should be optimised out?
}
gcc:
main:
mov DWORD PTR x[rip], 0
xor eax, eax
ret
_GLOBAL__sub_I_main:
ret
叮当声:
main: # @main
xor eax, eax
ret
为什么clang可以证明x
未被使用并优化出来,而gcc却不能?
优化器只优化其中实现的内容。
在这种情况下,我相信 Clang 的优化是正确的,因为 main 中的初始化是发生在全局中的第一个赋值。 这个全局变量不能被触及,因为在多个编译单元上初始化全局变量不能依赖来自另一个编译单元的全局变量。
由于您没有初始化正在更改的任何其他全局变量 a
,赋值前该值为 0,不需要它。
我认为这只是 clang 建模导致优化代码的边缘情况。如果您使用更复杂的代码,这种优化很可能甚至无法衡量。