Mostly to familiarize myself with the Crazyflie code and with bitbucket, I thought I would add support for link-time optimization to the project. I spend a lot of time optimizing firmware and cutting down on code size where I work (where we also happen to use STM32F1 micros), so I thought I could throw in support for one of the easier tricks to implement, link-time optimization.
As the name suggests, LTO allows GCC to perform additional optimizations during the linking phase, which allows it to perform optimizations across object file boundaries in a way that it cannot while compiling on a per-file basis. Theoretically, this only requires adding a few GCC flags during compilation and linking. In practice, on Cortex-M processors, GCC tends to optimize out things like interrupt handlers while LTO is enabled - as far as it can tell, they are never called (they are called by hardware, not software). This is corrected by explicitly marking those functions with an attribute telling GCC not to discard them. For some reason, I also had to explicitly include the math library when linking for it to work.
Doing this reduced the size of the binary by about 10%, from about 48K to about 43K. The code size reduction by itself isn't super necessary at the moment - there's still lots of room left in the micro's 128K of flash - but the code size reduction also carries with it a similar performance improvement which might be relevant, especially as we add new features. I don't have a terribly good way of measuring this right now though.
I uploaded my changes to a fork here: https://bitbucket.org/errantsignal/craz ... ommits/all
I also uploaded a pair of binaries for comparison's sake, one with LTO enabled and one without: https://bitbucket.org/errantsignal/craz ... /downloads
I think I can make a pull request if anyone wants to integrate this with the main repository (which should be very straightforward), though I'm still figuring out bitbucket.
When compiling with the new makefile, set LTO=1 to use the new feature. Make sure you do a clean first, or else GCC while build using old object files that don't contain extra metadata that it needs to use LTO.
Code: Select all
make clean make CLOAD=1 DEBUG=0 LTO=1