Skip to content

Commit 2170ee5

Browse files
authored
flambda-backend: Better region handling for functions (#1871)
1 parent 948507a commit 2170ee5

21 files changed

+115
-76
lines changed

lambda/lambda.ml

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ include (struct
7070
if Config.stack_allocation then Modify_maybe_stack
7171
else Modify_heap
7272

73+
let equal_alloc_mode mode1 mode2 =
74+
match mode1, mode2 with
75+
| Alloc_local, Alloc_local | Alloc_heap, Alloc_heap -> true
76+
| (Alloc_local | Alloc_heap), _ -> false
77+
7378
end : sig
7479

7580
type locality_mode = private
@@ -92,6 +97,7 @@ end : sig
9297

9398
val join_mode : alloc_mode -> alloc_mode -> alloc_mode
9499

100+
val equal_alloc_mode : alloc_mode -> alloc_mode -> bool
95101
end)
96102

97103
let is_local_mode = function
@@ -612,6 +618,7 @@ and lfunction =
612618
attr: function_attribute; (* specified with [@inline] attribute *)
613619
loc: scoped_location;
614620
mode: alloc_mode;
621+
ret_mode: alloc_mode;
615622
region: bool; }
616623

617624
and lambda_while =
@@ -675,7 +682,7 @@ let max_arity () =
675682
(* 126 = 127 (the maximal number of parameters supported in C--)
676683
- 1 (the hidden parameter containing the environment) *)
677684

678-
let lfunction ~kind ~params ~return ~body ~attr ~loc ~mode ~region =
685+
let lfunction ~kind ~params ~return ~body ~attr ~loc ~mode ~ret_mode ~region =
679686
assert (List.length params <= max_arity ());
680687
(* A curried function type with n parameters has n arrows. Of these,
681688
the first [n-nlocal] have return mode Heap, while the remainder
@@ -698,7 +705,7 @@ let lfunction ~kind ~params ~return ~body ~attr ~loc ~mode ~region =
698705
if not region then assert (nlocal >= 1);
699706
if is_local_mode mode then assert (nlocal = nparams)
700707
end;
701-
Lfunction { kind; params; return; body; attr; loc; mode; region }
708+
Lfunction { kind; params; return; body; attr; loc; mode; ret_mode; region }
702709

703710
let lambda_unit = Lconst const_unit
704711

@@ -1272,9 +1279,9 @@ let shallow_map ~tail ~non_tail:f = function
12721279
ap_specialised;
12731280
ap_probe;
12741281
}
1275-
| Lfunction { kind; params; return; body; attr; loc; mode; region } ->
1282+
| Lfunction { kind; params; return; body; attr; loc; mode; ret_mode; region } ->
12761283
Lfunction { kind; params; return; body = f body; attr; loc;
1277-
mode; region }
1284+
mode; ret_mode; region }
12781285
| Llet (str, layout, v, e1, e2) ->
12791286
Llet (str, layout, v, f e1, tail e2)
12801287
| Lmutlet (layout, v, e1, e2) ->

lambda/lambda.mli

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ val modify_heap : modify_mode
5656

5757
val modify_maybe_stack : modify_mode
5858

