We recommend using Visual Studio 2017
This documentation is archived and is not being maintained.

/LTCG (Link-time Code Generation)



:NOSTATUS | :STATUS (optional)

Specifies whether the linker should display a progress indicator showing what percentage of the link is complete. The default is to not display this status information.

:PGINSTRUMENT (optional)

Specifies that the linker should output a .pgd file in preparation for instrumented test runs on the application. You can optionally specify /PGD to create the .pgd file with a nondefault name or location.

The data collected from the instrumented runs will be used to create an optimized image. For more information, see Profile Guided Optimization. The short form of this option is /LTCG:PGI.

:PGOPTIMIZE (optional)

Specifies that the linker should use the profile data created after running the instrumented binary to create an optimized image. All input files must be identical to the files that were specified with /LTCG:PGI. For more information, see Profile Guided Optimization. The short form of this option is /LTCG:PGO.

:PGUPDATE (optional)

Allows list of input files to be added or modified from what was specified in the :PGINSTRUMENT phase. However, any new input files will not be optimized with profile-guided optimizations and changed portions of a modified input file that invalidate profile data collected during the instrumentation phase for that code will not be optimized with profile-guided optimizations. For more information, see Profile Guided Optimization. The short form of this option is /LTCG:PGU.

The /LTCG option tells the linker to call the compiler and perform whole program optimization. You can also do profile guided optimization. For more information, see Profile Guided Optimization.

With the following exceptions, you cannot add additional linker options to the /LTCG:PGOPTIMIZE or /LTCG:PGUPDATE run that were not specified in the /LTCG:PGINSTRUMENT run:

Any linker options specified to /LTCG:PGINSTRUMENT do not have to be specified to /LTCG:PGOPTIMIZE; they are implied.

The rest of this topic will only discuss /LTCG in terms of link-time code generation.

/LTCG is implied with /GL.

The linker invokes link-time code generation if it is passed a module that was compiled with /GL or an MSIL module (see .netmodule Files as Linker Input for more information). If you do not explicitly specify /LTCG when passing /GL or MSIL modules to the linker, the linker will eventually detect this and restart the link with /LTCG. Explicitly specify /LTCG when passing /GL and MSIL modules to the linker for the fastest possible build performance.

/LTCG is not valid for use with /INCREMENTAL.

When /LTCG is used to link modules compiled with /Og, /O1, /O2, or /Ox, the following optimizations are performed:

  • Cross-module inlining

  • Interprocedural register allocation (64-bit operating systems only)

  • Custom calling convention (x86 only)

  • Small TLS displacement (x86 only)

  • Stack double alignment (x86 only)

  • Improved memory disambiguation (better interference information for global variables and input parameters)

Using /LTCG and /Ogt will result in double-alignment optimization.

If /LTCG and /Ogs are specified, double alignment will not be performed. If most of the functions in an application are compiled for speed, with a few functions compiled for size (for example, by using the optimize pragma), the compiler will double align these functions that are optimized for size if they call functions that need double alignment.

If the compiler can identify all the call sites of a function, the compiler will ignore explicit calling-convention modifiers on a function and try to optimize the function's calling convention:

  • pass parameters in registers

  • reorder parameters for alignment

  • remove unused parameters

If a function is called via function pointer, or if a function make be called outside of a module compiled with /GL, the compiler will not attempt to optimize a function's calling convention.


If you use /LTCG and redefine mainCRTStartup, your application can have unpredictable behavior relating to user code that executes before global objects are initialized. There are three ways to address this issue: do not redefine mainCRTStartup, do not compile the file containing mainCRTStartup with /LTCG, or initialize global variables and objects statically, if possible.

Modules compiled with /GL and /clr can be used as input to the linker when /LTCG is specified:

  • /LTCG can accept native object files; mixed native/managed object files (compiled with /clr), pure object files (compiled with /clr:pure), and safe object files (compiled with /clr:safe)

  • /LTCG can accept safe .netmodules, which can be created with /clr:safe /LN in Visual C++ and /target:module with any other Visual Studio compiler. .netmodules produced with /clr or /clr:pure are not accepted by /LTCG.

  • /LTCG:PGI does not accept native modules compiled with /GL and /clr, or pure modules (produced with /clr:pure)

To set this compiler option in the Visual Studio development environment

  1. Open the project's Property Pages dialog box. For details, see Working with Project Properties.

  2. Click the Configuration Properties folder.

  3. Click the General property page.

  4. Modify the Whole Program Optimization property.

You can also apply /LTCG to specific builds by choosing Profile Guided Optimization from the Build menu, or by right clicking on the project name in Solution Explorer and selecting one of the Profile Guided Optimization options.

To set this compiler option programmatically