Gordon Williams
Gordon Williams

Reputation: 1886

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.

Upvotes: 19

Views: 6840

Answers (3)

bebbo
bebbo

Reputation: 2939

In addition to the many options you can also change parameters, e.g.

--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. p.p. , 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, e.g.:

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

Upvotes: 2

James Greenhalgh
James Greenhalgh

Reputation: 2491

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

Upvotes: 10

Michael Burr
Michael Burr

Reputation: 340198

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.

Upvotes: 4

Related Questions