59+
val equal_alloc_mode : alloc_mode -> alloc_mode -> bool
60+
5961
type initialization_or_assignment =
6062
(* [Assignment Alloc_local] is a mutation of a block that may be heap or local.
6163
[Assignment Alloc_heap] is a mutation of a block that's definitely heap. *)
@@ -515,6 +517,7 @@ and lfunction = private
515517
attr: function_attribute; (* specified with [@inline] attribute *)
516518
loc : scoped_location;
517519
mode : alloc_mode; (* alloc mode of the closure itself *)
520+
ret_mode: alloc_mode;
518521
region : bool; (* false if this function may locally
519522
allocate in the caller's region *)
520523
}
@@ -635,6 +638,7 @@ val lfunction :
635638
attr:function_attribute -> (* specified with [@inline] attribute *)
636639
loc:scoped_location ->
637640
mode:alloc_mode ->
641+
ret_mode:alloc_mode ->
638642
region:bool ->
639643
lambda
640644

lambda/printlambda.ml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -807,7 +807,7 @@ let rec lam ppf = function
807807
apply_inlined_attribute ap.ap_inlined
808808
apply_specialised_attribute ap.ap_specialised
809809
apply_probe ap.ap_probe
810-
| Lfunction{kind; params; return; body; attr; mode; region} ->
810+
| Lfunction{kind; params; return; body; attr; ret_mode; mode} ->
811811
let pr_params ppf params =
812812
match kind with
813813
| Curried {nlocal} ->
@@ -830,10 +830,9 @@ let rec lam ppf = function
830830
layout ppf p.layout)
831831
params;
832832
fprintf ppf ")" in
833-
let rmode = if region then alloc_heap else alloc_local in
834833
fprintf ppf "@[<2>(function%s%a@ %a%a%a)@]"
835834
(alloc_kind mode) pr_params params
836-
function_attribute attr return_kind (rmode, return) lam body
835+
function_attribute attr return_kind (ret_mode, return) lam body
837836
| Llet _ | Lmutlet _ as expr ->
838837
let let_kind = begin function
839838
| Llet(str,_,_,_,_) ->

