Skip to content

perf: spill slot free-list reuse (Issue #5)#9

Merged
jailalawat merged 1 commit into
mainfrom
issue-5-spill-slot-reuse
May 17, 2026
Merged

perf: spill slot free-list reuse (Issue #5)#9
jailalawat merged 1 commit into
mainfrom
issue-5-spill-slot-reuse

Conversation

@jailalawat

Copy link
Copy Markdown
Contributor

Summary

  • Task A: consume_use now returns a dead value's spill slot to g_spill_free when use count reaches 0. The slot is freed only here — not in regalloc_free — because regalloc_free is also called for register eviction where the value still has live uses and its spill slot must survive.
  • Task B: regalloc_alloc and ensure_spilled check g_spill_free first before growing sp_top. For functions with many short-lived spilled values, peak spill depth shrinks and the stack frame stays denser.

Key correctness insight

regalloc_free is called from two contexts:

  1. consume_use (use_cnt → 0): value is truly dead → safe to recycle its slot
  2. Explicit calls like lower_mod_magic line 17208: evicting a register to make room for MULQ/IDIV clobbers — value still has uses; freeing its slot here causes corruption

First attempt freed the slot in regalloc_free directly: 17 conformance failures (output mismatch) from values evicted for MULQ/IDIV whose recycled slots got overwritten by another spill before the original value was reloaded. Fixed by restricting the free to the consume_use path.

Test plan

  • 401/401 conformance tests pass
  • Self-host converges (2,001,998 bytes, sh2 == sh3)
  • arith_combined, fixedpoint_basic, math_mod_expression all pass (these exercise the MULQ/IDIV eviction path that was the original bug)

Closes #5

Task A: when consume_use drops a value's use_cnt to 0, the value's
spill slot (if any) is returned to g_spill_free rather than left
permanently dead. The key insight: free only from consume_use (the
true death point), not from regalloc_free which is also called for
register eviction where the value still has live uses.

Task B: in regalloc_alloc and ensure_spilled, pop a recycled slot
from g_spill_free before growing sp_top. Reduces peak spill depth
in functions with many short-lived spilled values.

- 401/401 conformance tests pass
- Self-host converges at 2,001,998 bytes
@jailalawat jailalawat merged commit a7278d4 into main May 17, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Perf: Naive Spill Slot Assignment

1 participant