Skip to content

Commit ea924f1

Browse files
committed
More precise environment type
Casting to the exact type should be slightly faster since we avoid the test for i31.
1 parent aa6b65e commit ea924f1

File tree

8 files changed

+135
-72
lines changed

8 files changed

+135
-72
lines changed

compiler/lib-wasm/code_generation.ml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,31 @@ let tee ?typ x e =
503503

504504
let should_make_global x st = Var.Set.mem x st.context.globalized_variables, st
505505

506+
let get_constant x st = Var.Hashtbl.find_opt st.context.constants x, st
507+
508+
let placeholder_value typ f =
509+
let* c = get_constant typ in
510+
match c with
511+
| None ->
512+
let x = Var.fresh () in
513+
let* () = register_constant typ (W.GlobalGet x) in
514+
let* () =
515+
register_global
516+
~constant:true
517+
x
518+
{ mut = false; typ = Ref { nullable = false; typ = Type typ } }
519+
(f typ)
520+
in
521+
return (W.GlobalGet x)
522+
| Some c -> return c
523+
524+
let empty_struct =
525+
let* typ =
526+
register_type "empty_struct" (fun () ->
527+
return { supertype = None; final = true; typ = W.Struct [] })
528+
in
529+
placeholder_value typ (fun typ -> W.StructNew (typ, []))
530+
506531
let value_type st = st.context.value_type, st
507532

508533
let get_constant x st = Var.Hashtbl.find_opt st.context.constants x, st

compiler/lib-wasm/code_generation.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,3 +205,5 @@ val array_placeholder : Code.Var.t -> expression
205205
val default_value :
206206
Wasm_ast.value_type
207207
-> (Wasm_ast.expression * Wasm_ast.value_type * Wasm_ast.ref_type option) t
208+
209+
val empty_struct : expression

compiler/lib-wasm/curry.ml

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,12 @@ module Make (Target : Target_sig.S) = struct
3535

