Skip to content

Commit fe7ccc9

Browse files
committed
No tail-calls
1 parent 654c522 commit fe7ccc9

File tree

1 file changed

+31
-10
lines changed

1 file changed

+31
-10
lines changed

compiler/lib-wasm/call_graph_analysis.ml

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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

103123
let 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

129149
let 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

Comments
 (0)