Skip to content

Commit bc7d9e9

Browse files
committed
When a function is only called directy, pass its integer parameters as i32.
1 parent e189da8 commit bc7d9e9

File tree

5 files changed

+89
-43
lines changed

5 files changed

+89
-43
lines changed

compiler/lib-wasm/generate.ml

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -788,13 +788,12 @@ module Generate (Target : Target_sig.S) = struct
788788
match e with
789789
| Apply { f; args; exact; _ } ->
790790
let* closure = load f in
791-
let* args = expression_list (fun x -> load_and_box ctx x) args in
792791
if exact || List.length args = if Var.Set.mem x ctx.in_cps then 2 else 1
793792
then
794793
match
795794
if exact then Global_flow.get_unique_closure ctx.global_flow_info f else None
796795
with
797-
| Some g ->
796+
| Some (g, params) ->
798797
let* cl =
799798
(* Functions with constant closures ignore their environment. *)
800799
match closure with
@@ -803,6 +802,18 @@ module Generate (Target : Target_sig.S) = struct
803802
if Option.is_some init then Value.unit else return closure
804803
| _ -> return closure
805804
in
805+
let* args =
806+
expression_list
807+
Fun.id
808+
(List.map2
809+
~f:(fun a p ->
810+
convert
811+
~from:(get_var_type ctx a)
812+
~into:(get_var_type ctx p)
813+
(load a))
814+
args
815+
params)
816+
in
806817
return (W.Call (g, args @ [ cl ]))
807818
| None -> (
808819
let funct = Var.fresh () in
@@ -813,13 +824,15 @@ module Generate (Target : Target_sig.S) = struct
813824
~arity:(List.length args)
814825
(load funct)
815826
in
827+
let* args = expression_list (fun x -> load_and_box ctx x) args in
816828
match funct with
817829
| W.RefFunc g -> return (W.Call (g, args @ [ closure ]))
818830
| _ -> return (W.Call_ref (ty, funct, args @ [ closure ])))
819831
else
820832
let* apply =
821833
need_apply_fun ~cps:(Var.Set.mem x ctx.in_cps) ~arity:(List.length args)
822834
in
835+
let* args = expression_list (fun x -> load_and_box ctx x) args in
823836
return (W.Call (apply, args @ [ closure ]))
824837
| Block (tag, a, _, _) ->
825838
Memory.allocate
@@ -1249,7 +1262,14 @@ module Generate (Target : Target_sig.S) = struct
12491262
List.fold_left
12501263
~f:(fun l x ->
12511264
let* _ = l in
1252-
let* _ = add_var x in
1265+
let* _ =
1266+
add_var
1267+
?typ:
1268+
(match get_var_type ctx x with
1269+
| Typing.Int (Normalized | Unnormalized) -> Some I32
1270+
| _ -> None)
1271+
x
1272+
in
12531273
return ())
12541274
~init:(return ())
12551275
params
@@ -1318,7 +1338,20 @@ module Generate (Target : Target_sig.S) = struct
13181338
; signature =
13191339
(match name_opt with
13201340
| None -> Type.primitive_type param_count
1321-
| Some _ -> Type.func_type (param_count - 1))
1341+
| Some f ->
1342+
if Call_graph_analysis.direct_calls_only ctx.fun_info f
1343+
then
1344+
{ W.params =
1345+
List.map
1346+
~f:(fun x : W.value_type ->
1347+
match get_var_type ctx x with
1348+
| Int (Unnormalized | Normalized) -> I32
1349+
| _ -> Type.value)
1350+
params
1351+
@ [ Type.value ]
1352+
; result = [ Type.value ]
1353+
}
1354+
else Type.func_type (param_count - 1))
13221355
; param_names
13231356
; locals
13241357
; body
@@ -1513,9 +1546,11 @@ let init = G.init
15131546
let start () = make_context ~value_type:Gc_target.Type.value
15141547

15151548
let f ~context ~unit_name p ~live_vars ~in_cps ~deadcode_sentinal ~global_flow_data =
1516-
let state, info = global_flow_data in
1517-
let fun_info = Call_graph_analysis.f p info in
1518-
let types = Typing.f ~state ~info ~deadcode_sentinal p in
1549+
let global_flow_state, global_flow_info = global_flow_data in
1550+
let fun_info = Call_graph_analysis.f p global_flow_info in
1551+
let types =
1552+
Typing.f ~global_flow_state ~global_flow_info ~fun_info ~deadcode_sentinal p
1553+
in
15191554
let t = Timer.make () in
15201555
let p = fix_switch_branches p in
15211556
let res =
@@ -1525,7 +1560,7 @@ let f ~context ~unit_name p ~live_vars ~in_cps ~deadcode_sentinal ~global_flow_d
15251560
~live_vars
15261561
~in_cps
15271562
~deadcode_sentinal
1528-
~global_flow_info:info
1563+
~global_flow_info
15291564
~fun_info
15301565
~types
15311566
p

compiler/lib-wasm/typing.ml

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -128,22 +128,25 @@ 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 (Call_graph_analysis.direct_calls_only fun_info x) ->
140+
List.iter ~f:set params
139141
| _ -> ()))
140142
blocks;
141-
function_parameters
143+
boxed_function_parameters
142144

