The default optimization level for compiling C programs using GCC is -O0. which turns off all optimizations according to GCC documentation. for example:
gcc -O0 test.c
However, to check if -O0 is really turning off all optimizations. I executed this command:
gcc -Q -O0 --help=optimizers
And here, I was a bit surprised. I got around 50 options enabled. Then, I checked the default arguments passed to gcc using this:
gcc -v
I got this:
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.8/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.8.4-
2ubuntu1~14.04' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --
enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --
program-suffix=-4.8 --enable-shared --enable-linker-build-id --
libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-
gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-
sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-
time=yes --enable-gnu-unique-object --disable-libmudflap --enable-plugin --
with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-
cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable-
java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64 --with-
jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64 --with-arch-
directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-
gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --
with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release
--build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04)
So my conclusion is that the -O0
flag I provided to the program was not overridden by something else.
In fact, I am seeking to implement from scratch a tool that generates random sequences of optimization options and compare generated sequences to default levels 0-3. Just like "acovea". So that, I would like to compare my generated sequences to a zero-optimization level (which should be -O0
)
Can you explain me why 50 options are enabled by default in -O0
?
One idea I have in mind is to compile with -O0
and turn off default optimizations in -O0
using -fno-OPTIMIZATION_NAME
50 times. What do you think?
To answer my question, I have made some conclusions and assumptions:
So let me say that compiling with O0 does not mean that no optimizations will be applied. Options that reduce compilation time and make debugging better will be turned on as @abligh said above.
In other words, O0 is optimizing in the level of compilation. Produced binaries are not optimized in order to ease debugging process.
I give an example: This option is enabled at O0 level
In GCC documentation:
So for GCC 4.8.x, there are almost 50 options turned on by default.
Stricto sensu, the GCC compiler middle-end is made of a sequence (actually a nested tree, dynamically changing during compilation) of optimization passes, so if GCC did no optimization, it won't be able to emit any code.
Think of it another way: the input language to GCC is quite rich (even for plain C, where you have
while
,for
, ....) but the intermediate Gimple language is much more poor (in particular Gimple/SSA) so you need to apply some transformations to go from source AST to Gimple. These transformations are optimization passes, almost by definition.See also the pictures from that answer and this one (an SVG image) and read the references mentioned here.
You should understand
-O0
as disabling any additional optimizations (e.g. provided by-O1
etc...) not needed to produce some executable.Well
will turn all the options off (yuck).
More seriously, if you are covering all optimisation states, make a list of the optimisation flags (which you need to do anyway), and explicitly turn on or off each one with
-fmyflag
or-fno-myflag
. This in essence answers your second question.You may, however, consider it not worth your while playing with turning off optimisations that are on for all
-O
levels.As to why it's like that, that's somewhere between 'too broad' (i.e. you would have to ask whoever wrote it) and 'because that's what https://github.com/gcc-mirror/gcc/blob/master/gcc/toplev.c does'.
Note the documentation does not say that
-O0
disables optimisation. It says (from the man page):By implication there may be optimisations with do not increase compilation time and do not affect debugging, and these will be left on.