When I enable Link Time Optimization in GCC, the binaries produced become much larger. I expected GCC to be able to remove a lot of reduntant functions, and perform other optimizations otherwise impossible, so how come this makes the generated output grow?
Compiler flags:
-Os -c -fno-builtin -ffunction-sections -fdata-sections -flto -mcpu=cortex-m0 -mthumb
Linker flags:
-nostdlib -s -Xlinker --gc-sections -flto -mcpu=cortex-m0 -mthumb -T
What is Link Time Optimization (LTO) Link Time Optimization is a form of interprocedural optimization that is performed at the time of linking application code. Without LTO, Arm Compiler for Linux compiles and optimizes each source file independently of one another, then links them to form the executable.
Generally speaking, you should not use Link Time Optimization for Crypto++. There are three reasons for the recommendation. First, we don't want the linker changing object files or the executables produced during link. The linker's job is to combine object files, not attempt to peephole optimize them.
Turning on optimization flags makes the compiler attempt to improve the performance and/or code size at the expense of compilation time and possibly the ability to debug the program.
LTO provides a performance boost for all the compilers. With small projects, this boost probably wouldn't be noticeable, but for big ones this option definitely makes a difference.
Did you strip the binary after linking with -flto
(it should be provided both at compilation and at link time)?
BTW, notice that the same optimization flags (-flto -Os
) should be passed both at compile time and at link time. If you forgot -like you did- any of them at linking phase, LTO won't work! (When using make
you want CC=gcc -flto -Os
not CFLAGS= -flto -Os
).
You did forgot -Os
at link time, in addition of -flto
; just passing -flto
at link time without any optimizations is wrong: the LTO phase would "de-optimize" at most
I know that -flto
adds a lot of sections in the ELF object files and executables (those sections contain the serialization of GCC internal representations like Gimple....). I guess (but have not checked) that the linking does not remove them.
Also, the main point of LTO is to inline accross several compilation units and this is expected to grow the code. So perhaps you should not use LTO in your particular case.
Most redundant functions are already removed (by the linker "GC" on sections) even without LTO.
BTW, you could use objdump
or readelf
to find out.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With