What is the difference between -O0 ,-O1 and -g - c++

I am wondering about the use of -O0,-O1 and -g for enabling debug symbols in a lib.
Some suggest to use -O0 to enable debug symbols and some suggest to use -g.
So what is the actual difference between -g and -O0 and what is the difference between -01 and -O0 and which is best to use.

-O0 is optimization level 0 (no optimization, same as omitting the -O argument)
-O1 is optimization level 1.
-g generates and embeds debugging symbols in the binaries.
See the gcc docs and manpages for further explanation.
For doing actual debugging, debuggers are usually not able to make sense of stuff that's been compiled with optimization, though debug symbols are useful for other things even with optimization, such as generating a stacktrace.

-OX specify the optimisation level that the compiler will perform. -g is used to generate debug symbols.

From GCC manual
http://gcc.gnu.org/onlinedocs/
3.10 Options That Control Optimization`
-O
-O1
Optimize. Optimizing compilation takes somewhat more time, and a lot more memory for a large function. With -O, the compiler tries to reduce code size and execution time, without performing any optimizations that take a great deal of compilation time.`
-O2
Optimize even more. GCC performs nearly all supported optimizations that do not involve a space-speed tradeoff. As compared to -O, this option increases both compilation time and the performance of the generated code.`
-O3
Optimize yet more. -O3 turns on all optimizations specified by -O2 and also turns on the -finline-functions, -funswitch-loops, -fpredictive-commoning, -fgcse-after-reload, -ftree-vectorize and -fipa-cp-clone options.`
-O0
Reduce compilation time and make debugging produce the expected results. This is the default. `
-g
Produce debugging information in the operating system's native format (stabs, COFF, XCOFF, or DWARF 2). GDB can work with this debugging information.`

-O0 doesn't enable debug symbols, it just disables optimizations in the generated code so debugging is easier (the assembly code follows the C code more or less directly). -g tells the compiler to produce symbols for debugging.
It's possible to generate symbols for optimized code (just continue to specify -g), but trying to step through code or set breakpoints may not work as you expect because the emitted code will likely not "follow along" with the original C source closely. So debugging in that situation can be considerably trickier.
-O1 (which is the same as -O) performs a minimal set of optimizations. -O0 essentially tells the compiler not to optimize. There are a slew of options that allow a very fine control over how you might want the compiler to perform: http://gcc.gnu.org/onlinedocs/gcc-4.6.3/gcc/Optimize-Options.html#Optimize-Options

As mentioned by others, -O set of options indicate the levels of optimization that must be done by the compiler whereas, the -g option adds the debugging symbols.
For a more detailed understanding, please refert to the following links
http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#Optimize-Options
http://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html#Debugging-Options

Related

C (Embedded): Code size does not shrink when commenting FreeRTOS' RootTask