3636
let call ?typ ~cps ~arity closure args =
3737
let funct = Var.fresh () in
38-
let* closure = tee ?typ funct closure in
38+
let closure = tee ?typ funct closure in
39+
let* closure =
40+
match typ with
41+
| None -> Memory.cast_closure ~cps ~arity closure
42+
| Some _ -> closure
43+
in
3944
let args = args @ [ closure ] in
4045
let* ty, funct =
4146
Memory.load_function_pointer
@@ -68,7 +73,7 @@ module Make (Target : Target_sig.S) = struct
6873
let body =
6974
let* () = no_event in
7075
let* () = bind_parameters args in
71-
let* _ = add_var f in
76+
let* _ = add_var ~typ:Type.closure f in
7277
let* args' = expression_list load args in
7378
let* _f = load f in
7479
let rec loop m args closure closure_typ =
@@ -126,7 +131,7 @@ module Make (Target : Target_sig.S) = struct
126131
let body =
127132
let* () = no_event in
128133
let* _ = add_var x in
129-
let* _ = add_var f in
134+
let* _ = add_var ~typ:Type.closure f in
130135
push (Closure.curry_allocate ~cps:false ~arity m ~f:name' ~closure:f ~arg:x)
131136
in
132137
let param_names = [ x; f ] in
@@ -154,7 +159,7 @@ module Make (Target : Target_sig.S) = struct
154159
let body =
155160
let* () = no_event in
156161
let* () = bind_parameters args in
157-
let* _ = add_var f in
162+
let* _ = add_var ~typ:Type.closure f in
158163
let* args' = expression_list load args in
159164
let* _f = load f in
160165
let rec loop m args closure closure_typ =
@@ -214,7 +219,7 @@ module Make (Target : Target_sig.S) = struct
214219
let* () = no_event in
215220
let* _ = add_var x in
216221
let* _ = add_var cont in
217-
let* _ = add_var f in
222+
let* _ = add_var ~typ:Type.closure f in
218223
let* e = Closure.curry_allocate ~cps:true ~arity m ~f:name' ~closure:f ~arg:x in
219224
let* c = call ~cps:false ~arity:1 (load cont) [ e ] in
220225
instr (W.Return (Some c))
@@ -333,7 +338,7 @@ module Make (Target : Target_sig.S) = struct
333338
let body =
334339
let* () = no_event in
335340
let* () = bind_parameters l in
336-
let* _ = add_var f in
341+
let* _ = add_var ~typ:Type.closure f in
337342
let* typ, closure = Memory.load_real_closure ~cps ~arity (load f) in
338343
let* l = expression_list load l in
339344
let* e =

compiler/lib-wasm/gc_target.ml

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ let include_closure_arity = false
2727
module Type = struct
2828
let value = W.Ref { nullable = false; typ = Eq }
2929

30+
let closure = W.Ref { nullable = false; typ = Struct }
31+
3032
let block_type =
3133
register_type "block" (fun () ->
3234
return
@@ -205,7 +207,8 @@ module Type = struct
205207
let primitive_type n =
206208
{ W.params = List.init ~len:n ~f:(fun _ -> value); result = [ value ] }
207209

208-
let func_type n = primitive_type (n + 1)
210+
let func_type n =
211+
{ W.params = List.init ~len:n ~f:(fun _ -> value) @ [ closure ]; result = [ value ] }
209212

210213
let function_type ~cps n =
211214
let n = if cps then n + 1 else n in
@@ -430,6 +433,8 @@ module Value = struct
430433
let* t = Type.block_type in
431434
array_placeholder t
432435

436+
let dummy_closure = empty_struct
437+
433438
let as_block e =
434439
let* t = Type.block_type in
435440
let* e = e in
@@ -811,6 +816,11 @@ module Memory = struct
811816
then 1
812817
else (if include_closure_arity then 1 else 0) + if arity = 1 then 1 else 2
813818

819+
let cast_closure ~cps ~arity closure =
820+
let arity = if cps then arity - 1 else arity in
821+
let* ty = Type.closure_type ~usage:`Access ~cps arity in
822+
wasm_cast ty closure
823+
814824
let load_function_pointer ~cps ~arity ?(skip_cast = false) closure =
815825
let arity = if cps then arity - 1 else arity in
816826
let* ty = Type.closure_type ~usage:`Access ~cps arity in
@@ -1189,7 +1199,7 @@ module Closure = struct
11891199
if free_variable_count = 0
11901200
then
11911201
(* The closures are all constants and the environment is empty. *)
1192-
let* _ = add_var (Code.Var.fresh ()) in
1202+
let* _ = add_var ~typ:Type.closure (Code.Var.fresh ()) in
11931203
return ()
11941204
else
11951205
let env_type_id = Option.value ~default:(-1) info.id in
@@ -1199,7 +1209,7 @@ module Closure = struct
11991209
match info.Closure_conversion.functions with
12001210
| [ _ ] ->
12011211
let* typ = Type.env_type ~cps ~arity ~env_type_id ~env_type:[] in
1202-
let* _ = add_var f in
1212+
let* _ = add_var ~typ:Type.closure f in
12031213
let env = Code.Var.fresh_n "env" in
12041214
let* () =
12051215
store
@@ -1220,7 +1230,7 @@ module Closure = struct
12201230
let* typ =
12211231
Type.rec_closure_type ~cps ~arity ~function_count ~env_type_id ~env_type:[]
12221232
in
1223-
let* _ = add_var f in
1233+
let* _ = add_var ~typ:Type.closure f in
12241234
let env = Code.Var.fresh_n "env" in
12251235
let* env_typ = Type.rec_env_type ~function_count ~env_type_id ~env_type:[] in
12261236
let* () =

compiler/lib-wasm/generate.ml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -793,7 +793,12 @@ module Generate (Target : Target_sig.S) = struct
793793
| [] -> (
794794
let arity = List.length args in
795795
let funct = Var.fresh () in
796-
let* closure = tee funct (load f) in
796+
let* closure =
797+
Memory.cast_closure
798+
~cps:(Var.Set.mem x ctx.in_cps)
799+
~arity
800+
(tee funct (load f))
801+
in
797802
let* ty, funct =
798803
Memory.load_function_pointer
799804
~cps:(Var.Set.mem x ctx.in_cps)
@@ -809,7 +814,7 @@ module Generate (Target : Target_sig.S) = struct
809814
(* Functions with constant closures ignore their
810815
environment. In case of partial application, we
811816
still need the closure. *)
812-
let* cl = if exact then Value.unit else return closure in
817+
let* cl = if exact then Value.dummy_closure else return closure in
813818
return (W.Call (g, List.rev (cl :: acc)))
814819
| _ -> (
815820
match

compiler/lib-wasm/target_sig.ml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ module type S = sig
2727
-> [ `Expr of Wasm_ast.expression | `Var of Wasm_ast.var ] list
2828
-> expression
2929

30+
val cast_closure : cps:bool -> arity:int -> expression -> expression
31+
3032
val load_function_pointer :
3133
cps:bool
3234
-> arity:int
@@ -100,6 +102,8 @@ module type S = sig
100102
module Type : sig
101103
val value : Wasm_ast.value_type
102104

105+
val closure : Wasm_ast.value_type
106+
103107
val func_type : int -> Wasm_ast.func_type
104108

105109
val primitive_type : int -> Wasm_ast.func_type
@@ -162,6 +166,8 @@ module type S = sig
162166

163167
val dummy_block : expression
164168

169+
val dummy_closure : expression
170+
165171
val as_block : expression -> expression
166172
end
167173

0 commit comments

Comments
 (0)