Reading the report
A diagnostic says the program is wrong. The report says what the optimizer did with a program that is right, and what stopped it where it stopped.
mettle example.mettle --release --explain -o example.exe
── optimization report: example.mettle ────────────────────────────────
where to start (1 of 1 missed optimization has a fix)
1. proven main:18 bind the array to a pointer once before the loop
proven = applied to a clone and re-checked
sum (loop @ line 7): vectorized → vpaddd, 8-wide int32 sum (AVX2)
main (loop @ line 18): NOT vectorized [store-only-fill]
18 │ for i in 0..8 {
19 │ data[i] = (int32)i + 1;
└─ reason: the loop fills the stack array `data`, whose address is
retaken on every iteration; the fill kernel indexes off one
invariant base pointer, and a fresh base each iteration is not one
└─ fix: bind the array to a pointer once before the loop
(`var p: int32* = &data[0];`) and write `p[i]` in the body
└─ verified: simulated that fix and re-ran the optimizer: this loop
then vectorizes → 8-wide int32 element-wise map (AVX2, bit-exact)
main (22 calls, lines 81-119): inlined
└─ calls: println (x9), array_sum, gcd, lo_byte, print (x8)
The verdict line
main (loop @ line 18): NOT vectorized [store-only-fill]
└──┬─┘ └──────┬──────┘ └──────┬─────┘ └───────┬───────┘
function what it is verdict decision code
The decision code appears only on a refusal, because on a success the verdict
already says what happened. It names the specific rule that declined, and it is
a link: mettle explain store-only-fill, or
its page here.
The detail lines
One line per fact, so a pattern that matches a whole reason keeps matching one line.
- reason. The specific shape the compiler found, in the terms of the rule that declined. Not a category; the actual thing about this loop.
- fix. What to write instead. Where the honest answer is that
nothing should change, the label reads
noteand the entry is kept out of the ranking. - verified. The compiler applied the fix to a clone of the function, re-ran the optimizer, and reports what happened. Advice that fails that check is replaced or withdrawn, never printed.
- still blocked. The fix helped and was not enough; this says what is left.
- calls. Repeated identical call remarks fold into one entry with a line range and a deduplicated callee census.
Where to start
The findings are in source order, which is the right order to read a file in and the wrong order to decide what to do. The block at the top answers "what do I change", ranked by what the compiler can stand behind:
proven: applied to a clone and re-checked.step 1: applied, and the loop still needs more.- no badge: suggested, not simulated.
Whole-function codegen fallbacks lead the ranking. A loop remark is a prediction about one loop; a fallback is a measurement over a whole function that already happened, and it costs every value in that function a register.
The other sections
The memory report repeats the memory and lifetime findings, and is printed only when there are any. The backend report says how much of the program reached the register-allocating backend, and groups whatever fell back to baseline codegen by cause, largest first.
Narrowing it down
--explain=matvec one function
--explain=store-only-fill one decision code
--explain=missed only the refusals
--explain=fixable only findings with a fix
--explain=proven only fixes the compiler proved
--explain=loops only loop verdicts
--explain=calls only call verdicts
The selector hides prose only. The machine-readable sidecar and the tallies stay whole-file, so a filtered run and an unfiltered one produce the same document.
For tools
--explain-json also writes
<output-stem>.explain.json: the same findings as structured
data, plus a startHere array carrying the ranking above.
--explain-all covers every file rather than the one being
compiled.
A long report goes to <output-stem>.explain.txt and stderr
gets a digest with the path. METTLE_EXPLAIN_REPORT_LINES sets the
threshold; 0 keeps everything on stderr.
The rule it follows
Every fix the report suggests has been applied to a clone and re-checked before printing. If the compiler cannot prove the advice works, it either says so or says nothing.