Skip to content

Commit 04494e1

Browse files
committed
Generic functions for unboxed types (oxcaml#1104)
1 parent 23c793d commit 04494e1

File tree

9 files changed

+383
-251
lines changed

9 files changed

+383
-251
lines changed

backend/cmm_helpers.ml

Lines changed: 294 additions & 211 deletions
Large diffs are not rendered by default.

backend/cmm_helpers.mli

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,8 @@ val call_cached_method :
369369
expression ->
370370
expression ->
371371
expression list ->
372+
machtype list ->
373+
machtype ->
372374
Clambda.apply_kind ->
373375
Debuginfo.t ->
374376
expression
@@ -408,11 +410,13 @@ val opaque : expression -> Debuginfo.t -> expression
408410

409411
(** Get the symbol for the generic application with [n] arguments, and ensure
410412
its presence in the set of defined symbols *)
411-
val apply_function_sym : int -> Lambda.alloc_mode -> string
413+
val apply_function_sym :
414+
machtype list -> machtype -> Lambda.alloc_mode -> string
412415

413416
(** Get the symbol for the generic currying or tuplifying wrapper with [n]
414417
arguments, and ensure its presence in the set of defined symbols. *)
415-
val curry_function_sym : Clambda.arity -> string
418+
val curry_function_sym :
419+
Lambda.function_kind -> machtype list -> machtype -> string
416420

417421
(** Bigarrays *)
418422

@@ -755,6 +759,8 @@ val generic_apply :
755759
Asttypes.mutable_flag ->
756760
expression ->
757761
expression list ->
762+
machtype list ->
763+
machtype ->
758764
Clambda.apply_kind ->
759765
Debuginfo.t ->
760766
expression
@@ -774,6 +780,8 @@ val send :
774780
expression ->
775781
expression ->
776782
expression list ->
783+
machtype list ->
784+
machtype ->
777785
Clambda.apply_kind ->
778786
Debuginfo.t ->
779787
expression
@@ -1107,6 +1115,7 @@ val indirect_call :
11071115
Lambda.region_close ->
11081116
Lambda.alloc_mode ->
11091117
expression ->
1118+
machtype list ->
11101119
expression list ->
11111120
expression
11121121

@@ -1118,6 +1127,7 @@ val indirect_full_call :
11181127
Lambda.region_close ->
11191128
Lambda.alloc_mode ->
11201129
expression ->
1130+
machtype list ->
11211131
expression list ->
11221132
expression
11231133

@@ -1197,3 +1207,5 @@ val transl_attrib : Lambda.check_attribute -> Cmm.codegen_option list
11971207
val make_symbol : ?compilation_unit:Compilation_unit.t -> string -> string
11981208

11991209
val kind_of_layout : Lambda.layout -> value_kind
1210+
1211+
val machtype_of_layout : Lambda.layout -> machtype

backend/cmmgen.ml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ let rec transl env e =
465465
~startenv:(startenv - pos) ~is_last dbg ::
466466
transl_fundecls (pos + 3) rem
467467
| arity ->
468-
Cconst_symbol (curry_function_sym arity, dbg) ::
468+
Cconst_symbol (curry_function_sym (fst arity) (List.init (snd arity) (fun _ -> typ_val)) typ_val, dbg) ::
469469
alloc_closure_info ~arity
470470
~startenv:(startenv - pos) ~is_last dbg ::
471471
Cconst_symbol (f.label, dbg) ::
@@ -496,12 +496,16 @@ let rec transl env e =
496496
| Ugeneric_apply(clos, args, kind, dbg) ->
497497
let clos = transl env clos in
498498
let args = List.map (transl env) args in
499-
generic_apply (mut_from_env env clos) clos args kind dbg
499+
let args_type = List.map (fun _ -> typ_val) args in
500+
let return = typ_val in
501+
generic_apply (mut_from_env env clos) clos args args_type return kind dbg
500502
| Usend(kind, met, obj, args, pos, dbg) ->
501503
let met = transl env met in
502504
let obj = transl env obj in
503505
let args = List.map (transl env) args in
504-
send kind met obj args pos dbg
506+
let args_type = List.map (fun _ -> typ_val) args in
507+
let return = typ_val in
508+
send kind met obj args args_type return pos dbg
505509
| Ulet(str, kind, id, exp, body) ->
506510
transl_let env str kind id exp (fun env -> transl env body)
507511
| Uphantom_let (var, defining_expr, body) ->

file_formats/cmx_format.mli

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,11 @@ type export_info_raw =
4141
| Flambda1_raw of Export_info.t
4242
| Flambda2_raw of Flambda2_cmx.Flambda_cmx_format.raw option
4343

44-
type apply_fn := int * Lambda.alloc_mode
44+
type apply_fn := Cmm.machtype list * Cmm.machtype * Lambda.alloc_mode
4545

4646
(* Curry/apply/send functions *)
4747
type generic_fns =
48-
{ curry_fun: Clambda.arity list;
48+
{ curry_fun: (Lambda.function_kind * Cmm.machtype list * Cmm.machtype) list;
4949
apply_fun: apply_fn list;
5050
send_fun: apply_fn list }
5151

middle_end/compilenv.ml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -323,24 +323,24 @@ let approx_env () = !merged_environment
323323

324324
(* Record that a currying function or application function is needed *)
325325

326-
let need_curry_fun arity =
326+
let need_curry_fun kind arity result =
327327
let fns = current_unit.ui_generic_fns in
328-
if not (List.mem arity fns.curry_fun) then
328+
if not (List.mem (kind, arity, result) fns.curry_fun) then
329329
current_unit.ui_generic_fns <-
330-
{ fns with curry_fun = arity :: fns.curry_fun }
330+
{ fns with curry_fun = (kind, arity, result) :: fns.curry_fun }
331331

332-
let need_apply_fun n mode =
333-
assert(n > 0);
332+
let need_apply_fun arity result mode =
333+
assert(List.compare_length_with arity 0 > 0);
334334
let fns = current_unit.ui_generic_fns in
335-
if not (List.mem (n,mode) fns.apply_fun) then
335+
if not (List.mem (arity, result, mode) fns.apply_fun) then
336336
current_unit.ui_generic_fns <-
337-
{ fns with apply_fun = (n,mode) :: fns.apply_fun }
337+
{ fns with apply_fun = (arity, result, mode) :: fns.apply_fun }
338338

339-
let need_send_fun n mode =
339+
let need_send_fun arity result mode =
340340
let fns = current_unit.ui_generic_fns in
341-
if not (List.mem (n,mode) fns.send_fun) then
341+
if not (List.mem (arity, result, mode) fns.send_fun) then
342342
current_unit.ui_generic_fns <-
343-
{ fns with send_fun = (n,mode) :: fns.send_fun }
343+
{ fns with send_fun = (arity, result, mode) :: fns.send_fun }
344344

345345
(* Write the description of the current unit *)
346346

middle_end/compilenv.mli

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,9 @@ val get_unit_export_info
6868
val flambda2_set_export_info : Flambda2_cmx.Flambda_cmx_format.t -> unit
6969
(* Set the export information for the current unit (Flambda 2 only). *)
7070

71-
val need_curry_fun: Clambda.arity -> unit
72-
val need_apply_fun: int -> Lambda.alloc_mode -> unit
73-
val need_send_fun: int -> Lambda.alloc_mode -> unit
71+
val need_curry_fun: Lambda.function_kind -> Cmm.machtype list -> Cmm.machtype -> unit
72+
val need_apply_fun: Cmm.machtype list -> Cmm.machtype -> Lambda.alloc_mode -> unit
73+
val need_send_fun: Cmm.machtype list -> Cmm.machtype -> Lambda.alloc_mode -> unit
7474
(* Record the need of a currying (resp. application,
7575
message sending) function with the given arity *)
7676

middle_end/flambda2/to_cmm/to_cmm_expr.ml

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,10 @@ let translate_apply0 env res apply =
108108
Ece.all ))
109109
| Function { function_call = Indirect_unknown_arity; alloc_mode } ->
110110
fail_if_probe apply;
111-
( C.indirect_call ~dbg Cmm.typ_val pos
111+
let args_ty, ty = Cmm.(List.map (fun _ -> [| Val |]) args, [| Val |]) in
112+
( C.indirect_call ~dbg ty pos
112113
(Alloc_mode.For_types.to_lambda alloc_mode)
113-
callee args,
114+
callee args_ty args,
114115
env,
115116
res,
116117
Ece.all )
@@ -129,9 +130,14 @@ let translate_apply0 env res apply =
129130
return_arity |> Flambda_arity.With_subkinds.to_arity
130131
|> C.machtype_of_return_arity
131132
in
133+
let args_ty =
134+
List.map
135+
(fun k -> C.machtype_of_kind (Flambda_kind.With_subkind.kind k))
136+
(Flambda_arity.With_subkinds.to_list param_arity)
137+
in
132138
( C.indirect_full_call ~dbg ty pos
133139
(Alloc_mode.For_types.to_lambda alloc_mode)
134-
callee args,
140+
callee args_ty args,
135141
env,
136142
res,
137143
Ece.all )
@@ -175,10 +181,14 @@ let translate_apply0 env res apply =
175181
Ece.all )
176182
| Call_kind.Method { kind; obj; alloc_mode } ->
177183
fail_if_probe apply;
184+
let args_ty, ty = Cmm.(List.map (fun _ -> [| Val |]) args, [| Val |]) in
178185
let obj, env, res, _ = C.simple ~dbg env res obj in
179186
let kind = Call_kind.Method_kind.to_lambda kind in
180187
let alloc_mode = Alloc_mode.For_types.to_lambda alloc_mode in
181-
C.send kind callee obj args (pos, alloc_mode) dbg, env, res, Ece.all
188+
( C.send kind callee obj args args_ty ty (pos, alloc_mode) dbg,
189+
env,
190+
res,
191+
Ece.all )
182192

