LTO vs PGO
That they are two names for "the aggressive build". They answer different questions: LTO gives the optimizer more code to look at, PGO gives it evidence about what that code does. They compose, and neither substitutes for the other — LTO without a profile still guesses which calls are hot.
Link-time optimization
When the program is split across many translation units and the interesting call sites cross them.
Profile-guided optimization
When you have a workload representative enough to measure, and the wins you need are in layout, branch direction and inlining decisions.
| Aspect | Link-time optimization | Profile-guided optimization |
|---|---|---|
| What it adds | Scope — the optimizer sees across translation-unit boundaries. | Evidence — measured branch and call frequencies. |
| When it happens | At link time, on IR the compiler deferred instead of lowering. | On a second compilation, reading counters from an instrumented or sampled run. |
| Main wins | Cross-module inlining, better alias facts, dead code across the whole program. | Hot/cold splitting, block layout, more selective inlining, better register priorities. |
| Main cost | Link time and memory; the link step becomes the build bottleneck. | The workflow — building twice and keeping the profile current. |
| How it goes wrong | Longer builds and harder debugging for a win that was never measured. | An unrepresentative profile optimizes for the benchmark and pessimises production. |
| Prerequisite | Every input object must be compiled with it enabled. | A workload someone is willing to defend as representative. |