简体   繁体   中英

Differences between -O0 and -O1 in GCC

While compiling some code I noticed big differences in the assembler created between -O0 and -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? 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.

Is there anything apart from '-f...' and '-m...' that can be changed?

Or is is just that 'O1' has some magic compared with 'O0' that cannot be turned off.


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.

If all you want is to see which passes are enabled at O1 which are not enabled at O0 you could run something like:

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.

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.

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:

  • From 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.

  • From Hagen's "Definitive Guide to GCC, 2nd Ed":

    Note: Not all of GCC'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

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.

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.

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:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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