@@ -37,45 +37,48 @@ let times = Debug.find "times"
3737
3838let stats = Debug. find " stats"
3939
40- let rewrite refs block m =
41- let m, l =
40+ let rewrite refs block m m' =
41+ let m, m', l =
4242 List. fold_left
43- ~f: (fun (m , acc ) i ->
43+ ~f: (fun (m , m' , acc ) i ->
4444 match i with
4545 | Let (x, Block (0 , [| y |], (NotArray | Unknown ), Maybe_mutable ))
46- when Var.Set. mem x refs -> Var.Map. add x y m, acc
46+ when Var.Set. mem x refs -> Var.Map. add x y m, m', acc
4747 | Let (y , Field (x , 0 , Non_float)) when Var.Map. mem x m ->
4848 (* Optimized away by Phisimpl *)
49- m, Let (y, Prim ( Extern " %identity " , [ Pv ( Var.Map. find x m) ])) :: acc
49+ m, Var.Map. add y ( Var.Map. find x m) m', acc
5050 | Offset_ref (x , n ) when Var.Map. mem x m ->
5151 let y = Var. fresh () in
5252 ( Var.Map. add x y m
53+ , m'
5354 , Let
5455 ( y
5556 , Prim
5657 ( Extern " %int_add"
5758 , [ Pv (Var.Map. find x m); Pc (Int (Targetint. of_int_exn n)) ] ) )
5859 :: acc )
59- | Set_field (x , 0 , Non_float, y ) when Var.Map. mem x m -> Var.Map. add x y m, acc
60+ | Set_field (x , 0 , Non_float, y ) when Var.Map. mem x m ->
61+ Var.Map. add x y m, m', acc
6062 | Event _ -> (
6163 ( m
64+ , m'
6265 , match acc with
6366 | Event _ :: prev ->
6467 (* Avoid consecutive events (keep just the last one) *)
6568 i :: prev
6669 | _ -> i :: acc ))
67- | _ -> m, i :: acc)
70+ | _ -> m, m', i :: acc)
6871 block.body
69- ~init: (m, [] )
72+ ~init: (m, m', [] )
7073 in
71- m, List. rev l
74+ m, m', List. rev l
7275
7376let rewrite_cont relevant_vars vars (pc' , args ) =
7477 let refs, _ = Int.Hashtbl. find relevant_vars pc' in
7578 let vars = Var.Map. filter (fun x _ -> Var.Set. mem x refs) vars in
7679 pc', List. map ~f: snd (Var.Map. bindings vars) @ args
7780
78- let rewrite_function p variables pc =
81+ let rewrite_function p variables pc subst =
7982 let relevant_vars = Int.Hashtbl. create 16 in
8083 let g = Structure. (dominator_tree (build_graph p.blocks pc)) in
8184 let rec traverse_tree g pc refs =
@@ -94,14 +97,14 @@ let rewrite_function p variables pc =
9497 Addr.Set. iter (fun pc' -> traverse_tree g pc' refs') (Structure. get_edges g pc)
9598 in
9699 traverse_tree g pc Var.Set. empty;
97- let rec traverse_tree ' g pc blocks =
100+ let rec traverse_tree ' g pc blocks subst =
98101 let block = Addr.Map. find pc p.blocks in
99102 let refs, refs' = Int.Hashtbl. find relevant_vars pc in
100103 let vars =
101104 Var.Set. fold (fun x m -> Var.Map. add x (Var. fork x) m) refs Var.Map. empty
102105 in
103106 let params = List. map ~f: snd (Var.Map. bindings vars) @ block.params in
104- let vars, body = rewrite refs' block vars in
107+ let vars, subst, body = rewrite refs' block vars subst in
105108 let branch =
106109 match block.branch with
107110 | Return _ | Raise _ | Stop -> block.branch
@@ -122,12 +125,12 @@ let rewrite_function p variables pc =
122125 in
123126 let blocks = Addr.Map. add pc { params; body; branch } blocks in
124127 Addr.Set. fold
125- (fun pc' blocks -> traverse_tree' g pc' blocks)
128+ (fun pc' ( blocks , subst ) -> traverse_tree' g pc' blocks subst )
126129 (Structure. get_edges g pc)
127- blocks
130+ ( blocks, subst)
128131 in
129- let blocks = traverse_tree' g pc p.blocks in
130- { p with blocks }
132+ let blocks, subst = traverse_tree' g pc p.blocks subst in
133+ { p with blocks }, subst
131134
132135let f p =
133136 let t = Timer. make () in
@@ -205,7 +208,17 @@ let f p =
205208 let functions =
206209 Var.Hashtbl. fold (fun _ pc s -> Addr.Set. add pc s) candidates Addr.Set. empty
207210 in
208- let p = Addr.Set. fold (fun pc p -> rewrite_function p candidates pc) functions p in
211+ let p, subst =
212+ Addr.Set. fold
213+ (fun pc (p , subst ) -> rewrite_function p candidates pc subst)
214+ functions
215+ (p, Var.Map. empty)
216+ in
217+ let p =
218+ if Var.Map. is_empty subst
219+ then p
220+ else Subst.Excluding_Binders. program (Subst. from_map subst) p
221+ in
209222 if times () then Format. eprintf " reference unboxing: %a@." Timer. print t;
210223 if stats ()
211224 then Format. eprintf " Stats - reference unboxing: %d@." (Var.Hashtbl. length candidates);
0 commit comments