/LTCG (Link-time Code Generation)



  • :NOSTATUS | :STATUS (optional)
    Specifies whether the linker displays a progress indicator that shows what percentage of the link is complete. By default, this status information is not displayed.

  • :PGINSTRUMENT (optional)
    Specifies that the linker outputs a .pgd file in preparation for instrumented test runs on the application. You can use the /PGD option to specify a file name or location for the .pgd file.

    The data that is collected from instrumented runs is 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 uses the profile data that is created after the instrumented binary is run to create an optimized image. All input files must be identical to the files that were specified in /LTCG:PGI. For more information, see Profile Guided Optimization. The short form of this option is /LTCG:PGO.

  • :PGUPDATE (optional)
    Enables a list of input files to be added or modified from what was specified in the :PGINSTRUMENT phase. However, any new input files are not optimized by using profile-guided optimizations, and changed portions of a modified input file that invalidate profile data that is collected during the instrumentation phase for that code are not optimized by using 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 linker options to the /LTCG:PGOPTIMIZE or /LTCG:PGUPDATE run that were not specified in the /LTCG:PGINSTRUMENT run:

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

The rest of this topic discusses /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 by using /GL or an MSIL module (see .netmodule Files as Linker Input). If you do not explicitly specify /LTCG when you pass /GL or MSIL modules to the linker, the linker eventually detects this and restarts the link by using /LTCG. Explicitly specify /LTCG when you pass /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 by using /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)


The linker decides which optimizations each function was compiled with and applies the same optimizations at link time.

Using /LTCG and /Ogt causes double-alignment optimization.

If /LTCG and /Ogs are specified, double alignment is not 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 double-aligns the functions that are optimized for size if they call functions that require double alignment.

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

  • pass parameters in registers

  • reorder parameters for alignment

  • remove unused parameters

If a function is called through a function pointer, or if a function make is called outside a module that is compiled by using /GL, the compiler does not attempt to optimize a function's calling convention.


If you use /LTCG and redefine mainCRTStartup, your application can have unpredictable behavior that relates 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 that contains mainCRTStartup by using /LTCG, or initialize global variables and objects statically.

/LTCG and MSIL Modules

Modules that are compiled by using /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 by using /clr), pure object files (compiled by using /clr:pure), and safe object files (compiled by using /clr:safe)

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

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

To set this compiler option in the Visual Studio development environment

  1. Open the project Property Pages dialog box. See Modifying Project Settings.

  2. Select the Configuration Properties folder.

  3. Select the General property page.

  4. Modify the Whole Program Optimization property.

You can also apply /LTCG to specific builds by choosing Build, Profile Guided Optimization on the menu bar, or by choosing one of the Profile Guided Optimization options on the shortcut menu for the project.

To set this compiler option programmatically

See Also


Setting Linker Options

Linker Options