Archive — history, not state. Kept for its reasoning and its evidence; its plan is closed.
Spectralnorm transient raw inline chain
Status: retry rejected; compiler implementation deleted. The QBE-only proof self-hosted and passed its focused tests, but the required boundary oracle disrupted in Mach before the native lane ran. There is no retry timing result and no performance claim. Historical first-attempt IL measurements below are design evidence only, not validation of this retry.
The retry also converts aot_bench/dumpil.ce from its environment-only bare
script interface to a typed one-shot command:
./pit aot_bench/dumpil.ce <file> [raw|mcode|il|asm]
The descriptor publishes a 600-second reply deadline, the actor replies only after the dump is complete, and then stops. This tooling-only change is the sole retained code from the retry; it does not affect language output.
Hypothesis
After structured loop phis and dead inlined-callee cleanup, each spectralnorm row keeps its accumulator in a QBE double and its index in a QBE integer. The hottest path nevertheless crosses the tagged PitValue representation twice per inner iteration:
divide -> qbe_new_float64 -> inlined return move
-> raw array load -> multiply -> qbe_new_float64 -> raw accumulator add
That is 12.8 million materializations in the benchmark’s 6.4 million inner
iterations. qbe_new_float64 does not allocate, but it is still an out-of-line
classification/encoding call followed by a later decode. This experiment keeps
the two intermediate arithmetic values in QBE double temporaries instead.
Candidate lowering
The QBE emitter recognizes only the exact final mcode region produced by the current inliner and numeric/array guards:
divide
<private inlined-success label>
move return, divide-result
jump <private continuation>
<zero-reference empty inlined-bad label>
<continuation>
load array element
jump <load join>
<zero-reference null alternate>: null
<load join>: is_num; jump_false <numeric error>
multiply product, return, element
jump <product join>
<numeric error>: ... call panic ... disrupt
<product join>
add raw-accumulator, raw-accumulator, product
The selected divide, move, and multiply do not write an intermediate PitValue.
Both arithmetic results still go through canonical_double, exactly as every
other raw arithmetic boundary does. The array helper retains its ordinary
frame write for the loaded element and returns the same value in the raw lane.
The result is therefore a compiler temporary only: no Pit frame slot, heap
object, persistent metadata, actor state, or GC root is added.
The empty inlined-bad label is omitted only after proving it has no reference and is immediately followed by the continuation. This prevents the QBE text walker from manufacturing an unreachable syntactic predecessor which lacks the raw return definition.
Rejection proof
The recognizer declines unless all of these facts hold:
- nan64 raw-double lowering and a pre-existing raw numeric loop lane are active;
- the function has no disruption handler;
- receiver and index are point-proven array and integer at the exact load;
- every success, continuation, load, error, and product label has the exact reference count expected by the compiler-private shape;
- the inline alternate and load-null labels have no external reference;
- the divide, return, and product slots are distinct, unpromoted, and not captured by any nested closure;
- the divide value is dead after the load overwrites its slot, the return value is dead after multiplication, and the product is dead after the accumulator add on every successor reachable after its definition;
- the guarded cold path ends in
disruptbefore the product join.
The numeric-error edge branches before the product instruction and therefore
has no raw product value to preserve. Its physical frame slot retains an
ordinary tagged value, while the unique cold edge terminates in disrupt.
Applying post-definition product liveness to that pre-definition edge is both
unnecessary and overly conservative: the generic liveness walker deliberately
stops at the diagnostic call because call operands are variable-shaped.
There is no semantic call, invoke, resume, or suspension point while the raw value is live. The exact array helper is a nonallocating C/QBE helper which cannot suspend an actor; it receives no raw value and returns before the raw return temporary is consumed. The cold diagnostic call is on the branch where the product temporary has not been defined and terminates in disruption.
Proof regressions cover the positive spectral-like region, a second edge into the inline continuation, and a child closure capturing the return cell. A runtime oracle covers finite results, division infinity, NaN, nan64 range overflow, signed zero, and the array-element disruption edge. Expected Mach and native result is 63.
Acceptance gate
This retry is based on exact language-performance baseline 9313e4ee; its
historical first attempt was based on the earlier dead-callee cleanup.
Before acceptance it must show:
- focused compiler and numeric-boundary regressions pass;
- spectral mcode is byte-identical to
9313e4ee(QBE-only change); - exactly the two intended row regions select, with both hot
qbe_new_float64materializations absent; - ARM64 assembly and native code size do not grow enough to outweigh a stable runtime gain;
- alternating isolated spectralnorm A/B runs preserve checksum 1,623,647,009 and produce a repeatable native improvement;
- the default suite and deterministic compiler fuzz remain green.
If inline canonicalization merely replaces two helper calls with more branch or register-pressure cost and does not win repeatedly, the lowering should be deleted. Compilation time and compiler-memory cost are not acceptance criteria for this campaign; target code, target memory, correctness, and runtime are.
First-attempt results
The first self-host attempt exposed a real compiler-size constraint. Adding
three label-walk scratch locals made compile_fn require 255 Mach slots, then
Mach lowering needed its mandatory 256th scratch and rejected the module. The
top-level command reported only mach compile/cache failed; the actual
requires 256 register slots diagnostic was present only in
.pit/log/observe.jsonl. Reusing existing emitter scratch bindings restored the
self-host margin. Focused compiler tests then passed 115/115, including the
positive region and both rejection tests.
The spectralnorm emitted-IL audit selected exactly two regions, one in each row function. It confirmed:
_inl1_stone_escape_done_1and its sibling were zero-reference, operationless generated labels with no source origin, and were absent from candidate QBE;return_rawis defined before the array-load diamond and therefore dominates both paths intoload_done;- the only alternate to the product-success edge ends in the original panic
call and
disrupt/return, so it does not reachmultiply_num_done_*_end; - diagnostic operations and their original mcode line/column operands were unchanged because the experiment modified only QBE emission;
- candidate IL was 173,730 bytes versus 176,499 bytes at
ae3fd976, a reduction of 2,769 bytes (1.57%).
The boundary fixture returned 63 in Mach and exercised the intended diagnostic
origin for the null-element edge. Its native compile reached QBE successfully
(163,676 bytes IL to 99,960 bytes assembly), but the in-process node stopped
the benchmark actor immediately afterward without completing the async native
build. A fresh daemon-mode attempt then remained alive without a listener for
the full 120-second readiness timeout. Two earlier successful commands also
left a live PID and socket whose endpoint refused the very next command; each
was recovered by killing only the exact worktree PID.
No native correctness result or spectralnorm timing was therefore obtained. The compiler lowering, proof tests, benchmark registration, and oracle were deleted. The result remains useful evidence: this exact raw chain reduces IL and has a credible CFG proof, but it must be retried only after native builds can run deterministically in an isolated worktree. The retry should start from this document rather than recover the discarded implementation.
Retry results
The retry reconstructed the QBE-only chain, its positive proof, two fail-closed
proof tests, and a boundary oracle. The first focused run self-hosted but passed
116/117: only the positive selector missed. In-process IL inspection showed
that the raw array helper, fraw accumulator, non-promoted scratch slots, label
references, and control shape were all present. The stale rejection was
value_live_from(error_pos, product_slot): that edge branches before the
product instruction, so the raw product has not been defined there. Its unique
cold successor ends in disrupt and cannot reach the product join. Removing
only that logically inapplicable pre-definition check left the structural cold
edge proof intact. The final focused run then passed 117/117, including the
positive selector and both rejection tests.
The required boundary oracle expected 63 from both Mach and native. Its
null-element case deliberately enters the original numeric diagnostic edge and
attempts to catch the disruption. Mach propagated that disruption out of the
benchmark thunk instead. Rewriting the catch wrapper from a decorated function
declaration to the repository’s established decorated function-expression form
failed identically. Both attempts stopped in measure_run before a Mach result
was recorded; native compilation did not begin. Under the acceptance gate this
means the representation boundary remains unproven, so spectral IL/assembly
comparison and alternating A/B timing were not run. The emitter changes, proof
tests, benchmark registration, and oracle were deleted. No default-suite or
fuzz claim is made for the deleted candidate.
Tooling findings
- A cold rebuild can expire before the target publishes its descriptor. The
descriptor’s 600-second command deadline is learned after realization, so it
cannot protect that earlier phase. The CLI printed only
reply timeoutwhile compilation continued in the shop. A warm retry used the completed cache. - After one focused daemon run, the exact worktree process was alive and idle
but its endpoint was unavailable. It was killed by exact PID;
PIT_INPROCESS=1then provided deterministic, serialized inspection and focused execution. - Temporary diagnostic string construction inside the already-large emitter made compiler range analysis pathological. The exact isolated process stayed at roughly 100% CPU for 10 minutes 46 seconds and was terminated at the agreed cap. That diagnostic expansion was removed completely. The restored candidate itself self-hosted in about one minute, so the blow-up is recorded as rejected diagnostic/tooling behavior, not target-code behavior.
The practical tooling fixes are to apply an explicit realization/build deadline independently of a command’s descriptor deadline, surface the active compile phase when an internal request expires, and provide an owned in-process/offline compiler-dump command so IR inspection does not require a daemon lifecycle.
Source: plans/archive/perf-2026-07/perf-spectral-inline-raw-chain.md