Skip to content

Commit 8d23c3a

Browse files
committed
Treat Prim_poly primitives as Alloc_heap in Lambda
1 parent 107e86b commit 8d23c3a

File tree

5 files changed

+61
-5
lines changed

5 files changed

+61
-5
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: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ let alloc_mode = function
8888
| Alloc_heap -> ""
8989
| Alloc_local -> "local"
9090

91+
let alloc_mode' = function
92+
| Alloc_heap -> "heap"
93+
| Alloc_local -> "local"
94+
9195
let boxed_integer_name = function
9296
| Pnativeint -> "nativeint"
9397
| Pint32 -> "int32"

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' : alloc_mode -> string

ocaml/lambda/translprim.ml

Lines changed: 32 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,34 @@ 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 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+
if alloc_mode <> alloc_mode' then
1012+
Misc.fatal_errorf "Alloc mode mismatch for:@ %a@ \
1013+
(from to_locality, %s; from primitive_may_allocate, %s)"
1014+
Printlambda.lambda body
1015+
(Printlambda.alloc_mode' alloc_mode)
1016+
(Printlambda.alloc_mode' alloc_mode')
1017+
)
1018+
| _ -> ()
1019+
in
9901020
let region =
991-
match to_locality p.prim_native_repr_res with
1021+
match alloc_mode with
9921022
| Alloc_heap -> true
9931023
| Alloc_local -> false
9941024
in
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
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+
end
14+
15+
let go_m f =
16+
let i = M.bits_of_float f in
17+
assert (i = 4L);
18+
()

0 commit comments

Comments
 (0)