Skip to content

Commit 9e8dc73

Browse files
EkdohibslthlsGbury
authored
flambda-backend: Functions with unboxed parameters and returns (#1271)
Co-authored-by: Vincent Laviron <[email protected]> Co-authored-by: Guillaume Bury <[email protected]>
1 parent fc3ecd6 commit 9e8dc73

File tree

11 files changed

+81
-21
lines changed

11 files changed

+81
-21
lines changed

lambda/lambda.ml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -602,11 +602,14 @@ type function_attribute = {
602602
stub: bool;
603603
tmc_candidate: bool;
604604
may_fuse_arity: bool;
605+
unbox_return: bool;
605606
}
606607

607608
type scoped_location = Debuginfo.Scoped_location.t
608609

609-
type parameter_attribute = No_attributes
610+
type parameter_attribute = {
611+
unbox_param: bool;
612+
}
610613

611614
type lparam = {
612615
name : Ident.t;
@@ -803,12 +806,13 @@ let default_function_attribute = {
803806
them multi-argument. So, we keep arity fusion turned on by default for now.
804807
*)
805808
may_fuse_arity = true;
809+
unbox_return = false;
806810
}
807811

808812
let default_stub_attribute =
809813
{ default_function_attribute with stub = true; check = Ignore_assert_all Zero_alloc }
810814

811-
let default_param_attribute = No_attributes
815+
let default_param_attribute = { unbox_param = false }
812816

813817
(* Build sharing keys *)
814818
(*

lambda/lambda.mli

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -499,9 +499,12 @@ type function_attribute = {
499499
(* [may_fuse_arity] is true if [simplif.ml] is permitted to fuse arity, i.e.,
500500
to perform the rewrite [fun x -> fun y -> e] to [fun x y -> e] *)
501501
may_fuse_arity: bool;
502+
unbox_return: bool;
502503
}
503504

504-
type parameter_attribute = No_attributes
505+
type parameter_attribute = {
506+
unbox_param: bool;
507+
}
505508

506509
type lparam = {
507510
name : Ident.t;

lambda/printlambda.ml

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -885,21 +885,23 @@ let rec lam ppf = function
885885
| Curried {nlocal} ->
886886
fprintf ppf "@ {nlocal = %d}" nlocal;
887887
List.iter (fun (p : Lambda.lparam) ->
888-
(* Make sure we change this once there are attributes *)
889-
let No_attributes = p.attributes in
890-
fprintf ppf "@ %a%s%a"
891-
Ident.print p.name (alloc_kind p.mode) layout p.layout) params
888+
let { unbox_param } = p.attributes in
889+
fprintf ppf "@ %a%s%a%s"
890+
Ident.print p.name (alloc_kind p.mode) layout p.layout
891+
(if unbox_param then "[@unboxed]" else "")
892+
) params
892893
| Tupled ->
893894
fprintf ppf " (";
894895
let first = ref true in
895896
List.iter
896897
(fun (p : Lambda.lparam) ->
897-
(* Make sure we change this once there are attributes *)
898-
let No_attributes = p.attributes in
898+
let { unbox_param } = p.attributes in
899899
if !first then first := false else fprintf ppf ",@ ";
900900
Ident.print ppf p.name;
901901
Format.fprintf ppf "%s" (alloc_kind p.mode);
902-
layout ppf p.layout)
902+
layout ppf p.layout;
903+
if unbox_param then Format.fprintf ppf "[@unboxed]"
904+
)
903905
params;
904906
fprintf ppf ")" in
905907
fprintf ppf "@[<2>(function%s%a@ %a%a%a)@]"

lambda/translattribute.ml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ let is_loop_attribute =
5353
let is_opaque_attribute =
5454
[ ["opaque"; "ocaml.opaque"], true ]
5555

56+
let is_unboxed_attribute =
57+
[ ["unboxed"; "ocaml.unboxed"], true ]
5658

5759
let find_attribute ?mark_used p attributes =
5860
let inline_attribute =
@@ -586,6 +588,21 @@ let add_opaque_attribute expr loc attributes =
586588
end
587589
| _ -> expr
588590

591+
let add_unbox_return_attribute expr loc attributes =
592+
match expr with
593+
| Lfunction funct ->
594+
let attr = find_attribute is_unboxed_attribute attributes in
595+
begin match attr with
596+
| None -> expr
597+
| Some _ ->
598+
if funct.attr.unbox_return then
599+
Location.prerr_warning loc
600+
(Warnings.Duplicated_attribute "unboxed");
601+
let attr = { funct.attr with unbox_return = true } in
602+
lfunction_with_attr ~attr funct
603+
end
604+
| _ -> expr
605+
589606

590607
(* Get the [@inlined] attribute payload (or default if not present). *)
591608
let get_inlined_attribute e =
@@ -646,6 +663,9 @@ let add_function_attributes lam loc attr =
646663
let lam =
647664
add_tmc_attribute lam loc attr
648665
in
666+
let lam =
667+
add_unbox_return_attribute lam loc attr
668+
in
649669
(* last because poll and opaque overrides inline and local *)
650670
let lam =
651671
add_poll_attribute lam loc attr
@@ -654,3 +674,10 @@ let add_function_attributes lam loc attr =
654674
add_opaque_attribute lam loc attr
655675
in
656676
lam
677+
678+
let transl_param_attributes pat =
679+
let attrs = pat.pat_attributes in
680+
let unbox_param =
681+
Option.is_some (find_attribute is_unboxed_attribute attrs)
682+
in
683+
{ unbox_param }

lambda/translattribute.mli

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,8 @@ val add_function_attributes
6666
-> Lambda.lambda
6767

6868
val get_assume_zero_alloc : with_warnings:bool -> Parsetree.attributes -> bool
69+
70+
val transl_param_attributes
71+
: Typedtree.pattern
72+
-> Lambda.parameter_attribute
73+

lambda/translcore.ml

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -963,6 +963,7 @@ and transl_exp0 ~in_new_scope ~scopes sort e =
963963
stub = false;
964964
poll = Default_poll;
965965
tmc_candidate = false;
966+
unbox_return = false;
966967
may_fuse_arity = false;
967968
} in
968969
let funcid = Ident.create_local ("probe_handler_" ^ name) in
@@ -1332,10 +1333,15 @@ and transl_curried_function ~scopes loc repr params body
13321333
layout_of_sort fc_loc fc_arg_sort
13331334
in
13341335
let arg_mode = transl_alloc_mode fc_arg_mode in
1336+
let attributes =
1337+
match fc_cases with
1338+
| [ { c_lhs }] -> Translattribute.transl_param_attributes c_lhs
1339+
| [] | _ :: _ :: _ -> Lambda.default_param_attribute
1340+
in
13351341
let param =
13361342
{ name = fc_param;
13371343
layout = arg_layout;
1338-
attributes = Lambda.default_param_attribute;
1344+
attributes;
13391345
mode = arg_mode;
13401346
}
13411347
in
@@ -1350,18 +1356,19 @@ and transl_curried_function ~scopes loc repr params body
13501356
List.fold_right
13511357
(fun fp (body, params) ->
13521358
let { fp_param; fp_kind; fp_mode; fp_sort; fp_partial; fp_loc } = fp in
1353-
let arg_env, arg_type =
1359+
let arg_env, arg_type, attributes =
13541360
match fp_kind with
1355-
| Tparam_pat pat -> pat.pat_env, pat.pat_type
1356-
| Tparam_optional_default (_, expr, _) ->
1357-
expr.exp_env, Predef.type_option expr.exp_type
1361+
| Tparam_pat pat ->
1362+
pat.pat_env, pat.pat_type, Translattribute.transl_param_attributes pat
1363+
| Tparam_optional_default (pat, expr, _) ->
1364+
expr.exp_env, Predef.type_option expr.exp_type, Translattribute.transl_param_attributes pat
13581365
in
13591366
let arg_layout = layout arg_env fp_loc fp_sort arg_type in
13601367
let arg_mode = transl_alloc_mode fp_mode in
13611368
let param =
13621369
{ name = fp_param;
13631370
layout = arg_layout;
1364-
attributes = Lambda.default_param_attribute;
1371+
attributes;
13651372
mode = arg_mode;
13661373
}
13671374
in

lambda/translmod.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,7 @@ let rec compile_functor ~scopes mexp coercion root_path loc =
603603
stub = false;
604604
tmc_candidate = false;
605605
may_fuse_arity = true;
606+
unbox_return = false;
606607
}
607608
~loc
608609
~mode:alloc_heap

