pgo — Claude Code skill: what it does, how to install
Guides profile-guided optimisation and post-link BOLT layout tuning for C and C++ binaries using GCC or Clang.
npx skills add mohitmishra786/low-level-dev-skills --skill pgo -a claude-codeWhat pgo does
The skill steers assistants through two-stage PGO pipelines for C and C++ programs. It covers the full cycle: building an instrumented binary, running representative workloads, gathering runtime stats, and recompiling with profile data.
It details GCC flags like -fprofile-generate alongside -fprofile-correction for non-deterministic runs. For Clang, the skill details IR-based workflows with llvm-profdata, lightweight SamplePGO execution via Linux perf, and CMake switches. It also incorporates post-link layout reordering with llvm-bolt.
Without Linux perf on the host system, SamplePGO and BOLT workflows fail. Applying PGO before testing standard -O3 -march=native brings little gain: runtime improvements center on branch-heavy routines and irregular call patterns.
What it helps with
- configure two-stage PGO compilation for GCC or Clang
- collect non-intrusive runtime samples using Linux
perfand SamplePGO - reorder binary basic blocks using BOLT to improve instruction cache hits
- integrate PGO instrumentation flags into
CMakeLists.txt
Example prompts for the agent
- Show me the two-stage GCC flags needed for PGO profiling.
- Help me configure CMake options to toggle Clang PGO.
- How do I run llvm-bolt on my compiled binary?
How to install pgo
1Skills CLI (Vercel)
npx skills add mohitmishra786/low-level-dev-skills --skill pgo -a claude-code2Manually: put the files in place
~/.claude/skills/pgo/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/pgo/
1Skills CLI (Vercel)
npx skills add mohitmishra786/low-level-dev-skills --skill pgo -a codex2Manually: put the files in place
.agents/skills/pgo/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add mohitmishra786/low-level-dev-skills --skill pgo -a cursor2Manually: put the files in place
.cursor/skills/pgo/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install mohitmishra786/low-level-dev-skills pgo2Manually: put the files in place
.github/skills/pgo/SKILL.md1Skills CLI (Vercel)
npx skills add mohitmishra786/low-level-dev-skills --skill pgo -a gemini-cli2Platform CLI
gemini skills install https://github.com/mohitmishra786/low-level-dev-skills --path skills/compilers/pgoManually: put the files in place
.devin/skills/pgo/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add mohitmishra786/low-level-dev-skills --skill pgo -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about pgo
How to install pgo in Claude Code?
Run npx skills add mohitmishra786/low-level-dev-skills --skill pgo -a claude-code. The file will be placed in ~/.claude/skills/pgo/SKILL.md.
What does the pgo skill do?
It guides coding assistants through profile-guided optimization workflows for C and C++ compilers, including GCC, Clang, and BOLT.
When should BOLT be used instead of standard PGO?
BOLT acts on the final linked binary rather than source code. It reorganizes functions and basic blocks after PGO to maximize instruction cache locality.
Source text
SKILL.md · MIT
---
name: pgo
description: 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.
---
# 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 instrumentation
gcc -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 profile
gcc -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 build
clang -O2 -fprofile-instr-generate prog.c -o prog_instr
# Step 2: Run workload (generates default.profraw)
./prog_instr < workload.input
LLVM_PROFILE_FILE="prog-%p.profraw" ./prog_instr # per-PID files for parallel runs
# Step 3: Merge raw profiles
llvm-profdata merge -output=prog.profdata *.profraw
# Step 4: Optimised build
clang -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 stacks
clang -O2 -fno-omit-frame-pointer prog.c -o prog
# Step 2: Sample with perf
perf record -b -e cycles:u ./prog < workload.input
perf script -F ip,brstack > perf.script # or use perf2bolt
# Step 3: Convert perf data
llvm-profgen --binary=./prog --perf-script=perf.script \
--output=prog.profdata
# Step 4: Optimised build
clang -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: instrument
cmake -S . -B build-pgo-instr -DPGO_INSTRUMENT=ON -DCMAKE_BUILD_TYPE=Release
cmake --build build-pgo-instr -j$(nproc)
# Collect profile
./build-pgo-instr/prog < workload.input
llvm-profdata merge -output=prog.profdata *.profraw
# Phase 2: optimised
cmake -S . -B build-pgo -DPGO_USE=ON -DCMAKE_BUILD_TYPE=Release
cmake --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 support
clang -O2 -Wl,--emit-relocs prog.c -o prog
# Step 2: Collect profile with perf
perf record -e cycles:u -b ./prog < workload.input
perf2bolt prog -p perf.data -o prog.fdata
# Or use instrumented BOLT
llvm-bolt prog -instrument -o prog.instr
./prog.instr < workload.input
# Generates /tmp/prof.fdata
# Step 3: Apply BOLT optimisation
llvm-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 build
perf stat ./prog_baseline < workload.input
perf stat ./prog_pgo < workload.input
# Check which functions are hot in each
perf record ./prog_pgo < workload.input
perf report --stdio | head -30
```
For full workflow details and Clang vs GCC profile format notes, see [references/pgo-workflow.md](references/pgo-workflow.md).
## 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
© mohitmishra786 · MIT · mohitmishra786/low-level-dev-skills