Pgo

mohitmishra786/low-level-dev-skills/skills/compilers/pgo

by mohitmishra786bdc58472fa9fNo license253 starsListed Oct 9, 2026Updated Oct 9, 2026Repository updated 3 months ago

Profile-guided optimisation skill for C/C++ with GCC and Clang. Use when squeezing maximum runtime performance after standard optimisation plateaus, implementing two-stage PGO builds, collecting profile data, or applying BOLT for post-link optimisation. Activates on queries about PGO, profile-guided optimization, fprofile-generate, fprofile-use, instrumented builds, or BOLT.

Instructions onlySoftware Development
AI-generated overview

Guides agents through profile-guided optimisation (PGO) and BOLT builds for C/C++ with GCC and Clang.

What it does
Walks through the full PGO workflow: instrumented build, running a representative workload, collecting and merging profile data, and producing an optimised build. Covers GCC (-fprofile-generate/-fprofile-use), Clang IR PGO and SamplePGO, CMake integration, and BOLT post-link optimisation. Also describes how to verify the performance impact with perf.
When to use it
Use when standard optimisation such as -O3 has plateaued and maximum runtime performance is needed, or when implementing two-stage PGO builds, collecting profile data, or applying BOLT. Also relevant to questions about fprofile-generate, fprofile-use, instrumented builds, or BOLT.
Requirements
GCC or Clang toolchains, LLVM tools such as llvm-profdata, llvm-profgen and llvm-bolt, perf for sampling and verification, and CMake for the integration example. Instructions only; no scripts are shipped.

PGO (Profile-Guided Optimisation)

Purpose

Guide agents through the full PGO workflow: instrument build → representative workload → collect profile → optimised build, covering both GCC and Clang, plus BOLT for post-link optimisation.

Triggers

  • "How do I use PGO to speed up my binary?"
  • "What is profile-guided optimization and when should I use it?"
  • "How do I use -fprofile-generate and -fprofile-use?"
  • "My -O3 build isn't fast enough — what next?"
  • "How does BOLT differ from PGO?"
  • "How do I collect representative profile data?"

Workflow

1. When to use PGO

text
Is -O3 -march=native already applied?  no  → apply standard optimisation first  yes → is workload branch-heavy or has irregular call patterns?          yes → PGO will likely help 5-30%          no  → PGO may not help; profile first with linux-perf

PGO helps most with:

  • Large binaries with many cold/hot code paths (compilers, databases, servers)
  • Branch-heavy code where static prediction is wrong
  • Function call-heavy code where inlining decisions improve with profile data

2. GCC PGO workflow

bash
# Step 1: Build with instrumentationgcc -O2 -fprofile-generate -fprofile-dir=./pgo-data \    prog.c -o prog_instr
# Step 2: Run with representative workload(s)./prog_instr < workload1.input./prog_instr < workload2.input# Generates .gcda files in ./pgo-data/
# Step 3: Build optimised binary using profilegcc -O2 -fprofile-use -fprofile-dir=./pgo-data \    -fprofile-correction \    prog.c -o prog_pgo

-fprofile-correction: handles profile count inconsistencies from parallel or nondeterministic runs. Always include it.

3. Clang PGO workflow (IR-based, preferred)

bash
# Step 1: Instrument buildclang -O2 -fprofile-instr-generate prog.c -o prog_instr
# Step 2: Run workload (generates default.profraw)./prog_instr < workload.inputLLVM_PROFILE_FILE="prog-%p.profraw" ./prog_instr  # per-PID files for parallel runs
# Step 3: Merge raw profilesllvm-profdata merge -output=prog.profdata *.profraw
# Step 4: Optimised buildclang -O2 -fprofile-instr-use=prog.profdata prog.c -o prog_pgo

Clang's IR PGO is more accurate than GCC's and supports SamplePGO (sampling-based, no instrumentation overhead).

4. Clang SamplePGO (sampling, no instrumentation)

bash
# Step 1: Build with frame pointers for accurate stacksclang -O2 -fno-omit-frame-pointer prog.c -o prog
# Step 2: Sample with perfperf record -b -e cycles:u ./prog < workload.inputperf script -F ip,brstack > perf.script  # or use perf2bolt
# Step 3: Convert perf datallvm-profgen --binary=./prog --perf-script=perf.script \             --output=prog.profdata
# Step 4: Optimised buildclang -O2 -fprofile-sample-use=prog.profdata prog.c -o prog_spgo

SamplePGO is ideal for production profiling without instrumentation overhead.

5. CMake integration

cmake
option(PGO_INSTRUMENT "Build with PGO instrumentation" OFF)option(PGO_USE "Build with PGO profile data" OFF)
if(PGO_INSTRUMENT)    add_compile_options(-fprofile-instr-generate)    add_link_options(-fprofile-instr-generate)endif()
if(PGO_USE)    add_compile_options(-fprofile-instr-use=${CMAKE_SOURCE_DIR}/prog.profdata)    add_link_options(-fprofile-instr-use=${CMAKE_SOURCE_DIR}/prog.profdata)endif()

Build script:

bash
# Phase 1: instrumentcmake -S . -B build-pgo-instr -DPGO_INSTRUMENT=ON -DCMAKE_BUILD_TYPE=Releasecmake --build build-pgo-instr -j$(nproc)
# Collect profile./build-pgo-instr/prog < workload.inputllvm-profdata merge -output=prog.profdata *.profraw
# Phase 2: optimisedcmake -S . -B build-pgo -DPGO_USE=ON -DCMAKE_BUILD_TYPE=Releasecmake --build build-pgo -j$(nproc)

6. BOLT (post-link binary optimisation)

BOLT reorders functions and basic blocks in the final binary based on profile data, improving instruction cache locality. Works after PGO for additional 5-15%.

bash
# Step 1: Build with relocation supportclang -O2 -Wl,--emit-relocs prog.c -o prog
# Step 2: Collect profile with perfperf record -e cycles:u -b ./prog < workload.inputperf2bolt prog -p perf.data -o prog.fdata
# Or use instrumented BOLTllvm-bolt prog -instrument -o prog.instr./prog.instr < workload.input# Generates /tmp/prof.fdata
# Step 3: Apply BOLT optimisationllvm-bolt prog -data prog.fdata -o prog.bolt \    -reorder-blocks=ext-tsp \    -reorder-functions=hfsort \    -split-functions \    -split-all-cold \    -dyno-stats

7. Verifying PGO impact

bash
# Compare perf of instrumented vs PGO buildperf stat ./prog_baseline < workload.inputperf stat ./prog_pgo < workload.input
# Check which functions are hot in eachperf record ./prog_pgo < workload.inputperf report --stdio | head -30

For full workflow details and Clang vs GCC profile format notes, see references/pgo-workflow.md [blocked].

Related skills

  • Use skills/compilers/gcc for GCC flag context
  • Use skills/compilers/clang for Clang PGO and SamplePGO setup
  • Use skills/profilers/linux-perf for collecting SamplePGO perf data
  • Use skills/profilers/flamegraphs to identify hot paths before applying PGO

Source and attribution

Source:mohitmishra786/low-level-dev-skillsinskills/compilers/pgoat commitbdc5847

License: No license

Content belongs to its original authors. SourceWeft indexes it from a public repository.

Report or request removal