简体   繁体   English

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

[英]Differences between -O0 and -O1 in GCC

While compiling some code I noticed big differences in the assembler created between -O0 and -O1. 在编译一些代码时,我注意到在-O0和-O1之间创建的汇编程序存在很大差异。 I wanted to run through enabling/disabling optimisations until I found out what was causing a certain change in the assembler. 我想要启动启用/禁用优化,直到我发现导致汇编程序发生某些变化的原因。

If I use -fverbose-asm to find out exactly which flags O1 is enabling compared to O0, and then disable them manually, why is the assembler produced still so massively different? 如果我使用-fverbose-asm来确切地找出O1与O0相比正在启用哪些标志,然后手动禁用它们,为什么生成的汇编程序仍然如此大不同? Even if I run gcc with O0 and manually add all the flags that fverbose-asm said were enabled with O1, I don't get the same assembler that I would have got just by using O1. 即使我用O0运行gcc并手动添加fverbose-asm所说的用O1启用的所有标志,我也没有得到与使用O1时相同的汇编程序。

Is there anything apart from '-f...' and '-m...' that can be changed? 除了'-f ...'和'-m ......'之外还有什么可以改变的吗?

Or is is just that 'O1' has some magic compared with 'O0' that cannot be turned off. 或者就是'O1'与无法关闭的'O0'相比具有一定的魔力。


Sorry for the crypticness - this was related to Reducing stack usage during recursion with GCC + ARM however the mention of it was making the question a bit hard to understand. 对于隐秘性感到抱歉 - 这与使用GCC + ARM减少递归期间的堆栈使用有关,但是提及它使问题有点难以理解。

If all you want is to see which passes are enabled at O1 which are not enabled at O0 you could run something like: 如果您只想查看在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

A similar process, using the set of flags which you discovered, will let you see what extra magic passes not controlled by flags are undertaken by GCC at O1. 一个类似的过程,使用你发现的一组标志,可以让你看到GCC在O1进行的不受标志控制的额外魔法传递。

EDIT: 编辑:

A less messy way might be to compare the output of -fdump-passes, which will list which passes are ON or OFF to stderr. 一种不那么混乱的方法可能是比较-fdump-pass的输出,它将列出哪些传递为ON或OFF到stderr。

So something like: 所以类似于:

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

Not that this helps, other than providing some evidence for your suspicions about -O1 magic that can't be turned off: 并不是说这有帮助,除了提供一些证据表明你怀疑-O1魔法无法关闭:

  • From http://gcc.gnu.org/ml/gcc-help/2007-11/msg00214.html : 来自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. CAVEAT,并非所有由-O1启用的优化都有一个命令行切换标志来禁用它们。

  • From Hagen's "Definitive Guide to GCC, 2nd Ed": 从Hagen的“GCC第二版的权威指南”:

    Note: Not all of GCC's optimizations can be controlled using a flag. 注意:并非所有GCC的优化都可以使用标志进行控制。 GCC performs some optimizations automatically and, short of modifying the source code, you cannot disable these optimizations when you request optimization using -O GCC会自动执行一些优化,除了修改源代码之外,当您使用-O请求优化时,无法禁用这些优化

Unfortunately, I haven't found any clear statement about what these hard-coded optimizations might be. 不幸的是,我没有找到关于这些硬编码优化可能是什么的明确陈述。 Hopefully someone who is knowlegable about GCC's internals might post an answer with some information about that. 希望能够了解GCC内部人员的人可能会发布一些有关此问题的答案。

In addition to the many options you can also change parameters, eg 除了许多选项,您还可以更改参数,例如

--param max-crossjump-edges=1

which affects the code generation. 这会影响代码生成。 Check the source file params.def for all available params. 检查所有可用参数的源文件params.def

But there is no way to switch from -O0 to -O1, or from -O1 to -O2, or from -Os or to -Os or etc. pp , by adding options, without patching the source code, since there are several hard coded locations where the level is checked without consulting an command line option, eg: 但是无法通过添加选项从-O0切换到-O1,或从-O1切换到-O2,或从-O或-Os等转换为pp,而无需修补源代码,因为有几个硬盘在不咨询命令行选项的情况下检查级别的编码位置,例如:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM