gpt4 book ai didi

c++ - GCC/Clang 未优化静态全局变量

转载 作者:行者123 更新时间:2023-12-02 18:14:48 30 4
gpt4 key购买 nike

GCC 似乎无法跟踪和优化在 C/C++ 中读/写全局变量的程序,即使它们是静态的,这应该允许它保证其他编译单元不会改变变量。

编译代码时

static int test = 0;

int abc() {
test++;
if (test > 100) \
return 123;
--test;
return 1;
}

int main() {
return abc();
}

使用 GCC 版本 11.2 使用标志 -Os(生成更短且更具可读性的汇编)和 -fwhole-program-flto我希望将其优化为 return 1 或以下程序集:

main:
mov eax, 1
ret

这实际上是如果 test 是局部变量时所产生的结果。但是,会生成以下内容:

main:
mov eax, DWORD PTR test[rip]
mov r8d, 1
inc eax
cmp eax, 100
jle .L1
mov DWORD PTR test[rip], eax
mov r8d, 123
.L1:
mov eax, r8d
ret

示例:https://godbolt.org/z/xzrPjanjd

GGC 和 Clang 以及我尝试过的所有其他编译器都会发生这种情况。我希望现代编译器能够跟踪程序的流程并删除检查。是否有一些我没有考虑到的东西可能会允许程序外部的东西影响变量,或者这只是尚未在任何编译器中实现?

相关:Why gcc isn't optimizing the global variable?但那里给出的答案提到了外部函数和线程,这两者都不适用这里

最佳答案

我认为您对大多数编译器的要求有点过高。虽然编译器可能被允许根据 as-if rule 优化静态变量。在标准中,它显然没有在许多编译器中实现,就像您为 GCC 和 Clang 所说的那样。

我能想到的两个原因是:

  • 在您的示例中,显然链接时间优化决定内联 abc 函数,但没有优化掉 test 变量。为此,需要对 test 变量的读/写语义进行分析。以通用方式做到这一点非常复杂。在您提供的简单情况下可能是可能的,但任何更复杂的情况都会非常困难。

  • 此类优化的用例很少见。全局变量最常用于表示某些共享的全局状态。我没有任何意义去优化它。与大多数程序的好处相比,在编译器/链接器中实现此类功能的工作量会很大。

添加
显然,如果您只读访问该变量,GCC 会优化该变量。如果您编译以下内容:

static int test = 0;

int abc() {
int test_ = test;
test_++;
if (test_ > 100) \
return 123;
--test_;
return 1;
}

int main() {
return abc();
}

如果您将变量读取一次到局部变量中并且从不写入它,它就会被优化为:

main:
mov eax, 1
ret

(参见 here for a demo )
然而,使用这样的局部变量会破坏全局变量的全部意义。如果你从不写它,你不妨定义一个常量。

关于c++ - GCC/Clang 未优化静态全局变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71742508/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com