Differences between -O0 and -O1 in GCC
在编译一些代码时,我注意到-O0和-O1之间创建的汇编程序存在很大差异。我想遍历启用/禁用优化,直到找出导致汇编程序发生某些更改的原因。
如果我使用-fverbose-asm来准确找出O1与O0相比启用了哪些标志,然后手动将其禁用,那么为什么生成的汇编器仍然如此巨大?即使我用O0运行gcc并手动添加fverbose-asm所说的所有已被O1启用的标志,我也不会得到仅使用O1就能得到的同一汇编器。
除了\\'-f ... \\'和\\'-m ... \\'之外,是否还有其他可以更改的内容?
或者仅仅是\\'O1 \\'与无法关闭的''O0 \\'相比具有一些魔力。
很抱歉,这与在使用GCC ARM进行递归过程中减少堆栈使用量有关,但是提及它使这个问题有点难以理解。
如果您只想查看O1启用了哪些通行证,而O0则未启用通行证,则可以运行以下命令:
1 2 3 4 5 6 | 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-passs的输出,该输出将列出与stderr对应的ON或OFF的通行证。
类似这样:
1 2 3 | gcc -O0 test.c -fdump-passes |& grep ON > O0 gcc -O1 test.c -fdump-passes |& grep ON > O1 diff O0 O1 |
除了为您怀疑无法关闭的
-
来自http://gcc.gnu.org/ml/gcc-help/2007-11/msg00214.html:
CAVEAT, not all optimizations enabled by -O1 have a command-line toggle flag to disable them.
-
摘自Hagen的" GCC权威指南,第二版":
Note: Not all of GCCa€?s optimizations can be controlled using a flag. GCC performs some optimizations automatically and, short of modifying the source code, you cannot disable these optimizations when you request optimization using -O
不幸的是,我没有找到关于这些硬编码优化可能是什么的明确声明。希望对GCC的内部知识了解的人可以发布答案,并提供一些有关此信息。
除了许多选项外,您还可以更改参数,例如
1 | --param max-crossjump-edges=1 |
这会影响代码生成。检查源文件
但是无法从-O0切换到-O1,或者从-O1切换到-O2,或者从-Os切换到-Os等等。 ,通过添加选项而不修补源代码,因为在不参考命令行选项的情况下检查级别的硬编码位置有多个,例如:
1 | return perform_tree_ssa_dce (/*aggressive=*/optimize >= 2); |