Note to self: Visual Studio Link Time Code Generation

Been worrying about the LNK4075 warning for a while now. So, here’s some digging done:

The world without LTCG:

VS invokes the front-end (C1.dll and C1XX.dll), which generates CPU-independent intermediate language (IL) code and passes it on to the back-end (C2.dll). The back-end generates machine-dependent OBJ files. Finally, the linker (LINKER.EXE) is invoked to merge the OBJ files and produce the final output.

Since the linker has limited idea about the program as a whole it cannot perform fine-tuned optimizations. One such optimization being inlining small-functions. Not that any ‘small’ function would be inline, but the linker can’t even get around to compute what it can consider small-enough to be inlined.

The world with LTCG:

The front-end now creates an OBJ file with IL code embedded within it and skips the back-end to call directly the linker. The linker works through this pastiche of OBJ and IL code and calls back in to the back-end to generate a full-blown final output.

Now, the linker has a wider reach and it can effectively go ahead and make decisions about whether functions can be inlined or not. Of course, this varies with the codebase size, optimization flags passed to the build environment, etc.

Note that precompiled headers and LTCG didn’t work hand-in-glove before VS2005! (The article I mention is dated and doesn’t have the updated status about VS patching up its PCH sub-system.)

To read more about LTCG (along with examples):

Recommendations for all windows projects I’ll ever create in future:

* Turn LTCG off in Debug builds (this is in conflict with INCREMENTAL which is implied by DEBUG)

* Keep LTCG along with GL (Whole Program Optimization) in Release builds


About this entry