Skip to content

Commit 969b937

Browse files
authored
flambda-backend: Backend support for local allocations (#478)
Adds local allocations (Ialloc Alloc_local) to the backend, as well as new primitives for region boundaries (Ibeginregion/Iendregion). In Cmm, instead of explicit Ibeginregion/Iendregion, there is a new block-structured Cregion. Since tail calls are supposed to end a region before transferring control, Cmm also has two new constructs that end a region early: Capply with Apply_tail, and Ctail (for general code blocks, resulting from tail calls that have been inlined).
1 parent 2d1e6ef commit 969b937

File tree

11 files changed

+61
-3
lines changed

11 files changed

+61
-3
lines changed

asmcomp/cmm_helpers.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2180,6 +2180,7 @@ let assignment_kind
21802180
(ptr: Lambda.immediate_or_pointer)
21812181
(init: Lambda.initialization_or_assignment) =
21822182
match init, ptr with
2183+
| Local_assignment, _ -> assert false (* temporary *)
21832184
| Assignment, Pointer -> Caml_modify
21842185
| Heap_initialization, Pointer -> Caml_initialize
21852186
| Assignment, Immediate

asmcomp/printcmm.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ let operation d = function
126126
| Lambda.Heap_initialization -> "(heap-init)"
127127
| Lambda.Root_initialization -> "(root-init)"
128128
| Lambda.Assignment -> ""
129+
| Lambda.Local_assignment -> "(local)"
129130
in
130131
Printf.sprintf "store %s%s" (chunk c) init
131132
| Caddi -> "+"

asmcomp/selectgen.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ method select_operation op args _dbg =
456456
match init with
457457
| Lambda.Root_initialization -> false
458458
| Lambda.Heap_initialization -> false
459-
| Lambda.Assignment -> true
459+
| Lambda.Assignment | Lambda.Local_assignment -> true
460460
in
461461
if chunk = Word_int || chunk = Word_val then begin
462462
let (op, newarg2) = self#select_store is_assign addr arg2 in

lambda/lambda.ml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ type immediate_or_pointer =
3434

3535
type initialization_or_assignment =
3636
| Assignment
37+
| Local_assignment
3738
| Heap_initialization
3839
| Root_initialization
3940

@@ -45,6 +46,14 @@ type field_read_semantics =
4546
| Reads_agree
4647
| Reads_vary
4748

49+
type alloc_mode =
50+
| Alloc_heap
51+
| Alloc_local
52+
53+
type region_close =
54+
| Rc_close_at_apply
55+
| Rc_normal
56+
4857
type primitive =
4958
| Pidentity
5059
| Pbytes_to_string
@@ -1005,3 +1014,21 @@ let mod_field ?(read_semantics=Reads_agree) pos =
10051014

10061015
let mod_setfield pos =
10071016
Psetfield (pos, Pointer, Root_initialization)
1017+
1018+
let join_mode a b =
1019+
match a, b with
1020+
| Alloc_local, _ | _, Alloc_local -> Alloc_local
1021+
| Alloc_heap, Alloc_heap -> Alloc_heap
1022+
1023+
let sub_mode a b =
1024+
match a, b with
1025+
| Alloc_heap, _ -> true
1026+
| _, Alloc_local -> true
1027+
| Alloc_local, Alloc_heap -> false
1028+
1029+
let eq_mode a b =
1030+
match a, b with
1031+
| Alloc_heap, Alloc_heap -> true
1032+
| Alloc_local, Alloc_local -> true
1033+
| Alloc_heap, Alloc_local -> false
1034+
| Alloc_local, Alloc_heap -> false

lambda/lambda.mli

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ type immediate_or_pointer =
3636

3737
type initialization_or_assignment =
3838
| Assignment
39+
| Local_assignment (* mutations of blocks that may be locally allocated *)
3940
(* Initialization of in heap values, like [caml_initialize] C primitive. The
4041
field should not have been read before and initialization should happen
4142
only once. *)
@@ -52,6 +53,14 @@ type field_read_semantics =
5253
| Reads_agree
5354
| Reads_vary
5455

56+
type alloc_mode =
57+
| Alloc_heap
58+
| Alloc_local
59+
60+
type region_close =
61+
| Rc_close_at_apply
62+
| Rc_normal
63+
5564
type primitive =
5665
| Pidentity
5766
| Pbytes_to_string
@@ -461,6 +470,10 @@ val max_arity : unit -> int
461470
This is unlimited ([max_int]) for bytecode, but limited
462471
(currently to 126) for native code. *)
463472

473+
val join_mode : alloc_mode -> alloc_mode -> alloc_mode
474+
val sub_mode : alloc_mode -> alloc_mode -> bool
475+
val eq_mode : alloc_mode -> alloc_mode -> bool
476+
464477
(***********************)
465478
(* For static failures *)
466479
(***********************)