middle_end/closure/closure.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1546,7 +1546,7 @@ and close_functions { backend; fenv; cenv; mutable_vars; kinds; catch_env } fun_
15461546
fun_region = region;
15471547
fun_poll = attr.poll } in
15481548
let dbg = Debuginfo.from_location loc in
1549-
(id, List.map (fun (p : Lambda.lparam) -> let No_attributes = p.attributes in (p.name, p.layout, p.mode)) params,
1549+
(id, List.map (fun (p : Lambda.lparam) -> (p.name, p.layout, p.mode)) params,
15501550
return, body, mode, fundesc, dbg)
15511551
| (_, _) -> fatal_error "Closure.close_functions")
15521552
fun_defs in

middle_end/flambda/closure_conversion.ml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ let rec close t env (lam : Lambda.lambda) : Flambda.t =
226226
(* CR-soon mshinwell: some of this is now very similar to the let rec case
227227
below *)
228228
let set_of_closures_var = Variable.create Names.set_of_closures in
229-
let params = List.map (fun (p : Lambda.lparam) -> let No_attributes = p.attributes in (p.name, p.layout)) params in
229+
let params = List.map (fun (p : Lambda.lparam) -> (p.name, p.layout)) params in
230230
let set_of_closures =
231231
let decl =
232232
Function_decl.create ~let_rec_ident:None ~closure_bound_var ~kind ~mode
@@ -279,7 +279,7 @@ let rec close t env (lam : Lambda.lambda) : Flambda.t =
279279
let closure_bound_var =
280280
Variable.create_with_same_name_as_ident let_rec_ident
281281
in
282-
let params = List.map (fun (p : Lambda.lparam) -> let No_attributes = p.attributes in (p.name, p.layout)) params in
282+
let params = List.map (fun (p : Lambda.lparam) -> (p.name, p.layout)) params in
283283
let function_declaration =
284284
Function_decl.create ~let_rec_ident:(Some let_rec_ident)
285285
~closure_bound_var ~kind ~mode ~region
@@ -699,7 +699,7 @@ and close_let_bound_expression t ?let_rec_ident let_bound_var env
699699
(* Ensure that [let] and [let rec]-bound functions have appropriate
700700
names. *)
701701
let closure_bound_var = Variable.rename let_bound_var in
702-
let params = List.map (fun (p : Lambda.lparam) -> let No_attributes = p.attributes in (p.name, p.layout)) params in
702+
let params = List.map (fun (p : Lambda.lparam) -> (p.name, p.layout)) params in
703703
let decl =
704704
Function_decl.create ~let_rec_ident ~closure_bound_var ~kind ~mode ~region
705705
~params ~body ~attr ~loc ~return_layout:return

