design-md-consolidation 2.4: condense Decision 11 mono-vs-vdisp correction history to state-only rationale

This commit is contained in:
2026-05-10 12:31:37 +02:00
parent 38d357d58a
commit 774886bb37
+12 -16
View File
@@ -1520,22 +1520,18 @@ After this pass, the IR contains no class machinery — only ordinary
monomorphic functions and direct calls. Codegen sees no difference
between a hand-written `show_int` and a synthesised `show__Int`.
**Why mono, not virtual dispatch (the empirically-grounded version).**
The original rationale implicitly argued that mono saves a per-call
indirect-jump cost. A mono-vs-vdisp micro-benchmark
(`bench/mono_dispatch.py`, JOURNAL bench-notes entry) refutes
that specific claim: on a saturating branch predictor with a
monomorphic indirect target, indirect dispatch is free relative to
the same-shape non-inlined direct call.
The correct rationale is one level up: **mono makes the call target
visible to the optimiser, unlocking inlining and downstream loop
transformations that virtual dispatch prevents in principle.** The
measured end-to-end win on a tight LCG hot loop is substantial vs
non-inlinable direct call and larger still vs polymorphic vdisp (4 distinct
targets cycling). On larger callee bodies or cold call sites the
inlining win shrinks toward zero, but the architectural claim — "mono
enables optimisations vdisp forbids" — holds across the spectrum,
while the older "saves an indirect call" framing does not.
**Why mono, not virtual dispatch.** Monomorphisation makes the call
target visible to the optimiser, unlocking inlining and downstream
loop transformations that virtual dispatch prevents in principle.
On a saturating branch predictor with a monomorphic indirect
target, the indirect call itself is comparable in cost to a
non-inlined direct call — the win is in what the optimiser can do
with the visible target, not in the call instruction. The
end-to-end gain shrinks toward zero on larger callee bodies and
cold call sites, but the architectural claim — "mono enables
optimisations vdisp forbids" — holds across the spectrum
(`bench/mono_dispatch.py` and the corresponding JOURNAL bench-notes
entry record the measured ratios).
The separator is `__` rather than `#` or `@` because `#` and `@`
are invalid in LLVM IR global identifiers (the IR verifier rejects