code wiki / (root) / nx_regalloc.nx

nx_regalloc.nx

buildroot/runtime/nx_regalloc.nx

42982 B1112 linesdepth 4pulls 5 transitivereach 46 importersview sourcekind librarytopic regalloc
docsdependenciesstructsconstsfunctions

about

regalloc.nx -- linear-scan register allocator, in NishiLang. Port of regalloc.c. Poletto-Sarkar 1999 with back-edge extension (so values live across a loop keep their register). Separate pools for caller-clobbered temps (t0..t3) and callee-saved registers (s0..s11). Values that cross a call go to s-regs; the emitted function saves only the s-regs it touched. Produces a ValueLoc table: one entry per Value, either { kind = REGISTER, idx = reg_index } or { kind = SPILLED, idx = sp-relative byte offset }. Shared struct layout with ir.nx: same Value/Instr/BasicBlock/ Function shapes. Redeclared here for scope; future module-import eliminates the duplication.

dependencies 3 imports · 26 importers

nx_syscalls.nx nx_types.nx nx_ir.nx nx_regalloc.nx _offc_probe_irbuild.nx _offc_regalloc_min.nx nx_main.nx nx_nxc.nx nx_regalloc_liveness_diag.nx nx_regalloc_soundness_test.nx nx_smoke_nxc_pipeline.nx nx_smoke_nxc_pipeline10.nx nx_smoke_nxc_pipeline13.nx nx_smoke_nxc_pipeline15.nx

diagram shows first 10 each side; +0 more imports, +16 more importers in the complete lists below.

imports: nx_syscalls.nxnx_types.nxnx_ir.nx

imported by: _offc_probe_irbuild.nx_offc_regalloc_min.nxnx_main.nxnx_nxc.nxnx_regalloc_liveness_diag.nxnx_regalloc_soundness_test.nxnx_smoke_nxc_pipeline.nxnx_smoke_nxc_pipeline10.nxnx_smoke_nxc_pipeline13.nxnx_smoke_nxc_pipeline15.nxnx_smoke_nxc_pipeline2.nxnx_smoke_nxc_pipeline7.nxnx_smoke_nxc_pipeline8.nxnx_smoke_nxc_pipeline9.nxnx_smoke_nxc_tilde.nxnx_smoke_regalloc_min.nxnx_smoke_regalloc_min2.nxnx_smoke_regalloc_min3.nxnx_smoke_regalloc_min4.nxnx_smoke_regalloc_min5.nxnx_smoke_regalloc_min6.nxnx_smoke_regalloc_step.nxregalloc.nxregalloc_evict_test.nxregalloc_fpr_evict_test.nxregalloc_test.nx

structs

61struct Interval {

consts

54const FREG_MAGIC_1024: i64 = 1024
55const FREG_MAGIC_4096: i64 = 4096
94const FREG_BASE_T: i64 = 100 // ft0 = 100
95const FREG_BASE_S: i64 = 200 // fs0 = 200
96const NUM_FT: i64 = 12 // ft0..ft11
97const NUM_FS: i64 = 12 // fs0..fs11
108const VREG_BASE: i64 = 300 // v0 = 300
109const NUM_V: i64 = 32 // v0..v31
110const VREG_SCRATCH_0: i64 = 300 // v0 (ISA mask reg)
111const VREG_SCRATCH_1: i64 = 301 // v1 (spill scratch)
143const FREG_SCRATCH_4: i64 = 104 // ft4
144const FREG_SCRATCH_5: i64 = 105 // ft5
145const FREG_SCRATCH_6: i64 = 106 // ft6

functions

113func is_vec_reg(r: i64) -> i64 {
called by 1: main
118func num_vregs() -> i64 { return NUM_V - 2 } // minus v0/v1 scratches
120func is_float_reg(r: i64) -> i64 {
called by 1: main
125func is_callee_saved(r: i64) -> i64 {
133func num_regs() -> i64 { return 16 }
called by 1: linear_scan
134func num_fregs() -> i64 { return NUM_FT + NUM_FS }
151func is_float_value(f: *Function, v: i64) -> i64 {
164func intv_at(buf: *Interval, id: i64) -> *Interval {
177func build_intervals(f: *Function,
341func cl_bit_get(bs: *i64, v: i64) -> i64 {
called by 1: compute_liveness
347func cl_bit_set(bs: *i64, v: i64) -> i64 {
called by 1: compute_liveness
355func cl_words(n: i64) -> i64 {
called by 1: compute_liveness
359func compute_liveness(f: *Function, intv: *Interval,
587func mark_crosses_call(intv: *Interval, n_values: i64,
620func pop_free(free_regs: *i64, n_free_ptr: *i64,
652func expire(active: *i64, n_active_ptr: *i64,
called by 2: linear_scanlinear_scan_fpr calls 1: intv_at
678func active_insert(active: *i64, n_active_ptr: *i64,
called by 2: linear_scanlinear_scan_fpr calls 1: intv_at
723func spill_furthest_active(active: *i64, n_active_ptr: *i64,
757func linear_scan(intv: *Interval,
844func linear_scan_fpr(intv: *Interval,
932func sort_by_start(ids: *i64, n: i64, intv: *Interval) -> i64 {
973func is_rematerialisable(f: *Function, v: i64) -> i64 {
986func regalloc_function(f: *Function, locs: *ValueLoc,