code wiki / _hdl_build / nx_js_regalloc_probe.nx
nx_js_regalloc_probe.nx source
↩ module page · 63 lines · 4813 B
1// nx_js_regalloc_probe.nx -- validates the register-allocation eligibility DETECTOR (jit_intloop_eligible),
2// step 1 of the sovereign optimizing tier. Compiles each source to bytecode and asks the detector for a verdict
3// (1 eligible / 0 unsafe-op / 2 no-loop / 3 pressure). Confirms it ACCEPTS hot int loops and DECLINES anything
4// with a float/string const, division, call, closure, object, array, or no loop -- i.e. it is decline-safe by
5// construction (the codegen that consumes this only ever sees register-safe int loops). expect_exit: 0
6// license_tier: ORIGINAL
7import "nx_js_vm.nx"
8func rw(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
9func vname(v: i64) -> i64 {
10 if v == 1 { rw("ELIGIBLE " as *u8); return 0 }
11 if v == 0 { rw("unsafe-op " as *u8); return 0 }
12 if v == 2 { rw("no-loop " as *u8); return 0 }
13 if v == 3 { rw("pressure " as *u8); return 0 }
14 rw("parse-err " as *u8); return 0
15}
16func check(src: *u8, expect: i64, tal: *i64) -> i64 {
17 tal[1] = tal[1] + 1
18 let v: i64 = js_regalloc_probe(src)
19 var ok: i64 = 0
20 if v == expect { ok = 1; tal[0] = tal[0] + 1 }
21 rw(" ")
22 if ok == 1 { rw("OK " as *u8) } else { rw("FAIL " as *u8) }
23 rw("got="); vname(v); rw(" want="); vname(expect); rw(" <= ")
24 var n: i64 = 0; while src[n] != (0 as u8) { n = n + 1 } sys_write(1, src, n)
25 rw("\n" as *u8)
26 return 0
27}
28func main(argc: i64, argv: *i64) -> i64 {
29 rw("=== nx_js_regalloc_probe: register-allocation eligibility detector (accept int loops, decline the rest) ===\n" as *u8)
30 let tal: *i64 = sys_mmap(16) as *i64
31 tal[0] = 0; tal[1] = 0
32 // ACCEPT: hot int loops (all register-safe int ops + a back-edge + within register budget)
33 check("var s=0;var i=0;while(i<1000){s=s+((i*7)%13);i=i+1;}s" as *u8, 1, tal) // K2 kernel
34 check("var i=0;while(i<1000000){i=i+1;}i" as *u8, 1, tal) // pure counter
35 check("var s=0;var i=0;while(i<100){if(i>50){s=s+1;}i=i+1;}s" as *u8, 1, tal) // int loop w/ if (comparison->JMPF)
36 // DECLINE: unsafe opcode (float const, division, call, closure, object, array)
37 check("var s=0.5;var i=0;while(i<10){s=s+1;i=i+1;}s" as *u8, 0, tal) // float const 0.5 -> BC_PUSHK
38 check("var s=0;var i=1;while(i<10){s=s+100/i;i=i+1;}s" as *u8, 0, tal) // OP_DIV -> float
39 check("function f(){return 1;}var i=0;while(i<10){i=i+f();}i" as *u8, 0, tal) // closure+call
40 check("var a=[];var i=0;while(i<10){i=i+1;}i" as *u8, 0, tal) // array literal
41 check("var o={};var i=0;while(i<10){i=i+1;}i" as *u8, 0, tal) // object literal
42 // DECLINE: a stored/returned COMPARISON result (needs a VAL_BOOL tag the unboxed codegen can't hold)
43 check("var b=0;var i=0;while(i<10){b=(i<5);i=i+1;}b" as *u8, 0, tal) // bool stored (constraint 4)
44 // DECLINE: an uninitialized-var read (undefined, not int) -- must be excluded for unboxed soundness
45 check("var x;var i=0;var s=0;while(i<10){s=s+x;i=i+1;}s" as *u8, 0, tal) // uninit read
46 // DECLINE: a CONDITIONALLY-skipped store (x=1 inside an if) -- linear order is NOT dominance; the not-taken
47 // path would leave the register garbage. Prologue-dominance rule must catch it.
48 check("var i=0;var s=0;if(s>5){var x=1;}while(i<10){s=s+x;i=i+1;}s" as *u8, 0, tal) // conditional store
49 // DECLINE: MOD by a VARIABLE (could be 0 at runtime -> NaN, unrepresentable in an unboxed int reg)
50 check("var s=0;var k=7;var i=0;while(i<10){s=s+(i%k);i=i+1;}s" as *u8, 0, tal) // %var
51 // DECLINE (v1 conservatism): a body-temp var declared inside the loop (first STORE after the prologue)
52 check("var s=0;var i=0;while(i<10){var t=i*2;s=s+t;i=i+1;}s" as *u8, 0, tal) // body temp
53 // DECLINE: no loop (straight-line int -> not worth register allocation)
54 check("var a=1;var b=2;var c=a*b+a;c" as *u8, 2, tal) // no back-edge
55 rw(" --- ");
56 let p: i64 = tal[0]; let t: i64 = tal[1]
57 let b: *u8 = sys_mmap(8); var m: i64 = p; var k: i64 = 0; if m==0{b[0]=48;k=1} while m>0{b[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var q: i64=k-1; while q>=0{sys_write(1,((b as i64)+q) as *u8,1);q=q-1}
58 rw("/"); let b2: *u8 = sys_mmap(8); var m2: i64 = t; var k2: i64 = 0; if m2==0{b2[0]=48;k2=1} while m2>0{b2[k2]=(48+(m2%10)) as u8;m2=m2/10;k2=k2+1} var q2: i64=k2-1; while q2>=0{sys_write(1,((b2 as i64)+q2) as *u8,1);q2=q2-1}
59 rw(" detector verdicts correct ---\n" as *u8)
60 if tal[0] == tal[1] { rw("=== GREEN: eligibility detector accepts int loops + declines float/call/object/array/no-loop ===\n" as *u8); return 0 }
61 rw("=== RED: a detector verdict was wrong ===\n" as *u8)
62 return 1
63}