code wiki / _hdl_build / nx_cap_detect_ir_candidate_t278.nx

nx_cap_detect_ir_candidate_t278.nx source

↩ module page · 112 lines · 4855 B

1// Read-only IR capacity facts for the existing janitor detector. 2// Reuses compiler SSA, folded named constants and actual store widths. 3// No source rewrite or range-based optimizer assumption. Unknown is explicit. 4import "nx_ir.nx" 5const JC_IR_UNKNOWN:i64=0 6const JC_IR_SCALAR:i64=1 7const JC_IR_POINTER:i64=2 8const JC_IR_ACCESS_IN_RANGE:i64=1 9const JC_IR_ACCESS_OUT_OF_RANGE:i64=2 10const JC_IR_I64_MAX:i64=9223372036854775807 11const JC_IR_I64_MIN:i64=0-9223372036854775807-1 12struct JcIrValue {kind:i64,value:i64,extent:i64,origin:i64} 13struct JcIrAccess {state:i64,extent:i64,offset:i64,width:i64,origin:i64,address:i64} 14func jc_ir_at(rows:*JcIrValue,id:i64)->*JcIrValue{return ((rows as i64)+id*__size_of(JcIrValue)) as *JcIrValue} 15func jc_ir_add(a:i64,b:i64,out:*i64)->i64{ 16 if b>0{if a>JC_IR_I64_MAX-b{return 0}} 17 if b<0{if a<JC_IR_I64_MIN-b{return 0}} 18 out[0]=a+b;return 1 19} 20func jc_ir_mul(a:i64,b:i64,out:*i64)->i64{ 21 // Negative multiplication and overflow remain unknown in this first pass. 22 if a<0{return 0};if b<0{return 0} 23 if b>0{if a>JC_IR_I64_MAX/b{return 0}} 24 out[0]=a*b;return 1 25} 26func jc_ir_name(f:*Function,s:*u8)->i64{ 27 if f==(0 as *Function){return 0} 28 let p:*u8=f.name_start as *u8;var n:i64=0;while s[n]!=(0 as u8){n=n+1} 29 if f.name_len!=n{return 0} 30 var i:i64=0;while i<n{if p[i]!=s[i]{return 0};i=i+1};return 1 31} 32func jc_ir_valid(f:*Function,id:i64)->i64{if id<0{return 0};if id>=f.n_values{return 0};return 1} 33func jc_ir_values(f:*Function,allocation_contract:*Function)->*JcIrValue{ 34 if f==(0 as *Function){return 0 as *JcIrValue} 35 if f.n_values<=0{return 0 as *JcIrValue} 36 if f.n_values>f.values_cap{return 0 as *JcIrValue} 37 if f.n_values>JC_IR_I64_MAX/__size_of(JcIrValue){return 0 as *JcIrValue} 38 let rows:*JcIrValue=sys_mmap_try(f.n_values*__size_of(JcIrValue)) as *JcIrValue 39 if (rows as i64)<=0{return 0 as *JcIrValue} 40 let scratch:*i64=sys_mmap_try(8) as *i64 41 if (scratch as i64)<=0{sys_munmap(rows as *u8,f.n_values*__size_of(JcIrValue));return 0 as *JcIrValue} 42 var id:i64=0 43 while id<f.n_values{ 44 let row:*JcIrValue=jc_ir_at(rows,id);let v:*Value=val_at(f,id) 45 row.kind=JC_IR_UNKNOWN;row.origin=0-1 46 if v.kind==VK_CONST_INT{row.kind=JC_IR_SCALAR;row.value=v.const_int} 47 if v.kind==VK_INSTR{ 48 let ins:*Instr=v.instr 49 if ins!=(0 as *Instr){ 50 if ins.op==OP_CALL{ 51 if ins.n_operands==1{ 52 if allocation_contract!=(0 as *Function){if ins.callee==allocation_contract{ 53 if jc_ir_valid(f,ins.op0)==1{ 54 let size:*JcIrValue=jc_ir_at(rows,ins.op0) 55 if ins.op0<id{if size.kind==JC_IR_SCALAR{if size.value>0{row.kind=JC_IR_POINTER;row.value=0;row.extent=size.value;row.origin=id}}} 56 } 57 } 58 } 59 } 60 } 61 if ins.op==OP_COPY{ 62 if jc_ir_valid(f,ins.op0)==1{if ins.op0<id{ 63 let source:*Value=val_at(f,ins.op0) 64 if source.ty!=(0 as *Type){if ins.ty!=(0 as *Type){if source.ty.size==ins.ty.size{ 65 let a:*JcIrValue=jc_ir_at(rows,ins.op0);row.kind=a.kind;row.value=a.value;row.extent=a.extent;row.origin=a.origin 66 }}} 67 }} 68 } 69 if ins.n_operands==2{ 70 if jc_ir_valid(f,ins.op0)==1{if jc_ir_valid(f,ins.op1)==1{ 71 if ins.op0<id{if ins.op1<id{ 72 let a:*JcIrValue=jc_ir_at(rows,ins.op0);let b:*JcIrValue=jc_ir_at(rows,ins.op1) 73 if a.kind==JC_IR_SCALAR{if b.kind==JC_IR_SCALAR{ 74 var ok:i64=0 75 if ins.op==OP_ADD{ok=jc_ir_add(a.value,b.value,scratch)} 76 if ins.op==OP_SUB{if b.value!=JC_IR_I64_MIN{ok=jc_ir_add(a.value,0-b.value,scratch)}} 77 if ins.op==OP_MUL{ok=jc_ir_mul(a.value,b.value,scratch)} 78 if ok==1{row.kind=JC_IR_SCALAR;row.value=scratch[0]} 79 }} 80 if a.kind==JC_IR_POINTER{if b.kind==JC_IR_SCALAR{ 81 var ok:i64=0 82 if ins.op==OP_GEP||ins.op==OP_ADD{ok=jc_ir_add(a.value,b.value,scratch)} 83 if ins.op==OP_SUB{if b.value!=JC_IR_I64_MIN{ok=jc_ir_add(a.value,0-b.value,scratch)}} 84 if ok==1{row.kind=JC_IR_POINTER;row.value=scratch[0];row.extent=a.extent;row.origin=a.origin} 85 }} 86 }} 87 }} 88 } 89 } 90 } 91 id=id+1 92 } 93 sys_munmap(scratch as *u8,8);return rows 94} 95func jc_ir_store(f:*Function,rows:*JcIrValue,ins:*Instr,out:*JcIrAccess)->i64{ 96 out.state=JC_IR_UNKNOWN;out.extent=0;out.offset=0;out.width=0;out.origin=0-1;out.address=0-1 97 if rows==(0 as *JcIrValue){return 0} 98 if ins==(0 as *Instr){return 0} 99 if ins.op!=OP_STORE{return 0} 100 if jc_ir_valid(f,ins.op0)!=1{return 0} 101 out.address=ins.op0 102 if ins.ty==(0 as *Type){return 0} 103 if ins.ty.size<=0{return 0} 104 let row:*JcIrValue=jc_ir_at(rows,ins.op0) 105 if row.kind!=JC_IR_POINTER{return 0} 106 out.extent=row.extent;out.offset=row.value;out.width=ins.ty.size;out.origin=row.origin 107 out.state=JC_IR_ACCESS_OUT_OF_RANGE 108 if row.value<0{return out.state} 109 if ins.ty.size>row.extent{return out.state} 110 if row.value>row.extent-ins.ty.size{return out.state} 111 out.state=JC_IR_ACCESS_IN_RANGE;return out.state 112}