@@ -37,45 +37,48 @@ let times = Debug.find "times"
37
37
38
38
let stats = Debug. find " stats"
39
39
40
- let rewrite refs block m =
41
- let m, l =
40
+ let rewrite refs block m m' =
41
+ let m, m', l =
42
42
List. fold_left
43
- ~f: (fun (m , acc ) i ->
43
+ ~f: (fun (m , m' , acc ) i ->
44
44
match i with
45
45
| 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
47
47
| Let (y , Field (x , 0 , Non_float)) when Var.Map. mem x m ->
48
48
(* 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
50
50
| Offset_ref (x , n ) when Var.Map. mem x m ->
51
51
let y = Var. fresh () in
52
52
( Var.Map. add x y m
53
+ , m'
53
54
, Let
54
55
( y
55
56
, Prim
56
57
( Extern " %int_add"
57
58
, [ Pv (Var.Map. find x m); Pc (Int (Targetint. of_int_exn n)) ] ) )
58
59
:: 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
60
62
| Event _ -> (
61
63
( m
64
+ , m'
62
65
, match acc with
63
66
| Event _ :: prev ->
64
67
(* Avoid consecutive events (keep just the last one) *)
65
68
i :: prev
66
69
| _ -> i :: acc ))
67
- | _ -> m, i :: acc)
70
+ | _ -> m, m', i :: acc)
68
71
block.body
69
- ~init: (m, [] )
72
+ ~init: (m, m', [] )
70
73
in
71
- m, List. rev l
74
+ m, m', List. rev l
72
75
73
76
let rewrite_cont relevant_vars vars (pc' , args ) =
74
77
let refs, _ = Int.Hashtbl. find relevant_vars pc' in
75
78
let vars = Var.Map. filter (fun x _ -> Var.Set. mem x refs) vars in
76
79
pc', List. map ~f: snd (Var.Map. bindings vars) @ args
77
80
78
- let rewrite_function p variables pc =
81
+ let rewrite_function p variables pc subst =
79
82
let relevant_vars = Int.Hashtbl. create 16 in
80
83
let g = Structure. (dominator_tree (build_graph p.blocks pc)) in
81
84
let rec traverse_tree g pc refs =
@@ -94,14 +97,14 @@ let rewrite_function p variables pc =
94
97
Addr.Set. iter (fun pc' -> traverse_tree g pc' refs') (Structure. get_edges g pc)
95
98
in
96
99
traverse_tree g pc Var.Set. empty;
97
- let rec traverse_tree ' g pc blocks =
100
+ let rec traverse_tree ' g pc blocks subst =
98
101
let block = Addr.Map. find pc p.blocks in
99
102
let refs, refs' = Int.Hashtbl. find relevant_vars pc in
100
103
let vars =
101
104
Var.Set. fold (fun x m -> Var.Map. add x (Var. fork x) m) refs Var.Map. empty
102
105
in
103
106
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
105
108
let branch =
106
109
match block.branch with
107
110
| Return _ | Raise _ | Stop -> block.branch
@@ -122,12 +125,12 @@ let rewrite_function p variables pc =
122
125
in
123
126
let blocks = Addr.Map. add pc { params; body; branch } blocks in
124
127
Addr.Set. fold
125
- (fun pc' blocks -> traverse_tree' g pc' blocks)
128
+ (fun pc' ( blocks , subst ) -> traverse_tree' g pc' blocks subst )
126
129
(Structure. get_edges g pc)
127
- blocks
130
+ ( blocks, subst)
128
131
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
131
134
132
135
let f p =
133
136
let t = Timer. make () in
@@ -205,7 +208,17 @@ let f p =
205
208
let functions =
206
209
Var.Hashtbl. fold (fun _ pc s -> Addr.Set. add pc s) candidates Addr.Set. empty
207
210
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
209
222
if times () then Format. eprintf " reference unboxing: %a@." Timer. print t;
210
223
if stats ()
211
224
then Format. eprintf " Stats - reference unboxing: %d@." (Var.Hashtbl. length candidates);
0 commit comments