@@ -46,6 +46,7 @@ let call_graph p info call_info =
4646 let under_handler = Var.Hashtbl. create 16 in
4747 let callees = Var.Hashtbl. create 16 in
4848 let callers = Var.Hashtbl. create 16 in
49+ let has_tail_calls = Var.Hashtbl. create 16 in
4950 let rec traverse name_opt pc visited nesting =
5051 if not (Addr.Set. mem pc visited)
5152 then (
@@ -80,6 +81,25 @@ let call_graph p info call_info =
8081 name_opt)
8182 | Let (_, (Closure _ | Prim _ | Block _ | Constant _ | Field _ | Special _))
8283 | Event _ | Assign _ | Set_field _ | Offset_ref _ | Array_set _ -> () );
84+ if nesting = 0
85+ then
86+ Option. iter
87+ ~f: (fun f ->
88+ Code. traverse
89+ { fold = Code. fold_children }
90+ (fun pc () ->
91+ let block = Addr.Map. find pc p.blocks in
92+ match block.branch with
93+ | Return x -> (
94+ match last_instr block.body with
95+ | Some (Let (x' , Apply _ )) when Code.Var. equal x x' ->
96+ Var.Hashtbl. replace has_tail_calls f ()
97+ | _ -> () )
98+ | _ -> () )
99+ pc
100+ p.blocks
101+ () )
102+ name_opt;
83103 Code. fold_children
84104 p.blocks
85105 pc
@@ -98,7 +118,7 @@ let call_graph p info call_info =
98118 p
99119 (fun name_opt _ (pc , _ ) _ () -> ignore (traverse name_opt pc Addr.Set. empty 0 ))
100120 () ;
101- under_handler, callers, callees
121+ under_handler, callers, callees, has_tail_calls
102122
103123let function_do_raise p pc =
104124 Code. traverse
@@ -127,23 +147,25 @@ let propagate nodes edges eligible =
127147 Var.Hashtbl. iter (fun n () -> propagate n) nodes
128148
129149let raising_functions p info call_info eligible =
130- let under_handler, callers, callees = call_graph p info call_info in
131- propagate under_handler callees eligible;
150+ let under_handler, callers, callees, has_tail_calls = call_graph p info call_info in
151+ propagate under_handler callees (fun f ->
152+ eligible f && not (Var.Hashtbl. mem has_tail_calls f));
132153 let h = Var.Hashtbl. create 16 in
154+ let eligible f =
155+ eligible f
156+ && Var.Hashtbl. mem under_handler f
157+ && not (Var.Hashtbl. mem has_tail_calls f)
158+ in
133159 Code. fold_closures
134160 p
135161 (fun name_opt _params (pc , _ ) _ () ->
136162 match name_opt with
137163 | None -> ()
138164 | Some name ->
139- if
140- direct_calls_only call_info name
141- && eligible name
142- && function_do_raise p pc
143- && Var.Hashtbl. mem under_handler name
165+ if direct_calls_only call_info name && eligible name && function_do_raise p pc
144166 then Var.Hashtbl. add h name () )
145167 () ;
146- propagate h callers ( fun f -> eligible f && Var.Hashtbl. mem under_handler f) ;
168+ propagate h callers eligible;
147169 if false
148170 then
149171 Var.Hashtbl. iter
@@ -180,5 +202,4 @@ let f p info =
180202
181203(*
182204- Optimize tail-calls
183- - Cannot change calling convention if the function has tail-calls
184205*)
0 commit comments