GCC中-O0和-O1之间的差异

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

如果我使用-fverbose-asm来确切地找出O1与O0相比启用了哪些标志,然后手动禁用它们,为什么生成的汇编程序仍然如此大不同? 即使我用O0运行gcc并手动添加fverbose-asm所说的用O1启用的所有标志,我也没有得到与使用O1时相同的汇编程序。

除了’-f …’和’-m ……’之外还有什么可以改变的吗?

或者只是’O1’与无法关闭的’O0’相比具有一定的魔力。


对于含糊不清的内容感到抱歉 – 这与使用GCC + ARM减少递归期间的堆栈使用有关,但是提及它使问题有点难以理解。

如果你想要的只是看看在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-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 

并不是说这有帮助,除了提供一些证据certificate你对-O1魔法无法关闭的怀疑:

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

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

  • 从Hagen的“GCC第二版的权威指南”:

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

不幸的是,我没有找到关于这些硬编码优化可能是什么的明确陈述。 希望有关GCC内部知识的人可能会发布一些有关此问题的答案。