I have a tree-shaped process/task architecture in my FreeRTOS construct. The main() simply creates a RootTask (after initializing the HAL), which creates another two tasks, and so on.
I'm currently fighting with flash size (code + constants, basically?), and therefore disabling tasks (=commenting them) in order to show the compiler that most translation units are not even needed, to find out which modules are most expensive.
However, I've "commented my way up" to main() and took out EVERYTHING except the while(1) loop. It still doesn't fit in 128k Flash.
Tried removing all C++ translation units, using even gcc for linking; but still ~100k ".text" section (I would be fine with 10k at this point, considering the application doesn't do anything).
I'm using arm-none-eabi-gcc/g++ 5.4.1. The linker script was generated by ST-CubeMX.
gcc flags:
-mcpu=cortex-m0 -mthumb -Os -s -Wall -Wa -a -ad -alms=build/$(notdir $(<:.c=.lst))
Linker flags:
-mcpu=cortex-m0 -specs=nosys.specs -T$(LDSCRIPT) [some-libraries] -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections,--undefined=uxTopUsedPriority,-flto
(also generated by CubeMX, except -flto)
Can someone explain why the Compiler/Linker are not removing unused code from the final binary? Are there tools to investigate further?
Please let me know if more information is needed.
Thank you!
You need to pass the flags -ffunction-sections -fdata-sections to the compiler (gcc/g++) such that --gc-sections in the linker works, and -flto to the compiler such that -flto in the linker can do its work.

Code size is doubled when compiling with GCC ARM Embedded?

I've just ported a STM32 microcontroller project from Keil uVision (using Keil ARM Compiler) to CooCox CoIDE (using GCC ARM Embedded compiler).
Problem is, the code size is the double size when compiled in CoIDE with GCC compared to Keil uVision.
How can this be? What can I do?
Code size in Keil: 54632b (.text)
Code size in CoIDE: 100844b (.text)
GCC compiler flags:
arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -g2 -Wl,-Map=project.map -Os
-Wl,--gc-sections -Wl,-TC:\arm-gcc-link.ld -g -o project.elf -L -lm
I am suspecting CoIDE and GCC to compile a lot of functions and files, that are present in the project, though aren't used (yet). Is it possible that it compiles whole files even if I only use 1 function out of 20 in there? (even though I have -Os)..
Hard to say which files are really compiled/linked in your final binary from the information you give. I suppose it takes all the C files it finds on your project if you did not explicitly specified which one to compile or if you don't use your own Makefile.
But from the compiler options you give, the linker flag --gc-sections won't do much garbage if you don't have the following compiler flags: -ffunction-sections -fdata-sections. Try to add those options to strip all unused functions and data at link time.
Since the question was tagged with C++, I wonder if you would like to disable exceptions and RTTI. Those take quite a bit of code. Add -fno-exceptions -fno-rtti to linker flags.

Can I enable vectorization only for one part of the code?

Is there a way to enable vectorization only for some part of the code, like a pragma directive? Basically having as if the -ftree-vectorize is enabled only while compiling some part of the code? Pragma simd for example is not available with gcc...
The reason is that from benchmarking we saw that with -O3 (which enables vectorization) the timings were worse than with -O2. But there are some part of the code for which we would like the compiler to try vectorizing loops.
One solution I could use would be to restrict the compiler directive to one file.
Yes, this is possible. You can either disable it for the whole module or individual functions. You can't however do this for particular loops.
For individual functions use
__attribute__((optimize("no-tree-vectorize"))).
For whole modules -O3 automatic enables -ftree-vectorize. I'm not sure how to disable it once it's enabled but you can use -O2 instead. If you want to use all of -O3 except -ftree-vectorize then do this
gcc -c -Q -O3 --help=optimizers > /tmp/O3-opts
gcc -c -Q -O2 --help=optimizers > /tmp/O2-opts
diff /tmp/O2-opts /tmp/O3-opts | grep enabled
And then include all the options except for -ftree-vectorize.
Edit: I don't see -fno-tree-vectorize in the man pages but it works anyway so you can do -O3 -fno-tree-vectorize.
Edit: The OP actually wants to enable vectorization for particular functions or whole modules. In that case for individual functions __attribute__((optimize("tree-vectorize"))) can be used and for whole modules -O2 -ftree-vectorize.
Edit (from Antonio): In theory there is a pragma directive to enable tree-vectorizing all functions that follow
#pragma GCC optimize("tree-vectorize")
But it seems not to work with my g++ compiler, maybe because of the bug mentioned here:
How to enable optimization in G++ with #pragma. On the other hand, the function attribute works.

What is the -O5 flag for compiling gfortran .f90 files?

I see the flag in the documentation of how to compile some f90 code I have acquired (specifically, mpfi90 -O5 file.f90), but researching the -O5 flag turned up nothing in the gfortran docs, mpfi docs, or anywhere else. I assume it is an optimization flag like -O1, etc., but I'm not sure.
Thanks!
Source: http://publib.boulder.ibm.com/infocenter/comphelp/v7v91/index.jsp?topic=%2Fcom.ibm.xlf91a.doc%2Fxlfug%2Fhu00509.htm
The flag -O5 is an optimizer like -O3 and -O2. The linked source says,
qnoopt/-O0 Fast compilation, debuggable code, conserved program
semantics.
-O2 (same as -O) Comprehensive low-level optimization; partial debugging support.
-O3 More extensive optimization; some precision trade-offs.
-O4 and -O5 Interprocedural optimization; loop optimization; automatic machine tuning.
With each higher number containing all the optimizations of the lower levels.

What extra optimisation does g++ do with -Ofast?

In g++ 4.6 (or later), what extra optimisations does -Ofast enable other than -ffast-math?
The man page says this option "also enables optimizations that are not valid for all standard compliant programs". Where can I find more information about whether this might affect my program or not?
Here's a command for checking what options are enabled with -Ofast:
$ g++ -c -Q -Ofast --help=optimizers | grep enabled
Since I only have g++ 4.4 that doesn't support -Ofast, I can't show you the output.
The -Ofast options might silently enable the gcc C++ extensions. You should check your sources to see if you make any use of them. In addition, the compiler might turn off some obscure and rarely encountered syntax checking for digraphs and trigraphs (this only improves compiler performance, not the speed of the compiled code).