Skip to content

Commit 7e17182

Browse files
committed
Treat Prim_poly primitives as Alloc_heap in Lambda (#2190)
(cherry picked from commit 003afd0)
1 parent 107e86b commit 7e17182

File tree

5 files changed

+87
-20
lines changed

5 files changed

+87
-20
lines changed

ocaml/lambda/lambda.ml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1448,16 +1448,19 @@ let alloc_mode_of_primitive_description (p : Primitive.description) =
14481448
if p.prim_alloc then Some alloc_heap else None
14491449
else
14501450
match p.prim_native_repr_res with
1451-
| (Prim_local | Prim_poly), _ ->
1451+
| Prim_local, _ ->
14521452
(* For primitives that might allocate locally, [p.prim_alloc] just says
14531453
whether [caml_c_call] is required, without telling us anything
14541454
about local allocation. (However if [p.prim_alloc = false] we
14551455
do actually know that the primitive does not allocate on the heap.) *)
14561456
Some alloc_local
1457-
| Prim_global, _ ->
1457+
| (Prim_global | Prim_poly), _ ->
14581458
(* For primitives that definitely do not allocate locally,
14591459
[p.prim_alloc = false] actually tells us that the primitive does
1460-
not allocate at all. *)
1460+
not allocate at all.
1461+
1462+
No external call that is [Prim_poly] may allocate locally.
1463+
*)
14611464
if p.prim_alloc then Some alloc_heap else None
14621465

