Skip to main content
Markdown

Optimization Reference

This reference defines PGO configuration, candidate presets, and advanced compiler controls. Follow the PGO walkthrough for setup and a complete optimization session; use this page to adjust acceptance criteria or investigate a specific transformation.

Configuration​

Settings belong under [targets.NAME.optimize] in exaloop.toml.

SettingPurpose
train, tune, holdoutRequired, separate lists of executable argument arrays
inputsAdditional data, imports, verifier scripts, and native dependencies to fingerprint
presetsCandidate policies; omitted means ["pgo"]
samplesPaired timing samples; default 7
timeoutPer-process timeout in seconds; default 60
min_gainRequired lower confidence-bound gain; default 0.03
max_regressionPer-case regression limit; default 0.05
max_code_growthMaximum native code-size ratio; default 1.25
max_memory_growthMaximum peak-RSS ratio; default 1.2
min_coverageMinimum profile-match coverage; default 0.95
verifyOptional verifier argument array replacing exact output comparison

The default verifier requires identical stdout and stderr and successful exits. A custom verifier receives the baseline and candidate stdout filenames appended to its command. It must return zero only for equivalent results. Declare its script and dependencies in inputs; see replay safety.

SDK and Session Selection​

Use a registered ext SDK or choose an unregistered one with optimize --sdk /path/to/sdk/ext or EXALOOP_OPTIMIZER_SDK. doctor --optimization --optimizer-sdk /path/to/sdk/ext --json checks a specific SDK without starting a target's optimization session.

--budget 10m bounds compilation and process execution for a session; the native capability probe counts toward it. Fingerprinting and report writing are outside the budget. --resume SESSION reuses valid artifacts but repeats measurements and holdout checks. Global --dry-run prints the plan without running the probe; global --no-open suppresses the dashboard.

Presets​

BuildPGOAdditional Exaloop passes
Default baselineNoNormal default inlining and DFA settings
pgoYesDisabled to isolate LLVM PGO
compact, balanced, aggressiveYesExperimental inlining and DFA policies

Omitting presets evaluates only pgo. The default optimizer baseline is retained unless the candidate passes the tuning and holdout gates. To study the experimental combinations, request them explicitly:

Configuration
presets = ["pgo", "compact", "balanced", "aggressive"]

Such runs are labeled experimental in the CLI and report. The Exaloop validation matrix established no incremental gain above 3% over PGO-only across its five workloads; preset search is not the default strategy. Profile-cold calls do not consume extra inline trials, and late reconsideration prioritizes hotter sites. Numerical semantics and legality rules are unchanged.

Older reports used a baseline with both extra passes disabled. They are not directly comparable with the current default-optimizer baseline; inspect each report's baseline label. Changed CLI fingerprints invalidate session reuse.

Additional Compiler Passes​

You can use the compiler passes without a PGO session. Choose an SDK matching your compiler and LLVM build:

Terminal
OPT_SDK=/path/to/sdk/ext
codon build -release -plugin "$OPT_SDK" -o program program.codon
./program

Context-sensitive inlining and DFA jump threading are enabled by default for release builds. Debug builds load the plugin without enabling these passes. There is no Codon module to import or optimizer runtime library to deploy.

Controls​

ControlDefault / behavior
CODON_EXT_INLINEUnset = 1; contextual inlining and late reconsideration
CODON_EXT_DFAUnset = 1; late DFA jump threading
-enable-dfa-jump-thread=falseExplicit LLVM disable takes precedence
-enable-dfa-jump-thread=trueLLVM controls enablement; plugin avoids duplicate insertion
CODON_EXT_INLINE_GROWTHAdded-instruction budget per caller: 512, maximum 16384
CODON_EXT_INLINE_TRIALSTrial budget: 128, maximum 4096
CODON_EXT_INLINE_WORKEstimated-work budget: 262144, maximum 16777216

Set environment controls when invoking the compiler, not the finished binary. The two pass switches accept 0 or 1; other values are rejected in release compilation. Explicit LLVM DFA flags take precedence over plugin defaults.

Compare a Build​

Build the same source with a plain compiler, a disabled plugin, each individual pass, and the default combination. Check outputs before comparing timings:

Terminal
codon build -release -o baseline program.codon
CODON_EXT_INLINE=0 CODON_EXT_DFA=0 \
codon build -release -plugin "$OPT_SDK" -o disabled program.codon
CODON_EXT_INLINE=1 CODON_EXT_DFA=0 \
codon build -release -plugin "$OPT_SDK" -o inline-only program.codon
CODON_EXT_INLINE=0 CODON_EXT_DFA=1 \
codon build -release -plugin "$OPT_SDK" -o dfa-only program.codon
codon build -release -plugin "$OPT_SDK" -o enabled program.codon

The disabled build isolates pipeline changes unrelated to the two passes. To investigate an effect, emit LLVM IR with -llvm and compare calls, allocations, switches, and loops. Fewer instructions do not establish a runtime gain; record compilation time and native code size too. Use the profiler to investigate the affected execution paths.

Context-Sensitive Inlining​

LLVM's normal inliner estimates a call's benefit before changing it. This plugin adds a trial for selected calls above the normal cost threshold: clone the caller, inline, simplify, and compare instruction counts. Candidates include constant arguments and small call groups sharing a noncaptured stack allocation. Two cleanup rounds run scalar replacement, mem2reg, early CSE, SCCP, instruction combining, control-flow simplification, and dead-code elimination.

An inline is accepted when the cleaned caller does not grow, or when enough materialized instructions disappear within the growth budget. These are static heuristics, not a performance oracle. A late pass tries coroutine-frame elision and reconsiders calls in singleton call-graph components, which can simplify generator state machines.

Fixed implementation limitValue
Caller instructions1,500
Callee instructions400
Calls in a shared-allocation group4

The configurable budgets are listed above. The pass respects @noinline and LLVM legality checks; it excludes direct recursion, presplit coroutine callees, size-optimized callers, and protected JIT/kernel functions. It does not turn indirect calls into direct calls. Remarks use codon-ext-inline / Trial.

DFA Jump Threading​

DFA jump threading simplifies control flow when possible state transitions are known. The plugin runs LLVM's existing pass late in scalar optimization, after other simplifications can expose transitions. Some generator-derived loops benefit; not every switch can be eliminated. Late coroutine and DFA passes run at optimization levels intended for speed.

Low-Level PGO Controls​

The CLI manages these for ordinary PGO sessions. They are exposed for tooling and compiler experiments:

ControlMeaning
CODON_EXT_PGO_GENERATE=1Instrument a release build; link the SDK profile runtime
CODON_EXT_PGO_USE=FILELoad an indexed profile; mutually exclusive with generation
CODON_EXT_PGO_REPORT=FILEWrite function-profile match and execution coverage

Generation/use occurs once at the first LLVM pipeline-start checkpoint. Codon's second O3 run preserves counter metadata and regenerates derived call-graph profile metadata. The LLVM matcher diagnoses function/hash mismatches; coverage distinguishes matched zero-count functions from executed functions. Available inline remarks and per-candidate coverage appear in the report.

The supplied SDK includes the matching profile runtime and exaloop-profdata merger. exaloop doctor --optimization checks that these components work with the active compiler before a tuning session begins.