@@ -45,8 +45,8 @@ let rec tail_call x f l =
4545 -> Some args
4646 | _ :: rem -> tail_call x f rem
4747
48- let rewrite_block update_count (f , f_params , f_pc , used ) pc blocks =
49- let block = Addr.Map. find pc blocks in
48+ let rewrite_block update_count (f , f_params , f_pc , used ) pc p =
49+ let block = Code. block pc p in
5050 match block.branch with
5151 | Return x -> (
5252 match tail_call x f block.body with
@@ -57,98 +57,91 @@ let rewrite_block update_count (f, f_params, f_pc, used) pc blocks =
5757 List. iter2 f_params f_args ~f: (fun p a -> Code.Var. propagate_name p a);
5858 used := true ;
5959 Some
60- (Addr.Map. add
60+ (Code. add_block
6161 pc
6262 { params = block.params
6363 ; body = remove_last block.body
6464 ; branch = Branch (f_pc, f_args)
6565 }
66- blocks ))
66+ p ))
6767 else None
6868 | None -> None )
6969 | _ -> None
7070
71- let rec traverse update_count f pc visited blocks =
71+ let rec traverse update_count f pc visited p =
7272 if not (Addr.Set. mem pc visited)
7373 then
7474 let visited = Addr.Set. add pc visited in
75- match rewrite_block update_count f pc blocks with
76- | Some blocks ->
75+ match rewrite_block update_count f pc p with
76+ | Some p ->
7777 (* The block was rewritten with a branch to the top of the function.
7878 No need to visit children. *)
79- visited, blocks
79+ visited, p
8080 | None ->
81- let visited, blocks =
82- Code. fold_children_skip_try_body
83- blocks
84- pc
85- (fun pc (visited , blocks ) ->
86- let visited, blocks = traverse update_count f pc visited blocks in
87- visited, blocks)
88- (visited, blocks)
89- in
90- visited, blocks
91- else visited, blocks
81+ Code. fold_children_skip_try_body
82+ (Code. blocks p)
83+ pc
84+ (fun pc (visited , p ) -> traverse update_count f pc visited p)
85+ (visited, p)
86+ else visited, p
9287
9388let f p =
9489 let previous_p = p in
9590 Code. invariant p;
96- let free_pc = ref (Code. free_pc p) in
97- let blocks = ref (Code. blocks p) in
91+ let p = ref p in
9892 let update_count = ref 0 in
9993 let t = Timer. make () in
10094 Addr.Map. iter
10195 (fun pc _ ->
102- let block = Addr.Map. find pc ! blocks in
96+ let block = Code. block pc ! p in
10397 let rewrite_body = ref false in
10498 let body =
10599 List. map block.body ~f: (function
106100 | Let (f , Closure (params , (pc_head , args ), cloc )) as i ->
107101 if List. equal ~eq: Code.Var. equal params args
108102 then (
109- blocks :=
103+ p :=
110104 snd
111105 (traverse
112106 update_count
113107 (f, params, pc_head, ref false )
114108 pc_head
115109 Addr.Set. empty
116- ! blocks );
110+ ! p );
117111 i)
118112 else
119- let intermediate_pc = ! free_pc in
113+ let intermediate_pc = Code. free_pc ! p in
120114 let need_to_create_intermediate_block = ref false in
121- blocks :=
115+ p :=
122116 snd
123117 (traverse
124118 update_count
125119 (f, params, intermediate_pc, need_to_create_intermediate_block)
126120 pc_head
127121 Addr.Set. empty
128- ! blocks );
122+ ! p );
129123 if ! need_to_create_intermediate_block
130124 then (
131- incr free_pc;
132125 let new_params = List. map params ~f: Code.Var. fork in
133126 let body =
134127 (* duplicate the debug event before the loop header. *)
135- match (Addr.Map. find pc_head ! blocks ).body with
128+ match (Code. block pc_head ! p ).body with
136129 | (Event _ as e ) :: _ -> [ e ]
137130 | _ -> []
138131 in
139- blocks :=
140- Addr.Map. add
132+ p :=
133+ Code. add_block
141134 intermediate_pc
142135 { params; body; branch = Branch (pc_head, args) }
143- ! blocks ;
136+ ! p ;
144137 rewrite_body := true ;
145138 Let (f, Closure (new_params, (intermediate_pc, new_params), cloc)))
146139 else i
147140 | i -> i)
148141 in
149- if ! rewrite_body then blocks := Addr.Map. add pc { block with body } ! blocks )
150- (Code. blocks p);
151- let p = Code. program ( Code. start p) ! blocks in
142+ if ! rewrite_body then p := Code. add_block pc { block with body } ! p )
143+ (Code. blocks ! p);
144+ let p = ! p in
152145 if times () then Format. eprintf " tail calls: %a@." Timer. print t;
153146 if stats () then Format. eprintf " Stats - tail calls: %d optimizations@." ! update_count;
154147 if debug_stats ()
0 commit comments