14631466
(* Changes to this function may also require changes in Flambda 2 (e.g.

ocaml/lambda/printlambda.ml

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,15 @@ let array_set_kind ppf k =
8484
| Pintarray_set -> fprintf ppf "int"
8585
| Pfloatarray_set -> fprintf ppf "float"
8686

87-
let alloc_mode = function
87+
let alloc_mode_if_local = function
8888
| Alloc_heap -> ""
8989
| Alloc_local -> "local"
9090

91+
let alloc_mode ppf alloc_mode =
92+
match alloc_mode with
93+
| Alloc_heap -> fprintf ppf "heap"
94+
| Alloc_local -> fprintf ppf "local"
95+
9196
let boxed_integer_name = function
9297
| Pnativeint -> "nativeint"
9398
| Pint32 -> "int32"
@@ -143,7 +148,7 @@ let rec layout is_top ppf layout_ =
143148
let layout ppf layout_ = layout true ppf layout_
144149

145150
let return_kind ppf (mode, kind) =
146-
let smode = alloc_mode mode in
151+
let smode = alloc_mode_if_local mode in
147152
match kind with
148153
| Pvalue Pgenval when is_heap_mode mode -> ()
149154
| Pvalue Pgenval -> fprintf ppf ": %s@ " smode
@@ -275,31 +280,31 @@ let primitive ppf = function
275280
| Pgetpredef id -> fprintf ppf "getpredef %a!" Ident.print id
276281
| Pmakeblock(tag, Immutable, shape, mode) ->
277282
fprintf ppf "make%sblock %i%a"
278-
(alloc_mode mode) tag block_shape shape
283+
(alloc_mode_if_local mode) tag block_shape shape
279284
| Pmakeblock(tag, Immutable_unique, shape, mode) ->
280285
fprintf ppf "make%sblock_unique %i%a"
281-
(alloc_mode mode) tag block_shape shape
286+
(alloc_mode_if_local mode) tag block_shape shape
282287
| Pmakeblock(tag, Mutable, shape, mode) ->
283288
fprintf ppf "make%smutable %i%a"
284-
(alloc_mode mode) tag block_shape shape
289+
(alloc_mode_if_local mode) tag block_shape shape
285290
| Pmakefloatblock (Immutable, mode) ->
286291
fprintf ppf "make%sfloatblock Immutable"
287-
(alloc_mode mode)
292+
(alloc_mode_if_local mode)
288293
| Pmakefloatblock (Immutable_unique, mode) ->
289294
fprintf ppf "make%sfloatblock Immutable_unique"
290-
(alloc_mode mode)
295+
(alloc_mode_if_local mode)
291296
| Pmakefloatblock (Mutable, mode) ->
292297
fprintf ppf "make%sfloatblock Mutable"
293-
(alloc_mode mode)
298+
(alloc_mode_if_local mode)
294299
| Pmakeufloatblock (Immutable, mode) ->
295300
fprintf ppf "make%sufloatblock Immutable"
296-
(alloc_mode mode)
301+
(alloc_mode_if_local mode)
297302
| Pmakeufloatblock (Immutable_unique, mode) ->
298303
fprintf ppf "make%sufloatblock Immutable_unique"
299-
(alloc_mode mode)
304+
(alloc_mode_if_local mode)
300305
| Pmakeufloatblock (Mutable, mode) ->
301306
fprintf ppf "make%sufloatblock Mutable"
302-
(alloc_mode mode)
307+
(alloc_mode_if_local mode)
303308
| Pfield (n, ptr, sem) ->
304309
let instr =
305310
match ptr, sem with
@@ -340,7 +345,7 @@ let primitive ppf = function
340345
fprintf ppf "setfield_%s%s_computed" instr init
341346
| Pfloatfield (n, sem, mode) ->
342347
fprintf ppf "floatfield%a%s %i"
343-
field_read_semantics sem (alloc_mode mode) n
348+
field_read_semantics sem (alloc_mode_if_local mode) n
344349
| Pufloatfield (n, sem) ->
345350
fprintf ppf "ufloatfield%a %i"
346351
field_read_semantics sem n
@@ -419,11 +424,12 @@ let primitive ppf = function
419424

420425
| Parraylength k -> fprintf ppf "array.length[%s]" (array_kind k)
421426
| Pmakearray (k, Mutable, mode) ->
422-
fprintf ppf "make%sarray[%s]" (alloc_mode mode) (array_kind k)
427+
fprintf ppf "make%sarray[%s]" (alloc_mode_if_local mode) (array_kind k)
423428
| Pmakearray (k, Immutable, mode) ->
424-
fprintf ppf "make%sarray_imm[%s]" (alloc_mode mode) (array_kind k)
429+
fprintf ppf "make%sarray_imm[%s]" (alloc_mode_if_local mode) (array_kind k)
425430
| Pmakearray (k, Immutable_unique, mode) ->
426-
fprintf ppf "make%sarray_unique[%s]" (alloc_mode mode) (array_kind k)
431+
fprintf ppf "make%sarray_unique[%s]" (alloc_mode_if_local mode)
432+
(array_kind k)
427433
| Pduparray (k, Mutable) -> fprintf ppf "duparray[%s]" (array_kind k)
428434
| Pduparray (k, Immutable) -> fprintf ppf "duparray_imm[%s]" (array_kind k)
429435
| Pduparray (k, Immutable_unique) ->

ocaml/lambda/printlambda.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,4 @@ val print_bigarray :
3636
string -> bool -> Lambda.bigarray_kind -> formatter ->
3737
Lambda.bigarray_layout -> unit
3838
val check_attribute : formatter -> check_attribute -> unit
39+
val alloc_mode : formatter -> alloc_mode -> unit

ocaml/lambda/translprim.ml

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -915,7 +915,11 @@ let lambda_of_prim prim_name prim loc args arg_exps =
915915
let check_primitive_arity loc p =
916916
let mode =
917917
match p.prim_native_repr_res with
918-
| Prim_global, _ | Prim_poly, _ -> Some Mode.Locality.global
918+
| Prim_global, _ | Prim_poly, _ ->
919+
(* We assume all primitives are compiled to have the same arity for
920+
different modes and types, so just pick one of the modes in the
921+
[Prim_poly] case. *)
922+
Some Mode.Locality.global
919923
| Prim_local, _ -> Some Mode.Locality.local
920924
in
921925
let prim = lookup_primitive loc mode Rc_normal p in
@@ -987,8 +991,42 @@ let transl_primitive loc p env ty ~poly_mode path =
987991
loc
988992
in
989993
let body = lambda_of_prim p.prim_name prim loc args None in
994+
let alloc_mode = to_locality p.prim_native_repr_res in
995+
let () =
996+
(* CR mshinwell: Write a version of [primitive_may_allocate] that
997+
works on the [prim] type. *)
998+
match body with
999+
| Lprim (prim, _, _) ->
1000+
(match Lambda.primitive_may_allocate prim with
1001+
| None ->
1002+
(* We don't check anything in this case; if the primitive doesn't
1003+
allocate, then after [Lambda] it will be translated to a term
1004+
not involving any region variables, meaning there would be
1005+
no concern about potentially unbound region variables. *)
1006+
()
1007+
| Some lambda_alloc_mode ->
1008+
(* In this case we add a check to ensure the middle end has
1009+
the correct information as to whether a region was inserted
1010+
at this point. *)
1011+
match alloc_mode, lambda_alloc_mode with
1012+
| Alloc_heap, Alloc_heap
1013+
| Alloc_local, Alloc_local -> ()
1014+
| Alloc_local, Alloc_heap ->
1015+
(* This case is ok: the Lambda-derived information is more
1016+
precise. A region will be inserted, likely unused, and
1017+
deleted by the middle end. *)
1018+
()
1019+
| Alloc_heap, Alloc_local ->
1020+
Misc.fatal_errorf "Alloc mode incompatibility for:@ %a@ \
1021+
(from to_locality, %a; from primitive_may_allocate, %a)"
1022+
Printlambda.lambda body
1023+
Printlambda.alloc_mode alloc_mode
1024+
Printlambda.alloc_mode lambda_alloc_mode
1025+
)
1026+
| _ -> ()
1027+
in
9901028
let region =
991-
match to_locality p.prim_native_repr_res with
1029+
match alloc_mode with
9921030
| Alloc_heap -> true
9931031
| Alloc_local -> false
9941032
in
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
(* TEST
2+
* flambda2
3+
** native
4+
*)
5+
6+
module M : sig
7+
val bits_of_float : float -> int64
8+
end = struct
9+
external bits_of_float
10+
: (float[@local_opt])
11+
-> (int64[@local_opt])
12+
= "caml_int64_bits_of_float" "caml_int64_bits_of_float_unboxed"
13+
[@@unboxed] [@@noalloc]
14+
end
15+
16+
let go_m f =
17+
let i = M.bits_of_float f in
18+
assert (i = 4L);
19+
()

0 commit comments

Comments
 (0)