AnsweredAssumed Answered

Optimize for Debug

Question asked by LPCware Support on Mar 31, 2016

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:


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


  • 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:






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.