lambda/printlambda.ml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ let primitive ppf = function
217217
| Heap_initialization -> "(heap-init)"
218218
| Root_initialization -> "(root-init)"
219219
| Assignment -> ""
220+
| Local_assignment -> "(local)"
220221
in
221222
fprintf ppf "setfield_%s%s %i" instr init n
222223
| Psetfield_computed (ptr, init) ->
@@ -230,6 +231,7 @@ let primitive ppf = function
230231
| Heap_initialization -> "(heap-init)"
231232
| Root_initialization -> "(root-init)"
232233
| Assignment -> ""
234+
| Local_assignment -> "(local)"
233235
in
234236
fprintf ppf "setfield_%s%s_computed" instr init
235237
| Pfloatfield (n, sem) ->
@@ -240,6 +242,7 @@ let primitive ppf = function
240242
| Heap_initialization -> "(heap-init)"
241243
| Root_initialization -> "(root-init)"
242244
| Assignment -> ""
245+
| Local_assignment -> "(local)"
243246
in
244247
fprintf ppf "setfloatfield%s %i" init n
245248
| Pduprecord (rep, size) -> fprintf ppf "duprecord %a %i" record_rep rep size

middle_end/closure/closure.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ let prim_size prim args =
121121
| Psetfield(_f, isptr, init) ->
122122
begin match init with
123123
| Root_initialization -> 1 (* never causes a write barrier hit *)
124-
| Assignment | Heap_initialization ->
124+
| Assignment | Local_assignment | Heap_initialization ->
125125
match isptr with
126126
| Pointer -> 4
127127
| Immediate -> 1

middle_end/flambda/inlining_cost.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ let prim_size (prim : Clambda_primitives.primitive) args =
2626
| Psetfield (_, isptr, init) ->
2727
begin match init with
2828
| Root_initialization -> 1 (* never causes a write barrier hit *)
29-
| Assignment | Heap_initialization ->
29+
| Assignment | Local_assignment | Heap_initialization ->
3030
match isptr with
3131
| Pointer -> 4
3232
| Immediate -> 1

middle_end/printclambda_primitives.ml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ let primitive ppf (prim:Clambda_primitives.primitive) =
7575
| Heap_initialization -> "(heap-init)"
7676
| Root_initialization -> "(root-init)"
7777
| Assignment -> ""
78+
| Local_assignment -> "(local)"
7879
in
7980
fprintf ppf "setfield_%s%s %i" instr init n
8081
| Psetfield_computed (ptr, init) ->
@@ -88,6 +89,7 @@ let primitive ppf (prim:Clambda_primitives.primitive) =
8889
| Heap_initialization -> "(heap-init)"
8990
| Root_initialization -> "(root-init)"
9091
| Assignment -> ""
92+
| Local_assignment -> "(local)"
9193
in
9294
fprintf ppf "setfield_%s%s_computed" instr init
9395
| Pfloatfield n -> fprintf ppf "floatfield %i" n
@@ -97,6 +99,7 @@ let primitive ppf (prim:Clambda_primitives.primitive) =
9799
| Heap_initialization -> "(heap-init)"
98100
| Root_initialization -> "(root-init)"
99101
| Assignment -> ""
102+
| Local_assignment -> "(local)"
100103
in
101104
fprintf ppf "setfloatfield%s %i" init n
102105
| Pduprecord (rep, size) ->

runtime/caml/domain_state.tbl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ DOMAIN_STATE(struct caml_ephe_ref_table*, ephe_ref_table)
3636
DOMAIN_STATE(struct caml_custom_table*, custom_table)
3737
/* See minor_gc.c */
3838

39+
DOMAIN_STATE(struct caml_local_arenas*, local_arenas)
40+
DOMAIN_STATE(intnat, local_sp)
41+
DOMAIN_STATE(void*, local_top)
42+
DOMAIN_STATE(intnat, local_limit)
43+
3944
DOMAIN_STATE(struct mark_stack*, mark_stack)
4045
/* See major_gc.c */
4146

runtime/domain.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ void caml_init_domain ()
5656
Caml_state->external_raise = NULL;
5757
Caml_state->exn_bucket = Val_unit;
5858

59+
Caml_state->local_arenas = NULL;
60+
Caml_state->local_sp = 0;
61+
Caml_state->local_top = NULL;
62+
Caml_state->local_limit = 0;
63+
5964
Caml_state->top_of_stack = NULL;
6065
Caml_state->bottom_of_stack = NULL; /* no stack initially */
6166
Caml_state->last_return_address = 1; /* not in OCaml code initially */

0 commit comments

Comments
 (0)