【问题标题】:Differences between -O0 and -O1 in GCCGCC中-O0和-O1的区别
【发布时间】:2012-10-20 21:01:43
【问题描述】:

在编译一些代码时,我注意到在 -O0 和 -O1 之间创建的汇编程序存在很大差异。我想通过启用/禁用优化,直到我发现是什么导致了汇编程序的某些变化。

如果我使用 -fverbose-asm 来准确找出 O1 与 O0 相比启用了哪些标志,然后手动禁用它们,为什么生成的汇编程序仍然存在如此巨大的差异?即使我使用 O0 运行 gcc 并手动添加 fverbose-asm 所说的使用 O1 启用的所有标志,我也无法获得与仅使用 O1 相同的汇编程序。

除了 '-f...' 和 '-m...' 还有什么可以改变的吗?

或者只是'O1'与'O0'相比有一些无法关闭的魔力。


抱歉,这与Reducing stack usage during recursion with GCC + ARM 有关,但提到它使问题有点难以理解。

【问题讨论】:

  • 所以问题是您不知道增加堆栈使用的“违规优化”的名称(或杀手组合),而且您不知道您需要来自-Os 的优化名称?其中“不知道名称”包括它们根本没有名称的可能性,它们是由 O1Os 启用的杂项额外优化,无法单独控制。
  • 是的 - 基本上我知道 GCC 说它已启用的所有标志(通过 -fverbose-asm)。但是手动禁用它们并不能解决问题,所以它一定是我无法控制的一些“魔法”。但是,我刚刚发现(请参阅链接的问题)O0 仍然存在问题,只是方式不同。不过,如果知道这个问题是否有答案仍然是件好事——因为无法控制优化是很可怕的。
  • 您是否尝试过使用 GCC 的 attribute(()) 或以其他方式重写函数(例如,将变量设为静态或手动分配它们的空间)?作为最后机会的解决方案,有问题的函数可以在汇编中重写。
  • 您确定这是优化吗?即使在 -O0 的情况下,您是否也查看过汇编程序的输出?我很确定 gcc 总是会生成这样的代码,因为它是生成代码的最简单方法。我现在没有要验证的 arm gcc,但无论如何,这可能会在编译器的机器独立部分中处理。
  • 嗨,我刚刚更新了这个问题,试图让它更清楚(并且与其他问题不同),很抱歉造成混乱。

标签: c gcc embedded arm


【解决方案1】:

除了许多选项之外,您还可以更改参数,例如

--param max-crossjump-edges=1

这会影响代码生成。检查源文件params.def 以获取所有可用参数。

但是没有办法从 -O0 切换到 -O1,或从 -O1 切换到 -O2,或者从 -Os 或切换到 -Os 等等。 p.p. ,通过添加选项,无需修补源代码,因为有几个硬编码位置可以在不咨询命令行选项的情况下检查级别,例如:

  return perform_tree_ssa_dce (/*aggressive=*/optimize >= 2);

【讨论】:

    【解决方案2】:

    如果您只想查看哪些通道在 O1 启用,哪些在 O0 未启用,您可以运行以下命令:

    gcc -O0 test.c -fdump-tree-all -da
    ls > O0
    rm -f test.c.*
    gcc -O1 test.c -fdump-tree-all -da
    ls > O1
    diff O0 O1
    

    一个类似的过程,使用您发现的标志集,将让您看到 GCC 在 O1 执行了哪些不受标志控制的额外魔法传递。

    编辑:

    比较简单的方法可能是比较 -fdump-passes 的输出,它将列出哪些 pass 是 ON 或 OFF 到 stderr。

    比如:

    gcc -O0 test.c -fdump-passes |& grep ON > O0
    gcc -O1 test.c -fdump-passes |& grep ON > O1
    diff O0 O1
    

    【讨论】:

      【解决方案3】:

      除了为您对无法关闭的 -O1 魔法的怀疑提供一些证据之外,这并没有帮助:

      • 来自http://gcc.gnu.org/ml/gcc-help/2007-11/msg00214.html

        CAVEAT,并非所有由 -O1 启用的优化都有命令行切换标志来禁用它们。

      • 来自 Hagen 的“GCC 权威指南,第 2 版”:

        注意:并非所有 GCC 的优化都可以使用标志来控制。 GCC 会自动执行一些优化,如果不修改源代码,当您使用 -O 请求优化时,您无法禁用这些优化

      不幸的是,我还没有找到任何关于这些硬编码优化可能是什么的明确说明。希望了解 GCC 内部的人可能会发布一个包含一些相关信息的答案。

      【讨论】:

        猜你喜欢
        • 2015-01-15
        • 1970-01-01
        • 2014-09-11
        • 2019-11-29
        • 2019-11-29
        • 2015-07-05
        • 1970-01-01
        • 1970-01-01
        • 2018-03-15
        相关资源
        最近更新 更多