Larry
Larry

Reputation: 1765

gcc LTO - shared library - Am I right?

Context :

Trying to understand how lto (link time compilation) works

Code:

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.

Question :

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

Answers (2)

oHo
oHo

Reputation: 54661

As keltar saied, LTO doesn't affect shared libraries. But...

LTO works with static libraries

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)

In your example

# 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.

Update 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

keltar
keltar

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

Related Questions