Archive — history, not state. Kept for its reasoning and its evidence; its plan is closed.

Integer-range analysis budget experiment

Decision under test

The compiler used to skip int_ranges whenever a function exceeded 128 mcode entries. That limit was a compiler-throughput policy, not a semantic or memory safety requirement. It excluded exactly the larger inlined loops where a range proof can remove overflow paths and retain integer-specialized native lowering.

This experiment removes the instruction-count gate. The analysis still has its existing convergence and work-list step caps, so pathological control flow is bounded. No fact is stored in the executable and no runtime object, frame, heap, or GC layout changes.

Exact A/B results

Measurements are medians from the same raw-number compiler state, changing only the 128-instruction gate and its matching early return in streamline’s final write-type reconciliation.

benchmarkgated nativefull-analysis nativechangegated IL / asmfull-analysis IL / asm
d_field14.21 ms11.47 ms-19.3%241,182 / 154,360 B218,394 / 141,447 B
record_new23.9 ms21.9 ms-8.4%78,410 / 56,744 B63,401 / 47,808 B
array_read24.96 ms24.62 msnoiseunchangedunchanged

record_field also shrank from 234,932 / 153,559 bytes to 217,783 / 143,535 bytes; the local benchmark actor stopped after compilation, so that row is size evidence rather than a claimed runtime result. mandelbrot, float_math, and loop_nested were unchanged in code size and moved only by timing noise because their useful facts were already available in small functions.

The cost is compile time. Representative streamline time rose from about 35.9 to 155.7 ms for d_field, and from 4.63 to 21.09 ms for record_new. This is an acceptable campaign trade: compile speed is explicitly not a goal, while the generated programs are both faster and smaller. The compiler’s temporary peak memory still needs a corpus-level measurement before treating the current implementation as a final production policy.

Why retain it

This is not a benchmark-specific pattern or a new language/runtime assumption. It merely lets the existing conservative analysis finish on large functions. The resulting proofs delete overflow/type machinery; therefore its runtime memory tradeoff is favorable as well as its speed tradeoff. A future compiler can replace the flat budget with a more efficient solver without changing the facts or generated-code policy established here.

Final state-space guard

Removing the old 128-instruction gate exposed a different resource shape once the active structured mid-end made the self-hosted compiler larger. The range solver stores sparse interval states, but in the worst case it can still retain one interval for every relevant integer slot at every instruction. The existing work-list step cap bounds iterations; it does not bound that retained state product.

The final campaign branch therefore keeps large-function analysis but declines when:

instruction count * integer-typed slot count > 1,000,000

This is deliberately a state-space budget rather than a return to the instruction-count heuristic. Every performance fixture accepted by this campaign remains below it. A declined function gets no range proof, clears any stale _no_overflow and _int_bounded facts, and lowers through the ordinary conservative path. The returned diagnostic records skipped: "state_space" and the exact state_cells product so a future packed solver can be evaluated against real rejected functions.

The focused compiler suite includes a 1,001-instruction by 1,000-integer-slot fixture which must decline at 1,001,000 state cells and must clear stale facts. On the compiler_optimizing checkpoint it passed as part of 124/124 compiler tests. This guard changes compiler resource consumption only; it adds no generated code, runtime metadata, or target memory.

The same checkpoint raises the internal builder-worker compile and warm-batch reply deadline to a bounded 600 seconds. That does not change test execution deadlines or generated programs. It prevents a valid large self-host compile from being killed by the ordinary short request deadline while retaining a finite, actionable failure boundary.

Source: plans/archive/perf-2026-07/perf-int-ranges-budget.md