Reputation: 1765
Trying to understand how lto (link time compilation) works
I have those files :
julia.h:
#ifndef JULIA_H
#define JULIA_H
#include <stdio.h>
int julian();
#endif // JULIA_H
julia.c :
#include "julia.h"
int julian()
{
printf("Hello Worldu!\n");
return 0;
}
compiled as a shared library like so : gcc -O3 -fPIC -shared julia.c -o libjulia.so -L$PWD -I$PWD -flto
and my main program :
main.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "julia.h"
int main()
{
julian();
return 0;
}
compiled with : gcc -O3 main.c -I/path/to/inc -L/path/to/lib -Wl,-rpath=/path/to/lib -ljulia -flto
It compiles fines.
So, this is a hello world program but am I doing it right with LTO ? Is is all it takes to optimize the linkage ?
Thanks
Upvotes: 3
Views: 8163
Reputation: 54661
As keltar saied, LTO doesn't affect shared libraries. But...
Just replace ar
by gcc-ar
and add the option --plugin gccpath/liblto_plugin.so
. This LTO plugin will copy the declarations, types, callgraph and GIMPLE representation from LTO-compiled objects into the static lib. (same for ranlib
to be replaced by gcc-ranlib
)
# First retrieve the GCC path
gccpath=$(gcc -print-search-dirs | awk '/install/{print $2}')
# Compile the static library
gcc julia.c -o julia.o -flto -ffat-lto-objects
gcc-ar rcs libjulia.a julia.o --plugin $gccpath/liblto_plugin.so
# Compile & link the executable
gcc main.c libjulia.a -flto -Ofast -march=native
Note: -Ofast
was introduced in GCC-4.6 [ref] and includes -ffast-math
.
Use -O3
if you don't want that.
Makefile
GCCPATH = $(shell gcc -print-search-dirs | awk '/install/{print $$2}')
AR = gcc-ar
RANLIB = gcc-ranlib
ARFLAGS += --plugin $(GCCPATH)/liblto_plugin.so
RANLIBFLAGS += --plugin $(GCCPATH)/liblto_plugin.so
CFLAGS += -flto -ffat-lto-objects
CXXFLAGS += -flto -ffat-lto-objects
LDFLAGS += -flto=8 # 8 -> compiles using 8 threads
Do not forget, the real compilation will be done at link time. Therefore, move your optimization flags from CFLAGS
(and CXXFLAGS
) to LDFLAGS
;-) One more thing, debugging info and LTO is still experimental in GCC-4.9. GCC-5.0 should improve this point...
Upvotes: 14
Reputation: 18409
LTO doesn't affect shared libraries; they're being linked with by dynamic linker, which is not aware of LTO and can't modify code at runtime.
Moreover, LTO doesn't even work with static libraries, but some day it presumably will (it is TODO on gcc wiki).
But yes, what it takes to enable is using -flto
on both compilation and linking phases.
Upvotes: 2