smoke_regalloc_step.nx source
↩ module page · 76 lines · 2550 B
1// Replay regalloc_function step-by-step on a binop function,
2// exiting with a different code at each checkpoint. Whichever
3// code we exit with tells us the LAST step that completed.
4
5import "syscalls.nx"
6import "types.nx"
7import "ir.nx"
8import "regalloc.nx"
9
10func main() -> i64 {
11 let m_raw: *u8 = sys_mmap(256)
12 let m: *Module = m_raw as *Module
13 m.functions = 0 as *Function
14 m.n_functions = 0
15 let f: *Function = ir_function_new(m, "x" as *u8, 1, ir_type_i64())
16 let b: *BasicBlock = ir_block_new(f)
17 let c1: i64 = ir_const_i64(f, 10)
18 let c2: i64 = ir_const_i64(f, 20)
19 ir_emit_binop(b, OP_ADD, c1, c2, ir_type_i64())
20
21 // -- inline regalloc_function steps --
22 let intv_raw: *u8 = sys_mmap(f.n_values * 48 + 16)
23 let intv: *Interval = intv_raw as *Interval
24 let calls_raw: *u8 = sys_mmap(4096)
25 let calls: *i64 = calls_raw as *i64
26 let bb_start_raw: *u8 = sys_mmap(f.n_blocks * 8 + 16)
27 let bb_start: *i64 = bb_start_raw as *i64
28 let bb_end_raw: *u8 = sys_mmap(f.n_blocks * 8 + 16)
29 let bb_end: *i64 = bb_end_raw as *i64
30 let nc_raw: *u8 = sys_mmap(16)
31 let nc_ptr: *i64 = nc_raw as *i64
32 *nc_ptr = 0
33 build_intervals(f, intv, calls, nc_ptr, bb_start, bb_end)
34 mark_crosses_call(intv, f.n_values, calls, *nc_ptr)
35
36 let ids_raw: *u8 = sys_mmap(f.n_values * 8 + 16)
37 let ids: *i64 = ids_raw as *i64
38 var n_sorted: i64 = 0
39 var v: i64 = 0
40 while v < f.n_values {
41 let iv: *Interval = intv_at(intv, v)
42 if iv.start >= 0 {
43 ids[n_sorted] = v
44 n_sorted = n_sorted + 1
45 }
46 v = v + 1
47 }
48 sort_by_start(ids, n_sorted, intv)
49
50 let mask_raw: *u8 = sys_mmap(16)
51 let mask: *i64 = mask_raw as *i64
52 *mask = 0
53 let spill_bytes: i64 = linear_scan(intv, ids, n_sorted, mask)
54
55 let locs_raw: *u8 = sys_mmap(4096)
56 let locs: *ValueLoc = locs_raw as *ValueLoc
57 let lbase: i64 = locs as i64
58 // outer if + TWO nested ifs (the original failing pattern)
59 var ki: i64 = 0
60 while ki < f.n_values {
61 let iv2: *Interval = intv_at(intv, ki)
62 let l: *ValueLoc = (lbase + ki * 16) as *ValueLoc
63 if iv2.start >= 0 {
64 if iv2.reg >= 0 {
65 l.kind = 0
66 l.idx = iv2.reg
67 }
68 if iv2.reg < 0 {
69 l.kind = 1
70 l.idx = iv2.slot
71 }
72 }
73 ki = ki + 1
74 }
75 return __syscall(93, 100, 0, 0, 0, 0, 0)
76}