Building PGO Builds using TeamBuild

One of the enhancements in C++ compiler space for Whidbey is building Profile-Guided Optimized (PGO) builds. Profile-guided optimization lets you optimize an output file, where the optimizer uses data from test runs of the .exe or .dll file. The data represents how the program is likely to perform in a production environment. Please refer to for more details.


This is applicable only for Release configuration. There are three phases in generating PGO builds:

1. Instrumentation (PGI) Phase: First, the user instruments the build through PG Instrumentation (using Build à Profile Guided Optimization à Instrument) which generates the .exe and .pgd files.

2. Training App: The user then trains the app by running it through the common user scenarios which generates test data, .pgc files (either run the app directly through command line and run it through Build à Profile Guided Optimization à Run Instrumented/Optimized Application).

3. Optimization Phase: At this stage, both .pgd and .pgc files should be available at $(outdir). There are two options to do this:

- Optimization (PGO) Option: The user then builds an optimized image by linking the object files in conjunction with the test data which is called Optimization (Build à Profile Guided Optimization à Optimize). One important thing to note is any changes to the sources after building the instrumented application and the .pgd file can dramatically affect PGO code generation and optimization decisions. So, while doing Optimize, the linker performs some checks to make sure that no changes happened to the input files (object files, libraries, etc…) used to build the instrumented application.

- Update (PGU) Option: There is another option available to create optimized binary called Update. Let us say, user discovers that he forgot to update the version number of the application, or, discovered a trivial bug which needs a very tiny fix that does not dramatically affect the flow in the application. He can use this option. Using this option the linker will not perform the checks it does when using Optimize option. The user can edit and recompile files or even add new files to the application between PGI and PGU builds.


Since these options are available through C++ compiler, user can use them through command line as well. Please refer,vs.80).aspx for a detailed walkthrough.


How does this work under TeamBuild?

We need to create two configurations for instrumentation and optimization and enable them in the teambuild process as below:


  1. Create two configurations POGO instrumentation and Optimization let’s say PGIRelease and PGORelease with the following properties set:

PGIRelease à Configuration Properties à General à Whole Program Optimization

Profile Guided Optimization - Instrument

PGIRelease à Configuration Properties à Linker à Optimization à Link Time Code Generation

Profile Guided Optimization - Instrument (/ltcg:pginstrument)

PGORelease à Configuration Properties à General à Whole Program Optimization

Profile Guided Optimization - Optimize

PGORelease à Configuration Properties à General à Intermediate Directory


PGORelease à Configuration Properties à Linker à Optimization à Profile Guided Database


PGORelease à Configuration Properties à Linker à Optimization à Link Time Code Generation

Profile Guided Optimization - Optimize (/ltcg:pgoptimize)


  1. Create a build type with PGIRelease configuration selected
  2. Create a copy of vcoverrides.vsprops, call it PGOOverrides.vsprops and set the following properties:

  <Tool Name="VCLinkerTool" ProfileGuidedDatabase="$(BinariesRoot)\Win32\PGIRelease\$(TargetName).pgd" />

  1. Override the AfterCompile target with the following:
    1. Run tests against the exe generated from PGIRelease configuration to generate .pgc files
    2. Add an msbuild task to compile PGORelease configuration


An example of this in Tfsbuild.proj would be something like this:

<Target Name="AfterCompile">

    <Exec Command="$(BinariesRoot)\win32\PGIRelease\PGODemo.exe" />


Projects="@(SolutionToBuild)" Properties="Configuration=PGORelease;Platform=Win32;SkipInvalidConfigurations=true;VCBuildOverride=$(MSBuildProjectDirectory)\PGOOverrides.vsprops;FxCopDir=$(FxCopDir);OutDir=$(OutDir);ReferencePath=$(ReferencePath);TeamBuildConstants=$(TeamBuildConstants);$(CodeAnalysisOption)"

      Targets="Build" />


Note: currently, there is some problem with running instrumented binaries through a service. Amit is following up on that. Until this is resolved, the tests need to be run manually. To validate this, we’ve replaced the exec task with a waiter task to halt the build process, ran the exe on the build machine and resumed the build process. Everything worked fine.

  1. Kick off the build. The optimized binaries will be dropped at win32\PGORelease location and instrumented binaries at win32\PGIRelease location.