Optimize for Debug

cancel
Showing results for 
Search instead for 
Did you mean: 

Optimize for Debug

1,202 Views
Senior Contributor I

Introduction to -Og

The compiler shipped with LPCXpresso v7 introduced a new optimisation level -Og, "Optimize for Debug", as described in the GCC documentation at:

http://gcc.gnu.org/onlinedocs/gcc-4.8.3/gcc/Optimize-Options.html

-Og enables optimizations that should not interfere with debugging. It is intended to be used as the optimization level of choice for the standard edit-compile-debug cycle, offering a reasonable level of optimization (providing noticeable code size / performance improvements over the -O0 option) whilst maintaining fast compilation and a good debugging experience.

Note:

  • For more general information on compiler optimization and the effects it can have on your code, please see the FAQ "Compiler Optimization".

Why is -Og useful?

-Og is an ideal choice for many users who wish to  typically develop, debug and release exactly the same build of their project, rather than switching between the traditional Eclipse "Debug" and "Release" build configurations at different stages of their project development. In the past this meant that such users either needed to stay with -O0 and have none-optimised code (with the consequent performance overhead and flash requirements), or turn up the optimisation level and encounter debugging oddities.

This "single build config development cycle" is exactly the circumstance that the -Og option was designed for.

Another advantage is that for users who do use the "two build config development cycle", having -Og as the default for debug builds helps to avoid issues that are commonly found today when switching from the Debug to Release builds (such as failure to use volatile, as described in the "Compiler Optimization" FAQ), as these will be encountered and fixed earlier in the design cycle.

A further advantage is that using -Og reduces code size by a significant amount, enabling more code to be written and debugged before either exceeding the flash size of the target device, or exceeding the code size limits of LPCXpresso (Free Edition).

Configuring LPCXpresso to use -Og

In LPCXpresso versions 7.1.0 to 7.4.0 inclusive, Debug builds would by default use the -Og option by default. But in LPCXpresso v7.5.0 we have reverted to using -O0 by default for Debug builds. This has been done because, as detailed below, the debug experience provided by -Og is not yet at the level expected by many users for a Debug build. Thus we have decided for now to make switching to -Og a user decision rather than having it as a default.

But if you want to explicitly modify the optimization level used by a particular build configuration of your project to -Og, you can do this using:

Project -> Properties -> C/C++ Build -> Settings -> Tool Settings …
… -> MCU C Compiler -> Optimization -> Optimization Level

You can also do this on a per-file/per-directory basis, as described in the FAQ "Project vs per-file properties".

Potential debugging issues with -Og compiled code

As discussed above -Og enables optimizations that should not interfere with debugging experience. However this is still an area of active development, and some issues may sometimes be seen. Reports of such behavior are welcome to be posted on the LPCXpresso Forum. You can find details of some such issues below...

Inlined functions

One example of such an issue is when the compiler inlines functions, rather than generating calls to the function. This is a useful performance optimization that is enabled by -Og and in some circumstances (particularly for very small functions) will also improve code size.

Unfortunately, at the time of writing, the debug information generated by the compiler for such inlined functions at -Og (and higher) is in many cases insufficent for the debugger to provide a full debug experience. This typically means that attempts to set a breakpoint on a source line which is an inlined function will fail. This is particularly the case with LPCOpen projects, as the LPCOpen chip libraries provide many functions within header files marked as 'static inline' meaning that with -Og they are extremely likely to get in-lined.

This is something being investigated for improvement in a future GCC release, but can be worked around easily by turning off the function in-lining optimization in the compiler using the option:

-fno-inline

in:

Project -> Properties -> C/C++ Build -> Settings -> Tool Settings …
… -> MCU C Compiler -> Optimization -> other Optimization flags

Initialization of local variables

When using -Og, if you have local variables that are initialized to specific values before being used, it is best to initialize them just before they are first used, rather than at the start of the function.

If this is not done, then when you step through the code at the source level, you may see a sudden jump back to the initialization statement at the start of the function just before the first real access. This is because the compiler will re-order the generated code so that the initialization happens immediately before it is first used, regardless of where the initialization is written within the source.

Labels (2)
1 Reply

42 Views
Contributor II

Hi,

I just spent hours of debugging a firmware and figured out that optimisations were the issue, but not in the way I thought. The program is actually working perfectly with -Og optimisation, but as soon as I set this parameter to -O0 (No optimisation), I cannot debug it properly: the firmware crashes attempting to reach 0x0 address (I get the "g_pfnVectors() at 0x0" message), the MCU reboots and I get kicked out from the debugger.

Does anyone knows what happens here?
Is it bad to have an embedded firmware running in debug mode (keeping -Og) for production?

Thank you very much for your help

Paul

0 Kudos