143145
type st =
144-
{ state : state
145-
; info : info
146-
; function_parameters : bool Var.Tbl.t
146+
{ global_flow_state : state
147+
; global_flow_info : info
148+
; boxed_function_parameters : bool Var.Tbl.t
149+
; fun_info : Call_graph_analysis.t
147150
}
148151

149152
let rec constant_type (c : constant) =
@@ -319,11 +322,11 @@ let prim_type ~approx prim args =
319322
| _ -> Top
320323

321324
let propagate st approx x : Domain.t =
322-
match st.state.defs.(Var.idx x) with
325+
match st.global_flow_state.defs.(Var.idx x) with
323326
| Phi { known; others; unit } ->
324327
let res = Domain.join_set ~others (fun y -> Var.Tbl.get approx y) known in
325328
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
329+
if Var.Tbl.get st.boxed_function_parameters x then Domain.box res else res
327330
| Expr e -> (
328331
match e with
329332
| Constant c -> constant_type c
@@ -332,7 +335,7 @@ let propagate st approx x : Domain.t =
332335
Tuple
333336
(Array.mapi
334337
~f:(fun i y ->
335-
match st.state.mutable_fields.(Var.idx x) with
338+
match st.global_flow_state.mutable_fields.(Var.idx x) with
336339
| All_fields -> Top
337340
| Some_fields s when IntSet.mem i s -> Top
338341
| Some_fields _ | No_field ->
@@ -348,15 +351,15 @@ let propagate st approx x : Domain.t =
348351
( Extern ("caml_check_bound" | "caml_check_bound_float" | "caml_check_bound_gen")
349352
, [ Pv y; _ ] ) -> Var.Tbl.get approx y
350353
| Prim ((Array_get | Extern "caml_array_unsafe_get"), [ Pv y; _ ]) -> (
351-
match Var.Tbl.get st.info.info_approximation y with
354+
match Var.Tbl.get st.global_flow_info.info_approximation y with
352355
| Values { known; others } ->
353356
Domain.join_set
354357
~others
355358
(fun z ->
356-
match st.state.defs.(Var.idx z) with
359+
match st.global_flow_state.defs.(Var.idx z) with
357360
| Expr (Block (_, lst, _, _)) ->
358361
let m =
359-
match st.state.mutable_fields.(Var.idx z) with
362+
match st.global_flow_state.mutable_fields.(Var.idx z) with
360363
| No_field -> false
361364
| Some_fields _ | All_fields -> true
362365
in
@@ -377,18 +380,22 @@ let propagate st approx x : Domain.t =
377380
| Prim (Extern prim, args) -> prim_type ~approx prim args
378381
| Special _ -> Top
379382
| Apply { f; args; _ } -> (
380-
match Var.Tbl.get st.info.info_approximation f with
383+
match Var.Tbl.get st.global_flow_info.info_approximation f with
381384
| Values { known; others } ->
382385
Domain.join_set
383386
~others
384387
(fun g ->
385-
match st.state.defs.(Var.idx g) with
388+
match st.global_flow_state.defs.(Var.idx g) with
386389
| Expr (Closure (params, _, _))
387390
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))
391+
let res =
392+
Domain.join_set
393+
(fun y -> Var.Tbl.get approx y)
394+
(Var.Map.find g st.global_flow_state.return_values)
395+
in
396+
if false && Call_graph_analysis.direct_calls_only st.fun_info g
397+
then res
398+
else Domain.box res
392399
| Expr (Closure (_, _, _)) ->
393400
(* The function is partially applied or over applied *)
394401
Top
@@ -403,33 +410,36 @@ module Solver = G.Solver (Domain)
403410
let solver st =
404411
let associated_list h x = try Var.Hashtbl.find h x with Not_found -> [] in
405412
let g =
406-
{ G.domain = st.state.vars
413+
{ G.domain = st.global_flow_state.vars
407414
; G.iter_children =
408415
(fun f x ->
409-
List.iter ~f (Var.Tbl.get st.state.deps x);
416+
List.iter ~f (Var.Tbl.get st.global_flow_state.deps x);
410417
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))
418+
~f:(fun g ->
419+
List.iter ~f (associated_list st.global_flow_state.function_call_sites g))
420+
(associated_list st.global_flow_state.functions_from_returned_value x))
413421
}
414422
in
415423
Solver.f () g (propagate st)
416424

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
425+
let f ~global_flow_state ~global_flow_info ~fun_info ~deadcode_sentinal p =
426+
update_deps global_flow_state p;
427+
let boxed_function_parameters = mark_function_parameters ~fun_info p in
428+
let typ =
429+
solver { global_flow_state; global_flow_info; fun_info; boxed_function_parameters }
430+
in
421431
Var.Tbl.set typ deadcode_sentinal (Int Normalized);
422432
if debug ()
423433
then (
424434
Var.ISet.iter
425435
(fun x ->
426-
match state.defs.(Var.idx x) with
436+
match global_flow_state.defs.(Var.idx x) with
427437
| Expr _ -> ()
428438
| Phi _ ->
429439
let t = Var.Tbl.get typ x in
430440
if not (Domain.equal t Top)
431441
then Format.eprintf "%a: %a@." Var.print x Domain.print t)
432-
state.vars;
442+
global_flow_state.vars;
433443
Print.program
434444
Format.err_formatter
435445
(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

compiler/lib/global_flow.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -791,9 +791,9 @@ let get_unique_closure info f =
791791
Var.Set.fold
792792
(fun g acc ->
793793
match info.info_defs.(Var.idx g) with
794-
| Expr (Closure _) -> (
794+
| Expr (Closure (params, _, _)) -> (
795795
match acc with
796-
| None -> Some (Some g)
796+
| None -> Some (Some (g, params))
797797
| Some (Some _) -> Some None
798798
| Some None -> acc)
799799
| Expr (Block _) -> acc

compiler/lib/global_flow.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,6 @@ val update_def : info -> Code.Var.t -> Code.expr -> unit
8484

8585
val exact_call : info -> Var.t -> int -> bool
8686

87-
val get_unique_closure : info -> Var.t -> Var.t option
87+
val get_unique_closure : info -> Var.t -> (Var.t * Var.t list) option
8888

8989
val function_arity : info -> Var.t -> int option

0 commit comments

Comments
 (0)