Skip to content

Commit f1352ed

Browse files
authored
flambda-backend: Add modes on parameters and a framework for attributes on them (#1257)
1 parent 3d23db5 commit f1352ed

File tree

14 files changed

+222
-103
lines changed

14 files changed

+222
-103
lines changed

bytecomp/bytegen.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,7 @@ let rec comp_expr env exp sz cont =
632632
let lbl = new_label() in
633633
let fv = Ident.Set.elements(free_variables exp) in
634634
let to_compile =
635-
{ params = List.map fst params; body = body; label = lbl;
635+
{ params = List.map (fun p -> p.name) params; body = body; label = lbl;
636636
free_vars = fv; num_defs = 1; rec_vars = []; rec_pos = 0 } in
637637
Stack.push to_compile functions_to_compile;
638638
comp_args env (List.map (fun n -> Lvar n) fv) sz
@@ -655,7 +655,7 @@ let rec comp_expr env exp sz cont =
655655
| (_id, Lfunction{params; body}) :: rem ->
656656
let lbl = new_label() in
657657
let to_compile =
658-
{ params = List.map fst params; body = body; label = lbl;
658+
{ params = List.map (fun p -> p.name) params; body = body; label = lbl;
659659
free_vars = fv; num_defs = ndecl; rec_vars = rec_idents;
660660
rec_pos = pos} in
661661
Stack.push to_compile functions_to_compile;

lambda/lambda.ml

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,15 @@ type function_attribute = {
537537

538538
type scoped_location = Debuginfo.Scoped_location.t
539539

540+
type parameter_attribute = No_attributes
541+
542+
type lparam = {
543+
name : Ident.t;
544+
layout : layout;
545+
attributes : parameter_attribute;
546+
mode : alloc_mode
547+
}
548+
540549
type lambda =
541550
Lvar of Ident.t
542551
| Lmutvar of Ident.t
@@ -568,7 +577,7 @@ type lambda =
568577

569578
and lfunction =
570579
{ kind: function_kind;
571-
params: (Ident.t * layout) list;
580+
params: lparam list;
572581
return: layout;
573582
body: lambda;
574583
attr: function_attribute; (* specified with [@inline] attribute *)
@@ -715,6 +724,8 @@ let default_function_attribute = {
715724
let default_stub_attribute =
716725
{ default_function_attribute with stub = true; check = Ignore_assert_all Zero_alloc }
717726

727+
let default_param_attribute = No_attributes
728+
718729
(* Build sharing keys *)
719730
(*
720731
Those keys are later compared with Stdlib.compare.
@@ -901,7 +912,7 @@ let rec free_variables = function
901912
free_variables_list (free_variables fn) args
902913
| Lfunction{body; params} ->
903914
Ident.Set.diff (free_variables body)
904-
(Ident.Set.of_list (List.map fst params))
915+
(Ident.Set.of_list (List.map (fun p -> p.name) params))
905916
| Llet(_, _k, id, arg, body)
906917
| Lmutlet(_k, id, arg, body) ->
907918
Ident.Set.union
@@ -1073,6 +1084,12 @@ let subst update_env ?(freshen_bound_variables = false) s input_lam =
10731084
((id', rhs) :: ids' , l)
10741085
) ids ([], l)
10751086
in
1087+
let bind_params params l =
1088+
List.fold_right (fun p (params', l) ->
1089+
let name', l = bind p.name l in
1090+
({ p with name = name' } :: params' , l)
1091+
) params ([], l)
1092+
in
10761093
let rec subst s l lam =
10771094
match lam with
10781095
| Lvar id as lam ->
@@ -1097,7 +1114,7 @@ let subst update_env ?(freshen_bound_variables = false) s input_lam =
10971114
Lapply{ap with ap_func = subst s l ap.ap_func;
10981115
ap_args = subst_list s l ap.ap_args}
10991116
| Lfunction lf ->
1100-
let params, l' = bind_many lf.params l in
1117+
let params, l' = bind_params lf.params l in
11011118
Lfunction {lf with params; body = subst s l' lf.body}
11021119
| Llet(str, k, id, arg, body) ->
11031120
let id, l' = bind id l in

lambda/lambda.mli

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,14 @@ type function_attribute = {
414414
tmc_candidate: bool;
415415
}
416416

417+
type parameter_attribute = No_attributes
418+
419+
type lparam = {
420+
name : Ident.t;
421+
layout : layout;
422+
attributes : parameter_attribute;
423+
mode : alloc_mode
424+
}
417425

418426
type scoped_location = Debuginfo.Scoped_location.t
419427

@@ -451,7 +459,7 @@ type lambda =
451459

452460
and lfunction = private
453461
{ kind: function_kind;
454-
params: (Ident.t * layout) list;
462+
params: lparam list;
455463
return: layout;
456464
body: lambda;
457465
attr: function_attribute; (* specified with [@inline] attribute *)
@@ -568,7 +576,7 @@ val name_lambda_list: (lambda * layout) list -> (lambda list -> lambda) -> lambd
568576

569577
val lfunction :
570578
kind:function_kind ->
571-
params:(Ident.t * layout) list ->
579+
params:lparam list ->
572580
return:layout ->
573581
body:lambda ->
574582
attr:function_attribute -> (* specified with [@inline] attribute *)
@@ -653,6 +661,7 @@ val swap_float_comparison : float_comparison -> float_comparison
653661

654662
val default_function_attribute : function_attribute
655663
val default_stub_attribute : function_attribute
664+
val default_param_attribute : parameter_attribute
656665

657666
val find_exact_application :
658667
function_kind -> arity:int -> lambda list -> lambda list option

lambda/printlambda.ml

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,7 @@ let apply_specialised_attribute ppf = function
667667
| Always_specialise -> fprintf ppf " always_specialise"
668668
| Never_specialise -> fprintf ppf " never_specialise"
669669

670-
let apply_probe ppf = function
670+
let apply_probe ppf : probe -> unit = function
671671
| None -> ()
672672
| Some {name} -> fprintf ppf " (probe %s)" name
673673

@@ -702,16 +702,22 @@ let rec lam ppf = function
702702
match kind with
703703
| Curried {nlocal} ->
704704
fprintf ppf "@ {nlocal = %d}" nlocal;
705-
List.iter (fun (param, k) ->
706-
fprintf ppf "@ %a%a" Ident.print param layout k) params
705+
List.iter (fun (p : Lambda.lparam) ->
706+
(* Make sure we change this once there are attributes *)
707+
let No_attributes = p.attributes in
708+
fprintf ppf "@ %a%s%a"
709+
Ident.print p.name (alloc_kind p.mode) layout p.layout) params
707710
| Tupled ->
708711
fprintf ppf " (";
709712
let first = ref true in
710713
List.iter
711-
(fun (param, k) ->
712-
if !first then first := false else fprintf ppf ",@ ";
713-
Ident.print ppf param;
714-
layout ppf k)
714+
(fun (p : Lambda.lparam) ->
715+
(* Make sure we change this once there are attributes *)
716+
let No_attributes = p.attributes in
717+
if !first then first := false else fprintf ppf ",@ ";
718+
Ident.print ppf p.name;
719+
Format.fprintf ppf "%s" (alloc_kind p.mode);
720+
layout ppf p.layout)
715721
params;
716722
fprintf ppf ")" in
717723
let rmode = if region then alloc_heap else alloc_local in

lambda/simplif.ml

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -373,8 +373,9 @@ let exact_application {kind; params; _} args =
373373
Lambda.find_exact_application kind ~arity args
374374

375375
let beta_reduce params body args =
376-
List.fold_left2 (fun l (param, kind) arg -> Llet(Strict, kind, param, arg, l))
377-
body params args
376+
List.fold_left2
377+
(fun l param arg -> Llet(Strict, param.layout, param.name, arg, l))
378+
body params args
378379

379380
(* Simplification of lets *)
380381

@@ -778,7 +779,8 @@ let split_default_wrapper ~id:fun_id ~kind ~params ~return ~body
778779
| Llet(Strict, k, id,
779780
(Lifthenelse(Lprim (Pisint _, [Lvar optparam], _), _, _, _) as def),
780781
rest) when
781-
Ident.name optparam = "*opt*" && List.mem_assoc optparam params
782+
Ident.name optparam = "*opt*" &&
783+
List.exists (fun p -> Ident.same p.name optparam) params
782784
&& not (List.mem_assoc optparam map)
783785
->
784786
let wrapper_body, inner = aux ((optparam, id) :: map) add_region rest in
@@ -793,14 +795,19 @@ let split_default_wrapper ~id:fun_id ~kind ~params ~return ~body
793795
List.iter (fun (id, _) -> if Ident.Set.mem id fv then raise Exit) map;
794796

795797
let inner_id = Ident.create_local (Ident.name fun_id ^ "_inner") in
796-
let map_param p layout =
798+
let map_param (p : Lambda.lparam) =
797799
try
798800
(* If the param is optional, then it must be a value *)
799-
List.assoc p map, Lambda.layout_field
801+
{
802+
name = List.assoc p.name map;
803+
layout = Lambda.layout_field;
804+
attributes = Lambda.default_param_attribute;
805+
mode = p.mode
806+
}
800807
with
801-
Not_found -> p, layout
808+
Not_found -> p
802809
in
803-
let args = List.map (fun (p, layout) -> Lvar (fst (map_param p layout))) params in
810+
let args = List.map (fun p -> Lvar (map_param p).name) params in
804811
let wrapper_body =
805812
Lapply {
806813
ap_func = Lvar inner_id;
@@ -815,11 +822,13 @@ let split_default_wrapper ~id:fun_id ~kind ~params ~return ~body
815822
ap_probe=None;
816823
}
817824
in
818-
let inner_params = List.map (fun (param, layout) -> map_param param layout) params in
819-
let new_ids = List.map (fun (param, layout) -> (Ident.rename param, layout)) inner_params in
825+
let inner_params = List.map map_param params in
826+
let new_ids =
827+
List.map (fun p -> { p with name = Ident.rename p.name }) inner_params
828+
in
820829
let subst =
821-
List.fold_left2 (fun s (id, _) (new_id, _) ->
822-
Ident.Map.add id new_id s
830+
List.fold_left2 (fun s p new_p ->
831+
Ident.Map.add p.name new_p.name s
823832
) Ident.Map.empty inner_params new_ids
824833
in
825834
let body = Lambda.rename subst body in
@@ -1005,9 +1014,13 @@ let simplify_local_functions lam =
10051014
| lam ->
10061015
Lambda.shallow_map ~tail:rewrite ~non_tail:rewrite lam
10071016
in
1017+
let new_params lf =
1018+
List.map
1019+
(fun p -> (p.name, p.layout)) lf.params
1020+
in
10081021
List.fold_right
10091022
(fun (st, lf) lam ->
1010-
Lstaticcatch (lam, (st, lf.params), rewrite lf.body, lf.return)
1023+
Lstaticcatch (lam, (st, new_params lf), rewrite lf.body, lf.return)
10111024
)
10121025
(LamTbl.find_all static lam0)
10131026
lam

lambda/simplif.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ val simplify_lambda: lambda -> lambda
3232
val split_default_wrapper
3333
: id:Ident.t
3434
-> kind:function_kind
35-
-> params:(Ident.t * Lambda.layout) list
35+
-> params:Lambda.lparam list
3636
-> return:Lambda.layout
3737
-> body:lambda
3838
-> attr:function_attribute

lambda/tmc.ml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,11 @@ and offset = Offset of lambda
6262
let offset_code (Offset t) = t
6363

6464
let add_dst_params ({var; offset} : Ident.t destination) params =
65-
(var, Lambda.layout_block) :: (offset, Lambda.layout_int) :: params
65+
{ name = var ; layout = Lambda.layout_block ;
66+
attributes = Lambda.default_param_attribute ; mode = alloc_heap } ::
67+
{ name = offset ; layout = Lambda.layout_int ;
68+
attributes = Lambda.default_param_attribute ; mode = alloc_heap } ::
69+
params
6670

6771
let add_dst_args ({var; offset} : offset destination) args =
6872
Lvar var :: offset_code offset :: args

lambda/transl_list_comprehension.ml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,17 @@ let rec translate_bindings
245245
~kind:(Curried { nlocal = 2 })
246246
(* Only the accumulator is local, but since the function itself is
247247
local, [nlocal] has to be equal to the number of parameters *)
248-
~params:[element, element_kind; inner_acc, Pvalue Pgenval]
248+
~params:[
249+
{name = element;
250+
layout = element_kind;
251+
attributes = Lambda.default_param_attribute;
252+
(* CR ncourant: check *)
253+
mode = alloc_heap};
254+
{name = inner_acc;
255+
layout = Pvalue Pgenval;
256+
attributes = Lambda.default_param_attribute;
257+
mode = alloc_local}
258+
]
249259
~return:(Pvalue Pgenval)
250260
~attr:default_function_attribute
251261
~loc

0 commit comments

Comments
 (0)