How to Get the Least out of your PIC32 C compiler
Transcription
How to Get the Least out of your PIC32 C compiler
How to Get the Least out of your PIC32 C compiler Optimizing for code size using the MPLAB® XC32 Compiler for PIC32 MCUs January 2012 In this webinar, we’ll look at how you can get the least out of your PIC32 C compiler... or more specifically, how to config the initial release of the MPLAB XC32 Compiler to optimize for code size. As you may already know, XC32 features a robust optimization framework with numerous new code transformations. This includes inter-procedural analysis and optimization features. Many optimization passes outperform their counterparts from older C32 releases. This results in a significant speed improvement when optimizing for speed and a pronounced footprint improvement when optimizing for size. Here is a set of 5 quick tips for reducing code size. Tip #5 Set -Os optimization Project’s Optimization Level -Os Designed to minimize code size Passes that do not involve a space-speed tradeoff Main optimizations at -Os : Inlining: -finline-functions-called-once Merging: -fcrossjumping Interprocedural: -fipa-sra Among many others… © 2012 Microchip Technology Incorporated. All Rights Reserved. How to Get the Least out of XC32 Slide 2 Tip #5: For new projects, MPLAB X IDE uses default build opBons. These ensure your code is debuggable, but may not mean it is opBmally compiled. For your project, you might want to use more aggressive opBmizaBons, disabling them only if they interfere with your debugging ability The -Os opBon (and remember these opBons are case sensiBve) enables all GCC level 2 opBmizaBons that target code size (as opposed to those that target code speed). The following are just a few of the opBmizaBons performed. The compiler will consider inlining all static funcBons called once, even if they are not marked inline. This will prevent code associated with the call from being produced. (-finline-functions-called-once) The compiler will also merge common code sequences which saves considerable space. (-fcrossjumping) The compiler will perform interprocedural scalar replacement of aggregates, removal of unused funcBon parameters, and replacement of parameters passed by reference with parameters passed by value. (-fipa-sra) The command-‐line opBons corresponding to these individual opBmizaBons are indicated on this slide. There are many other opBmizaBons performed by this opBmizaBon set, so be sure to enable this when code size is important. Tip #4 Take out the Garbage Remove unused functions Compiler: -ffunction-sections Linker: --gc-sections “Isolate each funcBon in a secBon” Place each function into its own section in the object “Remove unused secBons” Enable garbage collecBon of unused input secBons Linker: --print-gc-sections List all secBons removed by garbage collecBon © 2012 Microchip Technology Incorporated. All Rights Reserved. How to Get the Least out of XC32 Slide 3 Tip #4: The compiler and linker can work together to help you remove unused funcBons. To allow this to happen, select the compiler opBon to “Isolate each funcBon in a secBon”. This opBon tells the compiler to place each funcBon into its own secBon so they can be individually removed, if appropriate. Then, select the linker opBon to “Remove unused secBons”. NoBce that the linker can only deal with secBons, not funcBons. This two-‐stage process, then, will allow the linker's garbage-‐collecBon feature to remove unused funcBons, since each funcBon is in its own secBon. If you prefer to manually remove unused code from your source files, the linker opBon --print-gc-sections will instruct the linker to print a list of those secBons removed in this procedure. You can then use this list to help you find the unused funcBons in your source code. Tip #3 Code Compression MIPS16 Instruction Set Optional instruction-set extension Reduce footprint by ~30% Can be specified for particular functions __attribute__((mips16)) int myFunc(int param) { // function body } © 2012 Microchip Technology Incorporated. All Rights Reserved. How to Get the Least out of XC32 Slide 4 Tip #3: PIC32 devices can execute one of two instrucBons sets. The MIPS16 instrucBon set uses fixed-‐size 16-‐bit instrucBons, which take up half the program memory of the default 32-‐bit instrucBons. Due to the limited nature of the MIPS16 instrucBon set, more instrucBons are typically required to perform the same task, but they sBll operates on 32-‐bit registers and the device sBll operates as a 32-‐bit device. The MIPS16 instrucBon set typically reduces code size by around 30%, but the savings greatly depends on your applicaBon code. You can select the compiler opBon to generate 16-‐bit code for your enBre program. However, consider changing the instrucBon set used on funcBon-‐by-‐funcBon basis. Use the mips16 acribute, as shown in the example on this slide, to specify the alternate instrucBon set for individual funcBons, rather than for the enBre program. Note that interrupt, or excepBon, code must be compiled using the default 32-‐bit instrucBon set. Tip #2 Library Selection Choose an optimized multilib variant Selection on your project’s linker options By default, projects use -O2 (balanced) For smallest code size, use -Os If appropriate, use Generate 16-bit code (-mips16) Exclude floating-point (-mno-float) © 2012 Microchip Technology Incorporated. All Rights Reserved. How to Get the Least out of XC32 Slide 5 Tip #2: The XC32 toolchain provides prebuilt mulBlib variaBons of the libraries. These precompiled libraries, including the standard C library and the peripheral library, are compiled with various opBmizaBon levels set. In the linker build opBons, you can select the libraries to link in with your code. The default library variant is -O2 (a balanced opBmizaBon) for the MIPS32 instrucBon set. To save code space, be sure to select the size-‐opBmized compiler libraries. For example, to get the smallest code size, use the –Os library variant. You may also want to use the libraries compiled with the 16-‐bit instrucBon set, or libraries that exclude floaBng-‐point code, if these are appropriate for your applicaBon. Tip #1 Global-Pointer Threshold Global-Pointer Addressing Up to 64 KB accessed efficiently By default, objects 8 bytes or smaller in the “small” sections (.sdata, .sbss) Change default with -G option Largest value that doesn’t cause a link error results in efficient code All project modules must use the same -G value © 2012 Microchip Technology Incorporated. All Rights Reserved. How to Get the Least out of XC32 Slide 6 Now our final Bp: The compiler implements an efficient addressing mode known as Global-‐Pointer RelaBve addressing. Using this mode, up to 64 kilobytes of data can be accessed very efficiently, saving code space and improving execuBon speed. By default, the toolchain places objects 8 bytes or smaller into what is known as the 'small' secBons, which are placed in this space and which can be accessed using this efficient addressing mode. This approach means that virtually all applicaBons will compile without error and can take advantage of the opBmal addressing mode. However in many applicaBons, addiBonal data could have been placed into the small secBons which would have improved efficiency. The more data in the small secBons, the more opBmal the applicaBon. The -G opBon allows you to control the size threshold which determines which objects will be placed in this space. For example, we can add G1024 to the “AddiBonal opBons” field in MPLAB X. Thus objects 1024 bytes or smaller will be placed into the small secBons and be accessed using the global pointer relaBve addressing mode. In general, the largest value that does not cause a link error results in the most efficient code. But make sure to use the same threshold value for all modules in a project. -‐-‐ In this presentaBon, we have seen 5 simple Bps for producing more efficient code. Be sure to consult your compiler's user's guide for full informaBon about the opBons and keywords discussed. Used wisely, these Bps can make a big difference with very licle effort.