在编译某些代码时,我注意到在-O0和-O1之间创建的汇编程序存在很大差异。我想要启动启用/禁用优化,直到我发现导致汇编程序发生某种变化的原因。
如果我使用-fverbose-asm来确切地找出O1与O0相比启用哪些标志,然后手动禁用它们,为什么生成的汇编程序仍然如此大不同?即使我用O0运行gcc并手动添加fverbose-asm所说的用O1启用的所有标志,我也没有得到与使用O1时相同的汇编程序。
除了'-f ...'和'-m ......'之外还有什么可以改变吗?
或者只是'O1'与无法关闭的'O0'相比具有一定的魔力。
对于这种神秘感 - 很抱歉 - 这与Reducing stack usage during recursion with GCC + ARM有关但是提到这个问题让这个问题有点难以理解。
答案 0 :(得分:6)
如果你想要的只是看看在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
答案 1 :(得分:3)
除了提供一些证据表明您怀疑-O1
魔法无法关闭之外,这并不是有帮助的。
来自http://gcc.gnu.org/ml/gcc-help/2007-11/msg00214.html:
CAVEAT,并非-O1启用的所有优化都有一个命令行切换标志来禁用它们。
来自哈根的“海湾合作委员会权威指南,第二版”:
注意:并非所有GCC的优化都可以使用标志进行控制。 GCC会自动执行一些优化,除了修改源代码之外,当您使用-O
请求优化时,无法禁用这些优化
不幸的是,我没有找到关于这些硬编码优化可能是什么的明确陈述。希望对GCC内部人员有所了解的人可能会发布一些有关该内容的信息。
答案 2 :(得分:1)
除了许多选项之外,您还可以更改参数,例如
--param max-crossjump-edges=1
这会影响代码生成。检查源文件params.def
中所有可用的参数。
但是无法从-O0切换到-O1,或者从-O1切换到-O2,或者从-Os切换到-Os等等。 ,通过添加选项而不修补源代码,这是因为在不参考命令行选项的情况下可以检查级别的几个硬编码位置,例如:
return perform_tree_ssa_dce (/*aggressive=*/optimize >= 2);