Skip to content

Commit 1a73a72

Browse files
mshinwellriaqn
andauthored
Clean up ret_mode and region in Lambda.lfunction (#2985)
Co-authored-by: Zesen Qian <[email protected]>
1 parent e743d6c commit 1a73a72

21 files changed

+96
-170
lines changed

lambda/lambda.ml

+8-9
Original file line numberDiff line numberDiff line change
@@ -851,7 +851,7 @@ and lfunction =
851851
loc: scoped_location;
852852
mode: locality_mode;
853853
ret_mode: locality_mode;
854-
region: bool; }
854+
}
855855

856856
and lambda_while =
857857
{ wh_cond : lambda;
@@ -938,7 +938,7 @@ let max_arity () =
938938
(* 126 = 127 (the maximal number of parameters supported in C--)
939939
- 1 (the hidden parameter containing the environment) *)
940940

941-
let lfunction' ~kind ~params ~return ~body ~attr ~loc ~mode ~ret_mode ~region =
941+
let lfunction' ~kind ~params ~return ~body ~attr ~loc ~mode ~ret_mode =
942942
assert (List.length params > 0);
943943
assert (List.length params <= max_arity ());
944944
(* A curried function type with n parameters has n arrows. Of these,
@@ -959,14 +959,13 @@ let lfunction' ~kind ~params ~return ~body ~attr ~loc ~mode ~ret_mode ~region =
959959
let nparams = List.length params in
960960
assert (0 <= nlocal);
961961
assert (nlocal <= nparams);
962-
if not region then assert (nlocal >= 1);
962+
if is_local_mode ret_mode then assert (nlocal >= 1);
963963
if is_local_mode mode then assert (nlocal = nparams)
964964
end;
965-
{ kind; params; return; body; attr; loc; mode; ret_mode; region }
965+
{ kind; params; return; body; attr; loc; mode; ret_mode }
966966

967-
let lfunction ~kind ~params ~return ~body ~attr ~loc ~mode ~ret_mode ~region =
968-
Lfunction
969-
(lfunction' ~kind ~params ~return ~body ~attr ~loc ~mode ~ret_mode ~region)
967+
let lfunction ~kind ~params ~return ~body ~attr ~loc ~mode ~ret_mode =
968+
Lfunction (lfunction' ~kind ~params ~return ~body ~attr ~loc ~mode ~ret_mode)
970969

971970
let lambda_unit = Lconst const_unit
972971

@@ -1601,9 +1600,9 @@ let duplicate_function =
16011600
Ident.Map.empty).subst_lfunction
16021601

16031602
let map_lfunction f { kind; params; return; body; attr; loc;
1604-
mode; ret_mode; region } =
1603+
mode; ret_mode } =
16051604
let body = f body in
1606-
{ kind; params; return; body; attr; loc; mode; ret_mode; region }
1605+
{ kind; params; return; body; attr; loc; mode; ret_mode }
16071606

16081607
let shallow_map ~tail ~non_tail:f = function
16091608
| Lvar _

lambda/lambda.mli

+29-7
Original file line numberDiff line numberDiff line change
@@ -663,9 +663,33 @@ type loop_attribute =
663663
| Default_loop (* no [@loop] attribute *)
664664

665665
type curried_function_kind = { nlocal: int } [@@unboxed]
666-
(* [nlocal] determines how many arguments may be partially applied
667-
before the resulting closure must be locally allocated.
668-
See [lfunction] for details *)
666+
(** A well-formed function parameter list is of the form
667+
[G @ L @ [ Final_arg ]],
668+
where the values of G and L are of the form [More_args { partial_mode }],
669+
where [partial_mode] has locality Global in G and locality Local in L.
670+
671+
[nlocal] is defined as follows:
672+
- if {v |L| > 0 v}, then {v nlocal = |L| + 1 v}.
673+
- if {v |L| = 0 v},
674+
* if the function returns at mode local, the final arg has mode local,
675+
or the function itself is allocated locally, then {v nlocal = 1 v}.
676+
* otherwise, {v nlocal = 0 v}.
677+
*)
678+
679+
(* CR-someday: Now that some functions' arity won't be changed downstream of
680+
lambda (see [may_fuse_arity = false]), we could change [nlocal] to be
681+
more expressive. I suggest the variant:
682+
683+
{[
684+
type partial_application_is_local_when =
685+
| Applied_up_to_nth_argument_from_end of int
686+
| Never
687+
]}
688+
689+
I believe this will allow us to get rid of the complicated logic for
690+
|L| = 0, and help clarify how clients use this type. I plan on doing
691+
this in a follow-on PR.
692+
*)
669693

670694
type function_kind = Curried of curried_function_kind | Tupled
671695

@@ -797,8 +821,8 @@ and lfunction = private
797821
loc : scoped_location;
798822
mode : locality_mode; (* locality of the closure itself *)
799823
ret_mode: locality_mode;
800-
region : bool; (* false if this function may locally
801-
allocate in the caller's region *)
824+
(** alloc mode of the returned value. Also indicates if the function might
825+
allocate in the caller's region. *)
802826
}
803827

804828
and lambda_while =
@@ -1002,7 +1026,6 @@ val lfunction :
10021026
loc:scoped_location ->
10031027
mode:locality_mode ->
10041028
ret_mode:locality_mode ->
1005-
region:bool ->
10061029
lambda
10071030

10081031
val lfunction' :
@@ -1014,7 +1037,6 @@ val lfunction' :
10141037
loc:scoped_location ->
10151038
mode:locality_mode ->
10161039
ret_mode:locality_mode ->
1017-
region:bool ->
10181040
lfunction
10191041

10201042

lambda/simplif.ml

+18-17
Original file line numberDiff line numberDiff line change
@@ -253,10 +253,10 @@ let simplify_exits lam =
253253
| Lletrec(bindings, body) ->
254254
let bindings =
255255
List.map (fun ({ def = {kind; params; return; body = l; attr; loc;
256-
mode; ret_mode; region} }
256+
mode; ret_mode } }
257257
as rb) ->
258258
let def =
259-
lfunction' ~kind ~params ~return ~mode ~ret_mode ~region
259+
lfunction' ~kind ~params ~return ~mode ~ret_mode
260260
~body:(simplif ~layout:None ~try_depth l) ~attr ~loc
261261
in
262262
{ rb with def })
@@ -587,12 +587,12 @@ let simplify_lets lam =
587587
| _ -> no_opt ()
588588
end
589589
| Lfunction{kind=outer_kind; params; return=outer_return; body = l;
590-
attr=attr1; loc; ret_mode; mode; region=outer_region} ->
591-
begin match outer_kind, outer_region, simplif l with
590+
attr=attr1; loc; ret_mode; mode} ->
591+
begin match outer_kind, ret_mode, simplif l with
592592
Curried {nlocal=0},
593-
true,
593+
Alloc_heap,
594594
Lfunction{kind=Curried _ as kind; params=params'; return=return2;
595-
body; attr=attr2; loc; mode=inner_mode; ret_mode; region}
595+
body; attr=attr2; loc; mode=inner_mode; ret_mode}
596596
when optimize &&
597597
attr1.may_fuse_arity && attr2.may_fuse_arity &&
598598
List.length params + List.length params' <= Lambda.max_arity() ->
@@ -603,9 +603,9 @@ let simplify_lets lam =
603603
type of the merged function taking [params @ params'] as
604604
parameters is the type returned after applying [params']. *)
605605
let return = return2 in
606-
lfunction ~kind ~params:(params @ params') ~return ~body ~attr:attr1 ~loc ~mode ~ret_mode ~region
607-
| kind, region, body ->
608-
lfunction ~kind ~params ~return:outer_return ~body ~attr:attr1 ~loc ~mode ~ret_mode ~region
606+
lfunction ~kind ~params:(params @ params') ~return ~body ~attr:attr1 ~loc ~mode ~ret_mode
607+
| kind, ret_mode, body ->
608+
lfunction ~kind ~params ~return:outer_return ~body ~attr:attr1 ~loc ~mode ~ret_mode
609609
end
610610
| Llet(_str, _k, v, Lvar w, l2) when optimize ->
611611
Hashtbl.add subst v (simplif (Lvar w));
@@ -802,7 +802,7 @@ and emit_tail_infos_lfunction _is_tail lfun =
802802
function's body. *)
803803

804804
let split_default_wrapper ~id:fun_id ~kind ~params ~return ~body
805-
~attr ~loc ~mode ~ret_mode ~region:orig_region =
805+
~attr ~loc ~mode ~ret_mode =
806806
let rec aux map add_region = function
807807
(* When compiling [fun ?(x=expr) -> body], this is first translated
808808
to:
@@ -882,28 +882,29 @@ let split_default_wrapper ~id:fun_id ~kind ~params ~return ~body
882882
let inner_fun =
883883
lfunction' ~kind:(Curried {nlocal=0})
884884
~params:new_ids
885-
~return ~body ~attr ~loc ~mode ~ret_mode ~region:true
885+
~return ~body ~attr ~loc ~mode ~ret_mode
886886
in
887887
(wrapper_body, { id = inner_id;
888888
def = inner_fun })
889889
in
890890
try
891891
(* TODO: enable this optimisation even in the presence of local returns *)
892-
begin match kind with
893-
| Curried {nlocal} when nlocal > 0 -> raise Exit
894-
| Tupled when not orig_region -> raise Exit
895-
| _ -> assert orig_region
892+
begin match kind, ret_mode with
893+
| Curried {nlocal}, _ when nlocal > 0 -> raise Exit
894+
| Tupled, Alloc_local -> raise Exit
895+
| _, Alloc_heap -> ()
896+
| _, Alloc_local -> assert false
896897
end;
897898
let body, inner = aux [] false body in
898899
let attr = { default_stub_attribute with zero_alloc = attr.zero_alloc } in
899900
[{ id = fun_id;
900901
def = lfunction' ~kind ~params ~return ~body ~attr ~loc
901-
~mode ~ret_mode ~region:true };
902+
~mode ~ret_mode };
902903
inner]
903904
with Exit ->
904905
[{ id = fun_id;
905906
def = lfunction' ~kind ~params ~return ~body ~attr ~loc
906-
~mode ~ret_mode ~region:orig_region }]
907+
~mode ~ret_mode }]
907908

908909
(* Simplify local let-bound functions: if all occurrences are
909910
fully-applied function calls in the same "tail scope", replace the

lambda/simplif.mli

-1
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,4 @@ val split_default_wrapper
3939
-> loc:Lambda.scoped_location
4040
-> mode:Lambda.locality_mode
4141
-> ret_mode:Lambda.locality_mode
42-
-> region:bool
4342
-> rec_binding list

lambda/tmc.ml

+2-3
Original file line numberDiff line numberDiff line change
@@ -1045,9 +1045,9 @@ and make_dps_variant var inner_ctx outer_ctx (lfun : lfunction) =
10451045
(Debuginfo.Scoped_location.to_location lfun.loc)
10461046
Warnings.Unused_tmc_attribute;
10471047
let direct =
1048-
let { kind; params; return; body = _; attr; loc; mode; ret_mode; region } = lfun in
1048+
let { kind; params; return; body = _; attr; loc; mode; ret_mode } = lfun in
10491049
let body = Choice.direct fun_choice in
1050-
lfunction' ~kind ~params ~return ~body ~attr ~loc ~mode ~ret_mode ~region in
1050+
lfunction' ~kind ~params ~return ~body ~attr ~loc ~mode ~ret_mode in
10511051
let dps =
10521052
let dst_param = {
10531053
var = Ident.create_local "dst";
@@ -1076,7 +1076,6 @@ and make_dps_variant var inner_ctx outer_ctx (lfun : lfunction) =
10761076
~loc:lfun.loc
10771077
~mode:lfun.mode
10781078
~ret_mode:lfun.ret_mode
1079-
~region:true
10801079
in
10811080
let dps_var = special.dps_id in
10821081
[var, direct; dps_var, dps]

lambda/transl_list_comprehension.ml

+1-2
Original file line numberDiff line numberDiff line change
@@ -252,8 +252,7 @@ let rec translate_bindings ~transl_exp ~scopes ~loc ~inner_body ~accumulator =
252252
mode = alloc_local
253253
} ]
254254
~return:layout_any_value ~attr:default_function_attribute ~loc
255-
~mode:alloc_local ~ret_mode:alloc_local ~region:false
256-
~body:(add_bindings body)
255+
~mode:alloc_local ~ret_mode:alloc_local ~body:(add_bindings body)
257256
in
258257
let result =
259258
Lambda_utils.apply ~loc ~mode:alloc_local (Lazy.force builder)

lambda/translattribute.ml

+2-2
Original file line numberDiff line numberDiff line change
@@ -257,8 +257,8 @@ let check_opaque_local loc attr =
257257

258258

259259
let lfunction_with_attr ~attr
260-
{ kind; params; return; body; attr=_; loc; mode; ret_mode; region } =
261-
lfunction ~kind ~params ~return ~body ~attr ~loc ~mode ~ret_mode ~region
260+
{ kind; params; return; body; attr=_; loc; mode; ret_mode } =
261+
lfunction ~kind ~params ~return ~body ~attr ~loc ~mode ~ret_mode
262262

263263
let add_inline_attribute expr loc attributes =
264264
match expr with

lambda/translclass.ml

+4-12
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,12 @@ let layout_meth = layout_any_value
3737
let layout_tables = layout_any_value
3838

3939

40-
let lfunction ?(kind=Curried {nlocal=0}) ?(region=true) ?(ret_mode=alloc_heap) return_layout params body =
40+
let lfunction ?(kind=Curried {nlocal=0}) ?(ret_mode=alloc_heap) return_layout params body =
4141
if params = [] then body else
4242
match kind, body with
4343
| Curried {nlocal=0},
4444
Lfunction {kind = Curried _ as kind; params = params';
45-
body = body'; attr; loc; mode = Alloc_heap; ret_mode; region}
45+
body = body'; attr; loc; mode = Alloc_heap; ret_mode }
4646
when attr.may_fuse_arity &&
4747
List.length params + List.length params' <= Lambda.max_arity() ->
4848
lfunction ~kind ~params:(params @ params')
@@ -52,15 +52,13 @@ let lfunction ?(kind=Curried {nlocal=0}) ?(region=true) ?(ret_mode=alloc_heap) r
5252
~loc
5353
~mode:alloc_heap
5454
~ret_mode
55-
~region
5655
| _ ->
5756
lfunction ~kind ~params ~return:return_layout
5857
~body
5958
~attr:default_function_attribute
6059
~loc:Loc_unknown
6160
~mode:alloc_heap
6261
~ret_mode
63-
~region
6462

6563
let lapply ap =
6664
match ap.ap_func with
@@ -230,7 +228,6 @@ let rec build_object_init ~scopes cl_table obj params inh_init obj_init cl =
230228
~body
231229
~mode:alloc_heap
232230
~ret_mode:alloc_heap
233-
~region:true
234231
in
235232
begin match obj_init with
236233
Lfunction {kind = Curried {nlocal=0}; params; body = rem} ->
@@ -520,7 +517,6 @@ let rec transl_class_rebind ~scopes obj_init cl vf =
520517
~body
521518
~mode:alloc_heap
522519
~ret_mode:alloc_heap
523-
~region:true
524520
in
525521
(path, path_lam,
526522
match obj_init with
@@ -799,7 +795,7 @@ let transl_class ~scopes ids cl_id pub_meths cl vflag =
799795
let new_ids_meths = ref [] in
800796
let no_env_update _ _ env = env in
801797
let msubst arr = function
802-
Lfunction {kind = Curried _ as kind; region; ret_mode;
798+
Lfunction {kind = Curried _ as kind; ret_mode;
803799
params = self :: args; return; body} ->
804800
let env = Ident.create_local "env" in
805801
let body' =
@@ -811,7 +807,7 @@ let transl_class ~scopes ids cl_id pub_meths cl vflag =
811807
if not arr || !Clflags.debug then raise Not_found;
812808
builtin_meths [self.name] env env2 (lfunction return args body')
813809
with Not_found ->
814-
[lfunction ~kind ~region ~ret_mode return (self :: args)
810+
[lfunction ~kind ~ret_mode return (self :: args)
815811
(if not (Ident.Set.mem env (free_variables body')) then body' else
816812
Llet(Alias, layout_block, env,
817813
Lprim(Pfield_computed Reads_vary,
@@ -885,7 +881,6 @@ let transl_class ~scopes ids cl_id pub_meths cl vflag =
885881
~return:layout_function
886882
~mode:alloc_heap
887883
~ret_mode:alloc_heap
888-
~region:true
889884
~params:[lparam cla layout_table]
890885
~body:cl_init,
891886
Dynamic (* Placeholder, real kind is computed in [lbody] below *))
@@ -917,7 +912,6 @@ let transl_class ~scopes ids cl_id pub_meths cl vflag =
917912
~return:layout_function
918913
~mode:alloc_heap
919914
~ret_mode:alloc_heap
920-
~region:true
921915
~params:[lparam cla layout_table] ~body:cl_init;
922916
lambda_unit; lenvs],
923917
Loc_unknown),
@@ -980,7 +974,6 @@ let transl_class ~scopes ids cl_id pub_meths cl vflag =
980974
~loc:Loc_unknown
981975
~mode:alloc_heap
982976
~ret_mode:alloc_heap
983-
~region:true
984977
~body:(def_ids cla cl_init), lam)
985978
and lset cached i lam =
986979
Lprim(Psetfield(i, Pointer, Assignment modify_heap),
@@ -999,7 +992,6 @@ let transl_class ~scopes ids cl_id pub_meths cl vflag =
999992
~loc:Loc_unknown
1000993
~mode:alloc_heap
1001994
~ret_mode:alloc_heap
1002-
~region:true
1003995
~return:layout_function
1004996
~params:[lparam cla layout_table]
1005997
~body:(def_ids cla cl_init))

0 commit comments

Comments
 (0)