lambda/simplif.ml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -233,8 +233,8 @@ let simplify_exits lam =
233233
| Lapply ap ->
234234
Lapply{ap with ap_func = simplif ~layout:None ~try_depth ap.ap_func;
235235
ap_args = List.map (simplif ~layout:None ~try_depth) ap.ap_args}
236-
| Lfunction{kind; params; return; mode; region; body = l; attr; loc} ->
237-
lfunction ~kind ~params ~return ~mode ~region
236+
| Lfunction{kind; params; return; mode; ret_mode; region; body = l; attr; loc} ->
237+
lfunction ~kind ~params ~return ~mode ~region ~ret_mode
238238
~body:(simplif ~layout:None ~try_depth l) ~attr ~loc
239239
| Llet(str, kind, v, l1, l2) ->
240240
Llet(str, kind, v, simplif ~layout:None ~try_depth l1, simplif ~layout ~try_depth l2)
@@ -556,12 +556,12 @@ let simplify_lets lam =
556556
| _ -> no_opt ()
557557
end
558558
| Lfunction{kind=outer_kind; params; return=outer_return; body = l;
559-
attr; loc; mode; region=outer_region} ->
559+
attr; loc; ret_mode; mode; region=outer_region} ->
560560
begin match outer_kind, outer_region, simplif l with
561561
Curried {nlocal=0},
562562
true,
563563
Lfunction{kind=Curried _ as kind; params=params'; return=return2;
564-
body; attr; loc; mode=inner_mode; region}
564+
body; attr; loc; mode=inner_mode; ret_mode; region}
565565
when optimize &&
566566
List.length params + List.length params' <= Lambda.max_arity() ->
567567
(* The returned function's mode should match the outer return mode *)
@@ -571,9 +571,9 @@ let simplify_lets lam =
571571
type of the merged function taking [params @ params'] as
572572
parameters is the type returned after applying [params']. *)
573573
let return = return2 in
574-
lfunction ~kind ~params:(params @ params') ~return ~body ~attr ~loc ~mode ~region
574+
lfunction ~kind ~params:(params @ params') ~return ~body ~attr ~loc ~mode ~ret_mode ~region
575575
| kind, region, body ->
576-
lfunction ~kind ~params ~return:outer_return ~body ~attr ~loc ~mode ~region
576+
lfunction ~kind ~params ~return:outer_return ~body ~attr ~loc ~mode ~ret_mode ~region
577577
end
578578
| Llet(_str, _k, v, Lvar w, l2) when optimize ->
579579
Hashtbl.add subst v (simplif (Lvar w));
@@ -759,7 +759,7 @@ and list_emit_tail_infos is_tail =
759759
function's body. *)
760760

761761
let split_default_wrapper ~id:fun_id ~kind ~params ~return ~body
762-
~attr ~loc ~mode ~region:orig_region =
762+
~attr ~loc ~mode ~ret_mode ~region:orig_region =
763763
let rec aux map add_region = function
764764
(* When compiling [fun ?(x=expr) -> body], this is first translated
765765
to:
@@ -836,7 +836,7 @@ let split_default_wrapper ~id:fun_id ~kind ~params ~return ~body
836836
let inner_fun =
837837
lfunction ~kind:(Curried {nlocal=0})
838838
~params:new_ids
839-
~return ~body ~attr ~loc ~mode ~region:true
839+
~return ~body ~attr ~loc ~mode ~ret_mode ~region:true
840840
in
841841
(wrapper_body, (inner_id, inner_fun))
842842
in
@@ -849,9 +849,9 @@ let split_default_wrapper ~id:fun_id ~kind ~params ~return ~body
849849
end;
850850
let body, inner = aux [] false body in
851851
let attr = { default_stub_attribute with check = attr.check } in
852-
[(fun_id, lfunction ~kind ~params ~return ~body ~attr ~loc ~mode ~region:true); inner]
852+
[(fun_id, lfunction ~kind ~params ~return ~body ~attr ~loc ~mode ~ret_mode ~region:true); inner]
853853
with Exit ->
854-
[(fun_id, lfunction ~kind ~params ~return ~body ~attr ~loc ~mode ~region:orig_region)]
854+
[(fun_id, lfunction ~kind ~params ~return ~body ~attr ~loc ~mode ~ret_mode ~region:orig_region)]
855855

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

lambda/simplif.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,6 @@ val split_default_wrapper
3838
-> attr:function_attribute
3939
-> loc:Lambda.scoped_location
4040
-> mode:Lambda.alloc_mode
41+
-> ret_mode:Lambda.alloc_mode
4142
-> region:bool
4243
-> (Ident.t * lambda) list

lambda/tmc.ml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -991,9 +991,9 @@ and traverse_binding outer_ctx inner_ctx (var, def) =
991991
(Debuginfo.Scoped_location.to_location lfun.loc)
992992
Warnings.Unused_tmc_attribute;
993993
let direct =
994-
let { kind; params; return; body = _; attr; loc; mode; region } = lfun in
994+
let { kind; params; return; body = _; attr; loc; mode; ret_mode; region } = lfun in
995995
let body = Choice.direct fun_choice in
996-
lfunction ~kind ~params ~return ~body ~attr ~loc ~mode ~region in
996+
lfunction ~kind ~params ~return ~body ~attr ~loc ~mode ~ret_mode ~region in
997997
let dps =
998998
let dst_param = {
999999
var = Ident.create_local "dst";
@@ -1021,6 +1021,7 @@ and traverse_binding outer_ctx inner_ctx (var, def) =
10211021
~attr:lfun.attr
10221022
~loc:lfun.loc
10231023
~mode:lfun.mode
1024+
~ret_mode:lfun.ret_mode
10241025
~region:true
10251026
in
10261027
let dps_var = special.dps_id in

lambda/transl_list_comprehension.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ let rec translate_bindings
259259
~attr:default_function_attribute
260260
~loc
261261
~mode:alloc_local
262+
~ret_mode:alloc_local
262263
~region:false
263264
~body:(add_bindings body)
264265
in

lambda/translattribute.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -361,8 +361,8 @@ let check_poll_local loc attr =
361361
()
362362

363363
let lfunction_with_attr ~attr
364-
{ kind; params; return; body; attr=_; loc; mode; region } =
365-
lfunction ~kind ~params ~return ~body ~attr ~loc ~mode ~region
364+
{ kind; params; return; body; attr=_; loc; mode; ret_mode; region } =
365+
lfunction ~kind ~params ~return ~body ~attr ~loc ~mode ~ret_mode ~region
366366

367367
let add_inline_attribute expr loc attributes =
368368
match expr with

lambda/translclass.ml

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,26 +37,28 @@ let layout_meth = layout_any_value
3737
let layout_tables = Lambda.Pvalue Pgenval
3838

3939

40-
let lfunction ?(kind=Curried {nlocal=0}) ?(region=true) return_layout params body =
40+
let lfunction ?(kind=Curried {nlocal=0}) ?(region=true) ?(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}
45+
body = body'; attr; loc; mode = Alloc_heap; ret_mode; region}
4646
when List.length params + List.length params' <= Lambda.max_arity() ->
4747
lfunction ~kind ~params:(params @ params')
4848
~return:return_layout
4949
~body:body'
5050
~attr
5151
~loc
5252
~mode:alloc_heap
53+
~ret_mode
5354
~region
5455
| _ ->
5556
lfunction ~kind ~params ~return:return_layout
5657
~body
5758
~attr:default_function_attribute
5859
~loc:Loc_unknown
5960
~mode:alloc_heap
61+
~ret_mode
6062
~region
6163

6264
let lapply ap =
@@ -226,6 +228,7 @@ let rec build_object_init ~scopes cl_table obj params inh_init obj_init cl =
226228
~loc:(of_location ~scopes pat.pat_loc)
227229
~body
228230
~mode:alloc_heap
231+
~ret_mode:alloc_heap
229232
~region:true
230233
in
231234
begin match obj_init with
@@ -514,6 +517,7 @@ let rec transl_class_rebind ~scopes obj_init cl vf =
514517
~loc:(of_location ~scopes pat.pat_loc)
515518
~body
516519
~mode:alloc_heap
520+
~ret_mode:alloc_heap
517521
~region:true
518522
in
519523
(path, path_lam,
@@ -792,7 +796,7 @@ let transl_class ~scopes ids cl_id pub_meths cl vflag =
792796
let new_ids_meths = ref [] in
793797
let no_env_update _ _ env = env in
794798
let msubst arr = function
795-
Lfunction {kind = Curried _ as kind; region;
799+
Lfunction {kind = Curried _ as kind; region; ret_mode;
796800
params = self :: args; return; body} ->
797801
let env = Ident.create_local "env" in
798802
let body' =
@@ -804,7 +808,7 @@ let transl_class ~scopes ids cl_id pub_meths cl vflag =
804808
if not arr || !Clflags.debug then raise Not_found;
805809
builtin_meths [self.name] env env2 (lfunction return args body')
806810
with Not_found ->
807-
[lfunction ~kind ~region return (self :: args)
811+
[lfunction ~kind ~region ~ret_mode return (self :: args)
808812
(if not (Ident.Set.mem env (free_variables body')) then body' else
809813
Llet(Alias, layout_block, env,
810814
Lprim(Pfield_computed Reads_vary,
@@ -875,6 +879,7 @@ let transl_class ~scopes ids cl_id pub_meths cl vflag =
875879
~loc:Loc_unknown
876880
~return:layout_function
877881
~mode:alloc_heap
882+
~ret_mode:alloc_heap
878883
~region:true
879884
~params:[lparam cla layout_table] ~body:cl_init) in
880885
Llet(Strict, layout_function, class_init, cl_init, lam (free_variables cl_init))
@@ -900,6 +905,7 @@ let transl_class ~scopes ids cl_id pub_meths cl vflag =
900905
~loc:Loc_unknown
901906
~return:layout_function
902907
~mode:alloc_heap
908+
~ret_mode:alloc_heap
903909
~region:true
904910
~params:[lparam cla layout_table] ~body:cl_init;
905911
lambda_unit; lenvs],
@@ -960,6 +966,7 @@ let transl_class ~scopes ids cl_id pub_meths cl vflag =
960966
~attr:default_function_attribute
961967
~loc:Loc_unknown
962968
~mode:alloc_heap
969+
~ret_mode:alloc_heap
963970
~region:true
964971
~body:(def_ids cla cl_init), lam)
965972
and lcache lam =
@@ -985,6 +992,7 @@ let transl_class ~scopes ids cl_id pub_meths cl vflag =
985992
~attr:default_function_attribute
986993
~loc:Loc_unknown
987994
~mode:alloc_heap
995+
~ret_mode:alloc_heap
988996
~region:true
989997
~return:layout_function
990998
~params:[lparam cla layout_table]

0 commit comments

Comments
 (0)