utils/warnings.ml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ type t =
112112
| Unnecessarily_partial_tuple_pattern (* 189 *)
113113
| Probe_name_too_long of string (* 190 *)
114114
| Unchecked_property_attribute of string (* 199 *)
115+
| Unboxing_impossible (* 210 *)
115116

116117
(* If you remove a warning, leave a hole in the numbering. NEVER change
117118
the numbers of existing warnings.
@@ -196,12 +197,13 @@ let number = function
196197
| Unnecessarily_partial_tuple_pattern -> 189
197198
| Probe_name_too_long _ -> 190
198199
| Unchecked_property_attribute _ -> 199
200+
| Unboxing_impossible -> 210
199201
;;
200202
(* DO NOT REMOVE the ;; above: it is used by
201203
the testsuite/ests/warnings/mnemonics.mll test to determine where
202204
the definition of the number function above ends *)
203205

204-
let last_warning_number = 199
206+
let last_warning_number = 210
205207
;;
206208

207209
type description =
@@ -555,6 +557,10 @@ let descriptions = [
555557
description = "A property of a function that was \
556558
optimized away cannot be checked.";
557559
since = since 4 14 };
560+
{ number = 210;
561+
names = ["unboxing-impossible"];
562+
description = "The parameter or return value corresponding @unboxed attribute cannot be unboxed.";
563+
since = since 4 14 };
558564
]
559565

560566
let name_to_number =
@@ -1170,6 +1176,10 @@ let message = function
11701176
You can try to mark this function as [@inline never] \n\
11711177
or move the attribute to the relevant callers of this function."
11721178
property
1179+
| Unboxing_impossible ->
1180+
Printf.sprintf
1181+
"This [@unboxed] attribute cannot be used.\n\
1182+
The type of this value does not allow unboxing."
11731183
;;
11741184

11751185
let nerrors = ref 0

utils/warnings.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ type t =
116116
| Unnecessarily_partial_tuple_pattern (* 189 *)
117117
| Probe_name_too_long of string (* 190 *)
118118
| Unchecked_property_attribute of string (* 199 *)
119+
| Unboxing_impossible (* 210 *)
119120

120121
type alert = {kind:string; message:string; def:loc; use:loc}
121122

0 commit comments

Comments
 (0)