20.3.1 Coding for an Optimizing Compiler

How do you get the best out of the optimizer? It turns out the answer to this question is remarkably straight-forward.

Code clearly. The C language can be quite complex. Perhaps you may remember the obfuscated C one-liner competitions that many magazines from the early days of C used to have. These are the opposite of “code clearly.” The chances are that if you can't read the code, then it is not correct (well-formed) and the optimizer will expose this. Also, some clever C coding tricks will have side-effects that prevent the compiler from doing its best to get concise executable code. Remember, you want the output of the compiler to be concise and take advantage of the architecture...not the input!

Use well typed objects. It is recommended that you make use of the types defined in stdint.h instead of native C types. For example, the fastest way to represent a 8-bit value on a 16-bit device, such as Microchip's dsPIC line of products, is to use int_fast8_t from stdint.h. While you can cast (or let the compiler cast) an object to a different type, this may indicate that you should have chosen a better type in the first place. Additionally, the size and signed-ness of the picked type can have an impact on code generation; unfortunately, this is architecture dependent.

Take care using inline assembly (or don't use it at all). GCC-based compilers, such as MPLAB XC16, have an extended inline assembly format that is provided to communicate how data flows through inline assembly. This allows the compiler to properly optimize the flow of values around assembly statements. This is often a source of “compiler bugs” and the first place to look when investigating whether or not the compiler is broken. Make sure you tell the compiler when writing to a register in inline assembly; the compiler might be using it already! Make sure you tell the compiler if the result of a C expression is used within the inline assembly; if the compiler does not see the use of an expression, it might discard it. Extended GNU inline assembly is described more fully in Using Inline Assembly Language. Also a rich set of builtin functions are provided that perform many of the tasks for which inline assembly is often used.

Don't be afraid to use the optimizer. Once you are confident that the code does what you want to do (test early, test often), don't be afraid to enable optimizations. Optimizations can make it harder to debug, so it is important to take this step once you have tested and have working code.