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}