Skip to content

Commit 6365f6b

Browse files
committed
WIP
1 parent 238876e commit 6365f6b

File tree

3 files changed

+86
-38
lines changed

3 files changed

+86
-38
lines changed

compiler/lib-wasm/generate.ml

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -812,7 +812,24 @@ module Generate (Target : Target_sig.S) = struct
812812
| GlobalGet _ -> Value.unit
813813
| _ -> return closure
814814
in
815-
return (W.Call (g, List.rev (cl :: acc)))
815+
let params =
816+
match ctx.global_flow_info.info_defs.(Var.idx g) with
817+
| Expr (Closure (params, _, _)) -> params
818+
| _ -> assert false
819+
in
820+
let* args =
821+
expression_list
822+
Fun.id
823+
(List.map2
824+
~f:(fun a p ->
825+
convert
826+
~from:(get_var_type ctx a)
827+
~into:(get_var_type ctx p)
828+
(load a))
829+
args
830+
params)
831+
in
832+
return (W.Call (g, List.rev (cl :: List.rev args)))
816833
| None -> (
817834
let arity = List.length args in
818835
let funct = Var.fresh () in
@@ -1341,7 +1358,23 @@ module Generate (Target : Target_sig.S) = struct
13411358
; signature =
13421359
(match name_opt with
13431360
| None -> Type.primitive_type param_count
1344-
| Some _ -> Type.func_type (param_count - 1))
1361+
| Some f ->
1362+
if
1363+
Var.Hashtbl.mem
1364+
ctx.fun_info.Call_graph_analysis.unambiguous_non_escaping
1365+
f
1366+
then
1367+
{ W.params =
1368+
List.map
1369+
~f:(fun x : W.value_type ->
1370+
match get_var_type ctx x with
1371+
| Int (Unnormalized | Normalized) -> I32
1372+
| _ -> Type.value)
1373+
params
1374+
@ [ Type.value ]
1375+
; result = [ Type.value ]
1376+
}
1377+
else Type.func_type (param_count - 1))
13451378
; param_names
13461379
; locals
13471380
; body
@@ -1536,9 +1569,11 @@ let init = G.init
15361569
let start () = make_context ~value_type:Gc_target.Type.value
15371570

15381571
let f ~context ~unit_name p ~live_vars ~in_cps ~deadcode_sentinal ~global_flow_data =
1539-
let state, info = global_flow_data in
1540-
let fun_info = Call_graph_analysis.f p info in
1541-
let types = Typing.f ~state ~info ~deadcode_sentinal p in
1572+
let global_flow_state, global_flow_info = global_flow_data in
1573+
let fun_info = Call_graph_analysis.f p global_flow_info in
1574+
let types =
1575+
Typing.f ~global_flow_state ~global_flow_info ~fun_info ~deadcode_sentinal p
1576+
in
15421577
let t = Timer.make () in
15431578
let p = fix_switch_branches p in
15441579
let res =
@@ -1548,7 +1583,7 @@ let f ~context ~unit_name p ~live_vars ~in_cps ~deadcode_sentinal ~global_flow_d
15481583
~live_vars
15491584
~in_cps
15501585
~deadcode_sentinal
1551-
~global_flow_info:info
1586+
~global_flow_info
15521587
~fun_info
15531588
~types
15541589
p

compiler/lib-wasm/typing.ml

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -128,22 +128,27 @@ let update_deps st { blocks; _ } =
128128
| _ -> ()))
129129
blocks
130130

131-
let mark_function_parameters { blocks; _ } =
132-
let function_parameters = Var.Tbl.make () false in
133-
let set x = Var.Tbl.set function_parameters x true in
131+
let mark_function_parameters ~fun_info { blocks; _ } =
132+
let boxed_function_parameters = Var.Tbl.make () false in
133+
let set x = Var.Tbl.set boxed_function_parameters x true in
134134
Addr.Map.iter
135135
(fun _ block ->
136136
List.iter block.body ~f:(fun i ->
137137
match i with
138-
| Let (_, Closure (params, _, _)) -> List.iter ~f:set params
138+
| Let (x, Closure (params, _, _))
139+
when not
140+
(Var.Hashtbl.mem
141+
fun_info.Call_graph_analysis.unambiguous_non_escaping
142+
x) -> List.iter ~f:set params
139143
| _ -> ()))
140144
blocks;
141-
function_parameters
145+
boxed_function_parameters
142146

