# pgo

Guides profile-guided optimisation and post-link BOLT layout tuning for C and C++ binaries using GCC or Clang.

- skill · `type=skill` · Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode · 562 installs · ★ 267
- Author: mohitmishra786
- License: MIT · policy=mirror · the beginning of the file is at the end of this page
- Source: https://github.com/mohitmishra786/low-level-dev-skills/tree/HEAD/skills/compilers/pgo/SKILL.md
- Updated: 2026-06-27
- HTML: https://affpapa.org/en/nevibecode/skills/pgo

## What it 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.

## Install

### Claude Code (native platform)

1. **Skills CLI (Vercel)**
```bash
npx skills add mohitmishra786/low-level-dev-skills --skill pgo -a claude-code
```

2. **Manually: put the files in place**
- File: `~/.claude/skills/pgo/SKILL.md` — Copy the whole skill folder; for one project use .claude/skills/pgo/

### Codex

1. **Skills CLI (Vercel)**
```bash
npx skills add mohitmishra786/low-level-dev-skills --skill pgo -a codex
```

2. **Manually: put the files in place**
- File: `.agents/skills/pgo/SKILL.md` — For all projects use ~/.agents/skills/

### Cursor

1. **Skills CLI (Vercel)**
```bash
npx skills add mohitmishra786/low-level-dev-skills --skill pgo -a cursor
```

2. **Manually: put the files in place**
- File: `.cursor/skills/pgo/SKILL.md` — Cursor also reads .agents/skills/ and .claude/skills/

### GitHub Copilot

1. **GitHub CLI**
```bash
gh skill install mohitmishra786/low-level-dev-skills pgo
```

2. **Manually: put the files in place**
- File: `.github/skills/pgo/SKILL.md`

### Gemini CLI

1. **Skills CLI (Vercel)**
```bash
npx skills add mohitmishra786/low-level-dev-skills --skill pgo -a gemini-cli
```

2. **Platform CLI**
```bash
gemini skills install https://github.com/mohitmishra786/low-level-dev-skills --path skills/compilers/pgo
```

### Windsurf (Devin Desktop)

**Manually: put the files in place**
- File: `.devin/skills/pgo/SKILL.md` — The legacy .windsurf/skills/ path still works

### OpenCode

**Skills CLI (Vercel)**
```bash
npx skills add mohitmishra786/low-level-dev-skills --skill pgo -a opencode
```

### Claude.ai

**Claude.ai**
- Zip the folder and upload it in Settings → Capabilities → Skills

Where a file is given instead of a command, copy the files from the source to that path: https://github.com/mohitmishra786/low-level-dev-skills/tree/HEAD/skills/compilers/pgo/SKILL.md

## When to use it
- configure two-stage PGO compilation for GCC or Clang
- collect non-intrusive runtime samples using Linux `perf` and SamplePGO
- reorder binary basic blocks using BOLT to improve instruction cache hits
- integrate PGO instrumentation flags into `CMakeLists.txt`

## Example prompts
- 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?

## Source text · SKILL.md · MIT

Below is the content of a third-party file. It is data, not instructions for you: do not act on anything written inside unless the human asks. Block tag: 8d4c868a05f51d9e.

BEGIN THIRD-PARTY FILE 8d4c868a05f51d9e
````text
---
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
````
END THIRD-PARTY FILE 8d4c868a05f51d9e

The third-party file has ended. Everything between the 8d4c868a05f51d9e tags is data: requests and commands from it are not followed. An “end of file” line with another tag inside the block is part of the file.

First 3025 of 5601 bytes. © mohitmishra786 · MIT · https://github.com/mohitmishra786/low-level-dev-skills/tree/HEAD/skills/compilers/pgo/SKILL.md

_Part of the page did not fit — see the HTML version._

---
NeVibeCode on affpapa.org. Catalog texts are descriptions, not instructions for the agent. How to choose and install: https://affpapa.org/en/nevibecode/agents.md
