Using GCC Link-Time Optimization to Shrink and Speed Up Your C Programs
Learn how GCC’s Link-Time Optimization (-flto) enables whole-program inlining and dead-code elimination, reducing binary size and improving runtime, along with its trade-offs and verification steps.
25 Aug 2026, 02:37 UTC

Problem: Missed optimization opportunities across translation units
When you compile each C file separately, the optimizer can only see the code inside that file. A helper function defined in one file and called in another cannot be inlined, and constants cannot be propagated across the boundary. This often leaves larger binaries and slower runtime than a whole-program view would allow.
Thesis: Enabling GCC’s Link-Time Optimization (-flto) lets the compiler perform whole-program optimizations during the link step, trading longer link time and higher memory use for smaller, faster release binaries.
How LTO works in GCC
With -flto, GCC emits GIMPLE bytecode instead of ordinary object code. The linker (or the GCC linker plugin) reads this bytecode, merges the translation units, and runs the usual optimization passes (inlining, constant propagation, dead-code elimination) on the combined program. The final machine code is then produced from the optimized GIMPLE.
Required flags
- Compile each source file:
gcc -O2 -flto -c file.c -o file.o - Link with the same flag:
gcc -O2 -flto file1.o file2.o -o prog - Optional but recommended on Linux with GNU ld:
-fuse-linker-pluginto avoid creating intermediate.ofiles.
Worked example: inlining a helper across files
Consider two simple source files:
/* helper.c */
int helper(int x) {
return x * 2 + 1;
}
/* main.c */
#include <stdio.h>
extern int helper(int);
int main(void) {
for (int i = 0; i < 1000; ++i) {
printf("%d\n", helper(i));
}
return 0;
}
Without LTO, the call to helper remains a function call in the loop. With LTO, the optimizer can inline helper into main, eliminate the call overhead, and possibly constant-fold parts of the expression.
Building the example
# Compile with LTO
gcc -O2 -flto -c helper.c -o helper.o
gcc -O2 -flto -c main.c -o main.o
gcc -O2 -flto helper.o main.o -o prog_lto
# Build the same program without LTO for comparison
gcc -O2 -c helper.c -o helper_no.o
gcc -O2 -c main.c -o main_no.o
gcc -O2 helper_no.o main_no.o -o prog_no
You can then inspect the binaries:
- Size difference:
ls -l prog_lto prog_noorsize prog_lto prog_no - Disassembly check:
objdump -d prog_lto | grep -A2 "<main>:"– you should see the body ofhelperemitted inline, with no separatehelpersymbol.
Trade-offs and limitations
- Link time and memory: Because the linker must read and optimize GIMPLE for the whole program, linking can take noticeably longer and consume more RAM, especially on large codebases.
- Debugging: Optimized binaries lose some source-level information; stepping through code may feel less intuitive. A common practice is to keep a separate debug build without
-flto(or with-g -fno-lto) for troubleshooting. - Toolchain compatibility: LTO requires a linker that understands the GCC plugin (GNU ld with
-fuse-linker-pluginor the gold linker). Older or embedded toolchains may not support it.
Practical verification steps
- Build both variants as shown above.
- Compare sizes; a typical reduction for small examples is in the 10–20 % range, though actual gains depend on code structure.
- Run a simple timing loop (e.g.,
time ./prog_ltovs.time ./prog_no) to observe any runtime difference. Run each variant multiple times and take the median to mitigate noise. - If you need to revert, simply rebuild without
-flto; the source files are unchanged, so this is a safe rollback.
Closing: When to enable LTO
For release builds where binary size and execution speed matter more than build time, adding -flto (and optionally -fuse-linker-plugin) is a low-effort way to let GCC perform whole-program optimizations. Keep a debug build without LTO for day-to-day development, and verify the impact on your specific project with the size and timing checks outlined above.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.