183193
(* Function calls that have an exn continuation with extra arguments must be
184194
wrapped with assignments for the mutable variables used to pass the extra

middle_end/flambda2/to_cmm/to_cmm_set_of_closures.ml

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,14 @@ type closure_code_pointers =
3434

3535
let get_func_decl_params_arity t code_id =
3636
let info = Env.get_code_metadata t code_id in
37-
let num_params =
38-
Flambda_arity.With_subkinds.cardinal (Code_metadata.params_arity info)
37+
let params_ty =
38+
List.map
39+
(fun k -> C.machtype_of_kind (Flambda_kind.With_subkind.kind k))
40+
(Flambda_arity.With_subkinds.to_list (Code_metadata.params_arity info))
41+
in
42+
let result_ty =
43+
C.machtype_of_return_arity
44+
(Flambda_arity.With_subkinds.to_arity (Code_metadata.result_arity info))
3945
in
4046
let kind : Lambda.function_kind =
4147
if Code_metadata.is_tupled info
@@ -44,11 +50,11 @@ let get_func_decl_params_arity t code_id =
4450
Lambda.Curried { nlocal = Code_metadata.num_trailing_local_params info }
4551
in
4652
let closure_code_pointers =
47-
match kind, num_params with
48-
| Curried _, (0 | 1) -> Full_application_only
53+
match kind, params_ty with
54+
| Curried _, ([] | [_]) -> Full_application_only
4955
| (Curried _ | Tupled), _ -> Full_and_partial_application
5056
in
51-
let arity = kind, num_params in
57+
let arity = kind, params_ty, result_ty in
5258
arity, closure_code_pointers, Code_metadata.dbg info
5359

5460
type for_static_sets =
@@ -147,11 +153,11 @@ end = struct
147153
| Function_slot { size; function_slot; last_function_slot } -> (
148154
let code_id = Function_slot.Map.find function_slot decls in
149155
let code_linkage_name = Code_id.linkage_name code_id in
150-
let arity, closure_code_pointers, dbg =
156+
let (kind, params_ty, result_ty), closure_code_pointers, dbg =
151157
get_func_decl_params_arity env code_id
152158
in
153159
let closure_info =
154-
C.closure_info ~arity ~startenv:(startenv - slot_offset)
160+
C.closure_info ~arity:(kind, List.length params_ty) ~startenv:(startenv - slot_offset)
155161
~is_last:last_function_slot
156162
in
157163
let acc =
@@ -194,7 +200,8 @@ end = struct
194200
P.symbol_from_linkage_name ~dbg code_linkage_name
195201
:: P.int ~dbg closure_info
196202
:: P.symbol_from_linkage_name ~dbg
197-
(Linkage_name.of_string (C.curry_function_sym arity))
203+
(Linkage_name.of_string
204+
(C.curry_function_sym kind params_ty result_ty))
198205
:: acc
199206
in
200207
acc, slot_offset + size, env, res, Ece.pure, updates)

tools/flambda_backend_objinfo.ml

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -154,18 +154,34 @@ let print_global_table table =
154154
open Cmx_format
155155
open Cmxs_format
156156

157+
let machtype_identifier t =
158+
let open Cmm in
159+
let char_of_component = function
160+
| Val -> 'V' | Int -> 'I' | Float -> 'F' | Addr -> 'A'
161+
in
162+
String.of_seq (Seq.map char_of_component (Array.to_seq t))
163+
164+
let unique_arity_identifier arity =
165+
let open Cmm in
166+
if List.for_all (function [|Val|] -> true | _ -> false) arity then
167+
Int.to_string (List.length arity)
168+
else
169+
String.concat "_" (List.map machtype_identifier arity)
170+
171+
let return_arity_identifier t =
172+
let open Cmm in
173+
match t with [|Val|] -> "" | _ -> "_R" ^ machtype_identifier t
174+
157175
let print_generic_fns gfns =
158176
let pr_afuns _ fns =
159177
let mode = function Lambda.Alloc_heap -> "" | Lambda.Alloc_local -> "L" in
160-
List.iter (fun (arity, m) -> printf " %d%s" arity (mode m)) fns
161-
in
178+
List.iter (fun (arity,result,m) -> printf " %s%s%s" (unique_arity_identifier arity) (return_arity_identifier result) (mode m)) fns in
162179
let pr_cfuns _ fns =
163-
List.iter
164-
(function
165-
| Lambda.Curried { nlocal }, a -> printf " %dL%d" a nlocal
166-
| Lambda.Tupled, a -> printf " -%d" a)
167-
fns
168-
in
180+
List.iter (function
181+
| (Lambda.Curried {nlocal}, arity, result) ->
182+
printf " %s%sL%d" (unique_arity_identifier arity) (return_arity_identifier result) nlocal
183+
| (Lambda.Tupled, arity, result) ->
184+
printf " -%s%s" (unique_arity_identifier arity) (return_arity_identifier result)) fns in
169185
printf "Currying functions:%a\n" pr_cfuns gfns.curry_fun;
170186
printf "Apply functions:%a\n" pr_afuns gfns.apply_fun;
171187
printf "Send functions:%a\n" pr_afuns gfns.send_fun

0 commit comments

Comments
 (0)