tags:

views:

87

answers:

5

Optimizations such as constant propagation are possible across functions within the same compilation unit (ie. same file).

For example :

int f(int x)
{
    return 3 + x;
}

void main()
{
    printf("%d", 1+f(4));
}

In that example, I think that a sufficiently smart compiler can propagate the '4' constant to the function 'f', solving the integer arithmetic with the other constant '3', and propagates back the result value thus folding everything to the final value '8'.

(Well, correct me if I'm wrong..)

However, what is happening if the function 'f' is in another compilation unit. Since they both units are compiled separately, the compiler can't optimize that way.

Does it mean that optimizations are only possible within the same compilation unit, or is there some form late optimizations performed of link-time?

A: 

GCC 4.5 introduced link-time optimization. AFAIK, it only works on x86 and x64 targets.

leppie
A: 

Microsoft Visual Studio supports WPO (whole program optimization) enabled by ltcg switch (link-time code generation).

It causes several other problems which I don't remember right now, and is preferred off by many developers.

Pavel Radzivilovsky
Here they go: http://msdn.microsoft.com/en-us/magazine/cc301698.aspx1. Much bigger static libraries2. Static libraries with "bytecode" that can become unsupported at any time.
sharptooth
I had more, with very large code bases. Also, i'd add compile time.
Pavel Radzivilovsky
@Sharptooth: bytecode is simply intermediate presentation. Many compilers do it that way. For link-time optimization it is advised to recompile whole program every time - what is also how release builds are supposed to be made. Thus possible incompatible versions of the bytecode are not really a problem.
Dummy00001
@Dummy00001: Yes, but you might be tempted to ship your code as static library to someone. If you do this with a library compiled with LTCG it might become unusable when the user updates the compiler.
sharptooth
@Dummy00001 it's not intermediate: static libraries, which are just packages of obj files, are preferred way of shipping compiled code on windows, where DLLs do not support dynamic linking (aka shared globals problem)
Pavel Radzivilovsky
A: 

Yes, for the Visual C++ compiler in Visual Studio, this is known as Whole Program Optimization:

Whole program optimization allows the compiler to perform optimizations with information on all modules in the program. Without whole program optimization, optimizations are performed on a per module (compiland) basis

With information on all modules, the compiler can:

  • Optimize the use of registers across function boundaries.

  • Do a better job of tracking modifications to global data, allowing a reduction in the number of loads and stores.

  • Do a better job of tracking the possible set of items modified by a pointer dereference, reducing the numbers of loads and stores.

  • Inline a function in a module even when the function is defined in another module.

Chris Schmich
+3  A: 

Both MSVC (since 8.0: VS2005) and GCC (since 4.5) support the concept.

  • MSVC uses a compiler switch /GL and linker switch /LTCG. Documentation

  • GCC must have it enabled and uses the -flto, -fwhole-program, -fwhopr, and/or -combine to the same effect. Documentation (search for the options in your browser)

The "problem" is that every compilation unit (source file) (and in the case of MSVC every library) needs to be compiled with this, so you can't use old binary object files compiled without it. It also makes debugging harder, because the optimizer is a lot more aggressive and unpredictable.

rubenvb
... and .lib files get humongously huge. Still, it's amazing what it can do to code elimination.
peterchen
+2  A: 

Clang compiles to LLVM IR, and the LLVM linker performs whole-program optimization when it produces a native binary.

delnan
llvm makes it really easy to mix and match modules and optimize them separately or combined. And provides many (probably too many) optimization opportunities.
dwelch