Understanding the PGO Phase Argument in Chromium Builds
This article explains the purpose of the
chrome_pgo_phase build argument used during the multi-stage
production compilation of the Chromium web browser. It covers the
fundamentals of Profile-Guided Optimization (PGO), how this specific
build argument controls the different stages of the compilation process,
and why this multi-stage approach is essential for maximizing the final
performance of the browser.
What is Profile-Guided Optimization (PGO)?
Profile-Guided Optimization (PGO) is a compiler technique used to increase the runtime performance of software. Normally, a compiler optimizes code based on static analysis—guessing how the software will run just by looking at the source code. With PGO, the compiler uses data recorded from actual executions of the software to make exact, data-driven optimization decisions.
In the Chromium build system (GN), this multi-stage process is
controlled directly by the chrome_pgo_phase argument.
The Purpose of the
chrome_pgo_phase Argument
Because PGO requires running the program before the final version can
be built, Chromium must be compiled twice for a single production
release. The chrome_pgo_phase argument tells the Clang
compiler which stage of this process it is currently executing.
The argument accepts three specific integer values: 0,
1, and 2.
Phase 0: PGO Disabled
(chrome_pgo_phase = 0)
Setting the argument to 0 turns off Profile-Guided
Optimization entirely. The compiler builds the browser in a single step
using standard static optimizations. This is used primarily by
developers for local testing and debugging, where fast compilation times
are more important than maximum runtime speed.
Phase 1:
The Instrumentation Phase (chrome_pgo_phase = 1)
This is the first stage of a production build. Setting the argument
to 1 instructs the compiler to produce an "instrumented"
version of Chromium.
- What the compiler does: It injects tracking counters into the browser's binary code to monitor execution paths and function calls.
- How it is used: Once this slow, bulky version of Chromium is compiled, automated build servers run it through a series of benchmarks that simulate real-world user behaviors (like opening tabs, rendering complex web pages, and scrolling).
- The output: As the browser runs these tests, it
outputs raw performance logs (
.profrawfiles). These logs are then merged using LLVM tools into a single profile data file (.profdata).
Phase 2: The
Optimization Phase (chrome_pgo_phase = 2)
This is the final stage of a production build. Setting the argument
to 2 tells the compiler to strip out all tracking
instrumentation and compile the final release binary using the data
gathered in Phase 1.
During this phase, the build system also utilizes the
pgo_data_path argument to point the compiler to the
.profdata file generated during the instrumentation phase.
Note that if you are compiling a release build locally, Chromium's build
tools will automatically download a pre-generated .profdata
file from Google's servers so you can skip Phase 1 and jump straight to
Phase 2.
How Phase 2 Optimizes the Browser
By passing chrome_pgo_phase = 2 along with the profile
data, the compiler can see exactly how the browser behaves in the real
world. It uses this data to perform several critical optimizations:
- Function Inlining: Frequently called functions ("hot" code) are copied directly into the places where they are called, eliminating the overhead of jumping to a different part of memory.
- Code Layout and Cache Locality: Hot code paths are grouped closely together in the final binary, while rarely used functions ("cold" code, such as error handling) are pushed far away. This ensures the CPU's instruction cache is only filled with code that is actively needed.
- Branch Prediction: If the profile data shows an
if/elsestatement goes one way 99% of the time, the compiler rearranges the assembly code to favor that specific path, preventing CPU pipeline stalls. - Register Allocation: The compiler assigns the fastest CPU registers to the variables that are used most frequently during actual browsing sessions.
Ultimately, the chrome_pgo_phase argument exists to
orchestrate this two-step compilation dance, regularly resulting in a
10% or greater increase in browser speed and efficiency compared to
standard builds.