code wiki / _hdl_build / nx_regalloc_linscan.nx

nx_regalloc_linscan.nx

buildroot/runtime/_hdl_build/nx_regalloc_linscan.nx

5403 B143 linesdepth 2pulls 2 transitivereach 7 importersview sourcekind librarytopic regalloc
docsdependenciesstructsconstsfunctions

about

nx_regalloc_linscan.nx -- linear-scan register allocation, bits-up + PROVABLE. This is the keystone lever the ONGOING race vs C keeps pointing at: Nishi's stack/memory-resident codegen loads every operand and stores every result (the ~2x speed + ~6x code-density tax the race measured). Register allocation keeps live values in registers; only SPILLS touch memory. Built STANDALONE + proven first (NOT hand-patched into the protected self-hosting compiler -- a prior "g1 regalloc" attempt silently miscompiled high-pressure functions; we prove soundness here, then the loop absorbs it into codegen under governance). Algorithm: Poletto & Sarkar, "Linear Scan Register Allocation," ACM TOPLAS 1999 (the alternative is Chaitin graph-coloring, SIGPLAN 1982; linear scan is faster and good enough -- the right fit for a spore that re-derives its stack on deploy). Model IR: a straight-line block of n instructions; instruction i DEFINES virtual register i and USES up to two prior vregs (u0[i], u1[i]; -1 = none). The live interval of vreg v is [v (its def), last_use[v]]. Linear scan allocates nreg physical registers across the intervals, spilling the farthest-future interval when it runs out (the standard heuristic).

dependencies 1 imports · 3 importers

nx_syscalls.nx nx_regalloc_linscan.nx nx_regalloc_interp.nx nx_regalloc_linscan_test.nx nx_regalloc_race_kernel_test.nx

imports: nx_syscalls.nx

imported by: nx_regalloc_interp.nxnx_regalloc_linscan_test.nxnx_regalloc_race_kernel_test.nx

structs

none

consts

23const RA_SPILL: i64 = 0 - 1

functions

26func ra_compute_last_use(n: i64, u0: *i64, u1: *i64, last_use: *i64) -> i64
41func ra_linscan(n: i64, nreg: i64, last_use: *i64, alloc: *i64) -> i64
called by 5: mainmainmainra_runmain calls 1: sys_mmap
97func ra_validate(n: i64, last_use: *i64, alloc: *i64, nreg: i64) -> i64
120func ra_baseline_mem(n: i64, u0: *i64, u1: *i64) -> i64
called by 2: ra_runmain
133func ra_regalloc_mem(n: i64, u0: *i64, u1: *i64, alloc: *i64) -> i64
called by 2: ra_runmain