Skip to content

Commit 1645e1c

Browse files
committed
Generic functions for unboxed types
1 parent 23c793d commit 1645e1c

15 files changed

+475
-312
lines changed

backend/cmm_helpers.ml

+309-218
Large diffs are not rendered by default.

backend/cmm_helpers.mli

+15-3
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ val boxedintnat_header : nativeint
6161

6262
(** Closure info for a closure of given arity and distance to environment *)
6363
val closure_info :
64-
arity:Clambda.arity -> startenv:int -> is_last:bool -> nativeint
64+
arity:Lambda.function_kind * int -> startenv:int -> is_last:bool -> nativeint
6565

6666
(** Wrappers *)
6767
val alloc_infix_header : int -> Debuginfo.t -> expression
@@ -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

+17-7
Original file line numberDiff line numberDiff line change
@@ -459,14 +459,14 @@ let rec transl env e =
459459
let dbg = f.dbg in
460460
let without_header =
461461
match f.arity with
462-
| Curried _, (1|0) as arity ->
462+
| { function_kind = Curried _ ; params_layout = ([] | [_]) } as arity ->
463463
Cconst_symbol (f.label, dbg) ::
464-
alloc_closure_info ~arity
464+
alloc_closure_info ~arity:(arity.function_kind, List.length arity.params_layout)
465465
~startenv:(startenv - pos) ~is_last dbg ::
466466
transl_fundecls (pos + 3) rem
467467
| arity ->
468-
Cconst_symbol (curry_function_sym arity, dbg) ::
469-
alloc_closure_info ~arity
468+
Cconst_symbol (curry_function_sym arity.function_kind (List.map machtype_of_layout arity.params_layout) (machtype_of_layout arity.return_layout), dbg) ::
469+
alloc_closure_info ~arity:(arity.function_kind, List.length arity.params_layout)
470470
~startenv:(startenv - pos) ~is_last dbg ::
471471
Cconst_symbol (f.label, dbg) ::
472472
transl_fundecls (pos + 4) rem
@@ -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) ->
@@ -1480,8 +1484,14 @@ let transl_function f =
14801484
else
14811485
[ Reduce_code_size ]
14821486
in
1487+
let params_layout =
1488+
if List.length f.params = List.length f.arity.params_layout then
1489+
f.arity.params_layout
1490+
else
1491+
f.arity.params_layout @ [Lambda.layout_function]
1492+
in
14831493
Cfunction {fun_name = f.label;
1484-
fun_args = List.map (fun (id, _) -> (id, typ_val)) f.params;
1494+
fun_args = List.map2 (fun id ty -> (id, machtype_of_layout ty)) f.params params_layout;
14851495
fun_body = cmm_body;
14861496
fun_codegen_options;
14871497
fun_poll = f.poll;

file_formats/cmx_format.mli

+2-2
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/clambda.ml

+6-3
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@ open Asttypes
2020
open Lambda
2121

2222
type function_label = string
23-
type arity = Lambda.function_kind * int
23+
type arity = {
24+
function_kind : Lambda.function_kind ;
25+
params_layout : Lambda.layout list ;
26+
return_layout : Lambda.layout ;
27+
}
2428
type apply_kind = Lambda.region_close * Lambda.alloc_mode
2529

2630
type ustructured_constant =
@@ -98,8 +102,7 @@ and ulambda =
98102
and ufunction = {
99103
label : function_label;
100104
arity : arity;
101-
params : (Backend_var.With_provenance.t * layout) list;
102-
return : layout;
105+
params : Backend_var.With_provenance.t list;
103106
body : ulambda;
104107
dbg : Debuginfo.t;
105108
env : Backend_var.t option;

middle_end/clambda.mli

+6-3
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@ open Asttypes
2020
open Lambda
2121

2222
type function_label = string
23-
type arity = Lambda.function_kind * int
23+
type arity = {
24+
function_kind : Lambda.function_kind ;
25+
params_layout : Lambda.layout list ;
26+
return_layout : Lambda.layout ;
27+
}
2428
type apply_kind = Lambda.region_close * Lambda.alloc_mode
2529

2630
type ustructured_constant =
@@ -109,8 +113,7 @@ and ulambda =
109113
and ufunction = {
110114
label : function_label;
111115
arity : arity;
112-
params : (Backend_var.With_provenance.t * layout) list;
113-
return : layout;
116+
params : Backend_var.With_provenance.t list;
114117
body : ulambda;
115118
dbg : Debuginfo.t;
116119
env : Backend_var.t option;

middle_end/closure/closure.ml

+15-14
Original file line numberDiff line numberDiff line change
@@ -1029,28 +1029,29 @@ let rec close ({ backend; fenv; cenv ; mutable_vars; kinds; catch_env } as env)
10291029
Location.print_loc (Debuginfo.Scoped_location.to_location loc);
10301030
begin match (close env funct, close_list env args) with
10311031
((ufunct, Value_closure(_,
1032-
({fun_arity=(Tupled, nparams)} as fundesc),
1032+
({fun_arity={function_kind = Tupled ; params_layout = params_layout; _}} as fundesc),
10331033
approx_res)),
10341034
[Uprim(P.Pmakeblock _, uargs, _)])
1035-
when List.length uargs = nparams ->
1035+
when List.length uargs = List.length params_layout ->
10361036
let app =
10371037
direct_apply env ~loc ~attribute fundesc ufunct uargs
10381038
pos mode ~probe in
10391039
(app, strengthen_approx app approx_res)
10401040
| ((ufunct, Value_closure(_,
1041-
({fun_arity=(Curried _, nparams)} as fundesc),
1041+
({fun_arity={function_kind = Curried _ ; params_layout ; _}} as fundesc),
10421042
approx_res)), uargs)
1043-
when nargs = nparams ->
1043+
when nargs = List.length params_layout ->
10441044
let app =
10451045
direct_apply env ~loc ~attribute fundesc ufunct uargs
10461046
pos mode ~probe in
10471047
(app, strengthen_approx app approx_res)
10481048

10491049
| ((ufunct, (Value_closure(
10501050
clos_mode,
1051-
({fun_arity=(Curried {nlocal}, nparams)} as fundesc),
1051+
({fun_arity={ function_kind = Curried {nlocal} ; params_layout ; _ }} as fundesc),
10521052
_) as fapprox)), uargs)
1053-
when nargs < nparams ->
1053+
when nargs < List.length params_layout ->
1054+
let nparams = List.length params_layout in
10541055
let first_args = List.map (fun arg ->
10551056
(V.create_local "arg", arg) ) uargs in
10561057
(* CR mshinwell: Edit when Lapply has kinds *)
@@ -1119,9 +1120,10 @@ let rec close ({ backend; fenv; cenv ; mutable_vars; kinds; catch_env } as env)
11191120
fail_if_probe ~probe "Partial application";
11201121
(new_fun, approx)
11211122

1122-
| ((ufunct, Value_closure(_, ({fun_arity = (Curried _, nparams)} as fundesc),
1123+
| ((ufunct, Value_closure(_, ({fun_arity = { function_kind = Curried _; params_layout ; _}} as fundesc),
11231124
_approx_res)), uargs)
1124-
when nargs > nparams ->
1125+
when nargs > List.length params_layout ->
1126+
let nparams = List.length params_layout in
11251127
let args = List.map (fun arg -> V.create_local "arg", arg) uargs in
11261128
(* CR mshinwell: Edit when Lapply has kinds *)
11271129
let kinds =
@@ -1154,6 +1156,7 @@ let rec close ({ backend; fenv; cenv ; mutable_vars; kinds; catch_env } as env)
11541156
in
11551157
let result =
11561158
List.fold_left (fun body (id, defining_expr) ->
1159+
(* CR ncourant: we need to know the layout of defining_expr here, this is hard *)
11571160
Ulet (Immutable, Lambda.layout_top, VP.create id, defining_expr, body))
11581161
body
11591162
args
@@ -1276,7 +1279,7 @@ let rec close ({ backend; fenv; cenv ; mutable_vars; kinds; catch_env } as env)
12761279
in
12771280
let arg, _approx = close env arg in
12781281
let id = Ident.create_local "dummy" in
1279-
Ulet(Immutable, Lambda.layout_top, VP.create id, arg, cst), approx
1282+
Ulet(Immutable, Lambda.layout_unit, VP.create id, arg, cst), approx
12801283
| Lprim(Pignore, [arg], _loc) ->
12811284
let expr, approx = make_const_int 0 in
12821285
Usequence(fst (close env arg), expr), approx
@@ -1483,10 +1486,9 @@ and close_functions { backend; fenv; cenv; mutable_vars; kinds; catch_env } fun_
14831486
|> Symbol.linkage_name
14841487
|> Linkage_name.to_string
14851488
in
1486-
let arity = List.length params in
14871489
let fundesc =
14881490
{fun_label = label;
1489-
fun_arity = (kind, arity);
1491+
fun_arity = { function_kind = kind ; params_layout = List.map snd params ; return_layout = return };
14901492
fun_closed = initially_closed;
14911493
fun_inline = None;
14921494
fun_float_const_prop = !Clflags.float_const_prop;
@@ -1515,7 +1517,7 @@ and close_functions { backend; fenv; cenv; mutable_vars; kinds; catch_env } fun_
15151517
(fun (_id, _params, _return, _body, _mode, _attrib, fundesc, _dbg) ->
15161518
let pos = !env_pos + 1 in
15171519
env_pos := !env_pos + 1 +
1518-
(match fundesc.fun_arity with (Curried _, (0|1)) -> 2 | _ -> 3);
1520+
(match fundesc.fun_arity with { function_kind = Curried _; params_layout = ([] | [_]); _} -> 2 | _ -> 3);
15191521
pos)
15201522
uncurried_defs in
15211523
let fv_pos = !env_pos in
@@ -1565,8 +1567,7 @@ and close_functions { backend; fenv; cenv; mutable_vars; kinds; catch_env } fun_
15651567
{
15661568
label = fundesc.fun_label;
15671569
arity = fundesc.fun_arity;
1568-
params = List.map (fun (var, kind) -> VP.create var, kind) fun_params;
1569-
return;
1570+
params = List.map (fun (var, _) -> VP.create var) fun_params;
15701571
body = ubody;
15711572
dbg;
15721573
env = Some env_param;

middle_end/compilenv.ml

+10-10
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

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
(**************************************************************************)
23
(* *)
34
(* OCaml *)
@@ -68,9 +69,9 @@ val get_unit_export_info
6869
val flambda2_set_export_info : Flambda2_cmx.Flambda_cmx_format.t -> unit
6970
(* Set the export information for the current unit (Flambda 2 only). *)
7071

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
72+
val need_curry_fun: Lambda.function_kind -> Cmm.machtype list -> Cmm.machtype -> unit
73+
val need_apply_fun: Cmm.machtype list -> Cmm.machtype -> Lambda.alloc_mode -> unit
74+
val need_send_fun: Cmm.machtype list -> Cmm.machtype -> Lambda.alloc_mode -> unit
7475
(* Record the need of a currying (resp. application,
7576
message sending) function with the given arity *)
7677

middle_end/flambda/flambda_to_clambda.ml

+8-6
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,11 @@ let clambda_arity (func : Flambda.function_declaration) : Clambda.arity =
9999
Lambda.is_local_mode (Parameter.alloc_mode p))
100100
|> List.length
101101
in
102-
Curried {nlocal}, Flambda_utils.function_arity func
102+
{
103+
function_kind = Curried {nlocal} ;
104+
params_layout = List.map Parameter.kind func.params ;
105+
return_layout = assert false ; (* Need func.return *)
106+
}
103107

104108
let check_field t ulam pos named_opt : Clambda.ulambda =
105109
if not !Clflags.clambda_checks then ulam
@@ -562,7 +566,7 @@ and to_clambda_set_of_closures t env
562566
let env_body, params =
563567
List.fold_right (fun var (env, params) ->
564568
let id, env = Env.add_fresh_ident env (Parameter.var var) in
565-
env, (VP.create id, Parameter.kind var) :: params)
569+
env, VP.create id :: params)
566570
function_decl.params (env, [])
567571
in
568572
let label =
@@ -572,8 +576,7 @@ and to_clambda_set_of_closures t env
572576
in
573577
{ label;
574578
arity = clambda_arity function_decl;
575-
params = params @ [VP.create env_var, Lambda.layout_function];
576-
return = Lambda.layout_top;
579+
params = params @ [VP.create env_var];
577580
body = to_clambda t env_body function_decl.body;
578581
dbg = function_decl.dbg;
579582
env = Some env_var;
@@ -623,7 +626,7 @@ and to_clambda_closed_set_of_closures t env symbol
623626
let env_body, params =
624627
List.fold_right (fun var (env, params) ->
625628
let id, env = Env.add_fresh_ident env (Parameter.var var) in
626-
env, (VP.create id, Parameter.kind var) :: params)
629+
env, VP.create id :: params)
627630
function_decl.params (env, [])
628631
in
629632
let body =
@@ -641,7 +644,6 @@ and to_clambda_closed_set_of_closures t env symbol
641644
{ label;
642645
arity = clambda_arity function_decl;
643646
params;
644-
return = Lambda.layout_top;
645647
body;
646648
dbg = function_decl.dbg;
647649
env = None;

0 commit comments

Comments
 (0)