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}