143147
type st =
144-
{ state : state
145-
; info : info
146-
; function_parameters : bool Var.Tbl.t
148+
{ global_flow_state : state
149+
; global_flow_info : info
150+
; boxed_function_parameters : bool Var.Tbl.t
151+
; fun_info : Call_graph_analysis.t
147152
}
148153

149154
let rec constant_type (c : constant) =
@@ -319,11 +324,11 @@ let prim_type ~approx prim args =
319324
| _ -> Top
320325

321326
let propagate st approx x : Domain.t =
322-
match st.state.defs.(Var.idx x) with
327+
match st.global_flow_state.defs.(Var.idx x) with
323328
| Phi { known; others; unit } ->
324329
let res = Domain.join_set ~others (fun y -> Var.Tbl.get approx y) known in
325330
let res = if unit then Domain.join (Int Unnormalized) res else res in
326-
if Var.Tbl.get st.function_parameters x then Domain.box res else res
331+
if Var.Tbl.get st.boxed_function_parameters x then Domain.box res else res
327332
| Expr e -> (
328333
match e with
329334
| Constant c -> constant_type c
@@ -332,7 +337,7 @@ let propagate st approx x : Domain.t =
332337
Tuple
333338
(Array.mapi
334339
~f:(fun i y ->
335-
match st.state.mutable_fields.(Var.idx x) with
340+
match st.global_flow_state.mutable_fields.(Var.idx x) with
336341
| All_fields -> Top
337342
| Some_fields s when IntSet.mem i s -> Top
338343
| Some_fields _ | No_field ->
@@ -348,15 +353,15 @@ let propagate st approx x : Domain.t =
348353
( Extern ("caml_check_bound" | "caml_check_bound_float" | "caml_check_bound_gen")
349354
, [ Pv y; _ ] ) -> Var.Tbl.get approx y
350355
| Prim ((Array_get | Extern "caml_array_unsafe_get"), [ Pv y; _ ]) -> (
351-
match Var.Tbl.get st.info.info_approximation y with
356+
match Var.Tbl.get st.global_flow_info.info_approximation y with
352357
| Values { known; others } ->
353358
Domain.join_set
354359
~others
355360
(fun z ->
356-
match st.state.defs.(Var.idx z) with
361+
match st.global_flow_state.defs.(Var.idx z) with
357362
| Expr (Block (_, lst, _, _)) ->
358363
let m =
359-
match st.state.mutable_fields.(Var.idx z) with
364+
match st.global_flow_state.mutable_fields.(Var.idx z) with
360365
| No_field -> false
361366
| Some_fields _ | All_fields -> true
362367
in
@@ -377,18 +382,22 @@ let propagate st approx x : Domain.t =
377382
| Prim (Extern prim, args) -> prim_type ~approx prim args
378383
| Special _ -> Top
379384
| Apply { f; args; _ } -> (
380-
match Var.Tbl.get st.info.info_approximation f with
385+
match Var.Tbl.get st.global_flow_info.info_approximation f with
381386
| Values { known; others } ->
382387
Domain.join_set
383388
~others
384389
(fun g ->
385-
match st.state.defs.(Var.idx g) with
390+
match st.global_flow_state.defs.(Var.idx g) with
386391
| Expr (Closure (params, _, _))
387392
when List.length args = List.length params ->
388-
Domain.box
389-
(Domain.join_set
390-
(fun y -> Var.Tbl.get approx y)
391-
(Var.Map.find g st.state.return_values))
393+
let res =
394+
Domain.join_set
395+
(fun y -> Var.Tbl.get approx y)
396+
(Var.Map.find g st.global_flow_state.return_values)
397+
in
398+
if false && Var.Hashtbl.mem st.fun_info.unambiguous_non_escaping g
399+
then res
400+
else Domain.box res
392401
| Expr (Closure (_, _, _)) ->
393402
(* The function is partially applied or over applied *)
394403
Top
@@ -403,33 +412,36 @@ module Solver = G.Solver (Domain)
403412
let solver st =
404413
let associated_list h x = try Var.Hashtbl.find h x with Not_found -> [] in
405414
let g =
406-
{ G.domain = st.state.vars
415+
{ G.domain = st.global_flow_state.vars
407416
; G.iter_children =
408417
(fun f x ->
409-
List.iter ~f (Var.Tbl.get st.state.deps x);
418+
List.iter ~f (Var.Tbl.get st.global_flow_state.deps x);
410419
List.iter
411-
~f:(fun g -> List.iter ~f (associated_list st.state.function_call_sites g))
412-
(associated_list st.state.functions_from_returned_value x))
420+
~f:(fun g ->
421+
List.iter ~f (associated_list st.global_flow_state.function_call_sites g))
422+
(associated_list st.global_flow_state.functions_from_returned_value x))
413423
}
414424
in
415425
Solver.f () g (propagate st)
416426

417-
let f ~state ~info ~deadcode_sentinal p =
418-
update_deps state p;
419-
let function_parameters = mark_function_parameters p in
420-
let typ = solver { state; info; function_parameters } in
427+
let f ~global_flow_state ~global_flow_info ~fun_info ~deadcode_sentinal p =
428+
update_deps global_flow_state p;
429+
let boxed_function_parameters = mark_function_parameters ~fun_info p in
430+
let typ =
431+
solver { global_flow_state; global_flow_info; fun_info; boxed_function_parameters }
432+
in
421433
Var.Tbl.set typ deadcode_sentinal (Int Normalized);
422434
if debug ()
423435
then (
424436
Var.ISet.iter
425437
(fun x ->
426-
match state.defs.(Var.idx x) with
438+
match global_flow_state.defs.(Var.idx x) with
427439
| Expr _ -> ()
428440
| Phi _ ->
429441
let t = Var.Tbl.get typ x in
430442
if not (Domain.equal t Top)
431443
then Format.eprintf "%a: %a@." Var.print x Domain.print t)
432-
state.vars;
444+
global_flow_state.vars;
433445
Print.program
434446
Format.err_formatter
435447
(fun _ i ->

compiler/lib-wasm/typing.mli

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@ type typ =
2121
val constant_type : Code.constant -> typ
2222

2323
val f :
24-
state:Global_flow.state
25-
-> info:Global_flow.info
24+
global_flow_state:Global_flow.state
25+
-> global_flow_info:Global_flow.info
26+
-> fun_info:Call_graph_analysis.t
2627
-> deadcode_sentinal:Code.Var.t
2728
-> Code.program
2829
-> typ Code.Var.Tbl.t

0 commit comments

Comments
 (0)