Skip to content

Commit b9b9ae2

Browse files
Gburymshinwellalanechang
authored
flambda-backend: Middle and backend support for arrays of unboxed numbers (rebased) (#2185)
Co-authored-by: Mark Shinwell <[email protected]> Co-authored-by: alanechang <[email protected]>
1 parent 069fa80 commit b9b9ae2

22 files changed

+443
-25
lines changed

asmcomp/cmm_helpers.ml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2509,6 +2509,8 @@ let arraylength kind arg dbg =
25092509
Cop(Cor, [addr_array_length_shifted hdr dbg; Cconst_int (1, dbg)], dbg)
25102510
| Pfloatarray ->
25112511
Cop(Cor, [float_array_length_shifted hdr dbg; Cconst_int (1, dbg)], dbg)
2512+
| Punboxedfloatarray | Punboxedintarray _ ->
2513+
Misc.fatal_errorf "Unboxed arrays not supported"
25122514

25132515
let bbswap bi arg dbg =
25142516
let prim, tyarg = match (bi : Primitive.boxed_integer) with
@@ -2699,6 +2701,8 @@ let arrayref_unsafe rkind arg1 arg2 dbg =
26992701
int_array_ref arg1 arg2 dbg
27002702
| Pfloatarray_ref mode ->
27012703
float_array_ref mode arg1 arg2 dbg
2704+
| Punboxedfloatarray_ref | Punboxedintarray_ref _ ->
2705+
Misc.fatal_errorf "Unboxed arrays not supported"
27022706

27032707
let arrayref_safe rkind arg1 arg2 dbg =
27042708
match (rkind : Lambda.array_ref_kind) with
@@ -2752,6 +2756,8 @@ let arrayref_safe rkind arg1 arg2 dbg =
27522756
(get_header_masked arr dbg) dbg;
27532757
idx],
27542758
unboxed_float_array_ref arr idx dbg))))
2759+
| Punboxedfloatarray_ref | Punboxedintarray_ref _ ->
2760+
Misc.fatal_errorf "Unboxed arrays not supported"
27552761

27562762
type ternary_primitive =
27572763
expression -> expression -> expression -> Debuginfo.t -> expression
@@ -2802,6 +2808,8 @@ let arrayset_unsafe skind arg1 arg2 arg3 dbg =
28022808
int_array_set arg1 arg2 arg3 dbg
28032809
| Pfloatarray_set ->
28042810
float_array_set arg1 arg2 arg3 dbg
2811+
| Punboxedfloatarray_set | Punboxedintarray_set _ ->
2812+
Misc.fatal_errorf "Unboxed arrays not supported"
28052813
)
28062814

28072815
let arrayset_safe skind arg1 arg2 arg3 dbg =
@@ -2865,6 +2873,8 @@ let arrayset_safe skind arg1 arg2 arg3 dbg =
28652873
(get_header_masked arr dbg) dbg;
28662874
idx],
28672875
float_array_set arr idx newval dbg))))
2876+
| Punboxedfloatarray_set | Punboxedintarray_set _ ->
2877+
Misc.fatal_errorf "Unboxed arrays not supported"
28682878
)
28692879

28702880
let bytes_set size unsafe arg1 arg2 arg3 dbg =

asmcomp/cmmgen.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -873,6 +873,8 @@ and transl_make_array dbg env kind mode args =
873873
| Pfloatarray ->
874874
make_float_alloc ~mode dbg Obj.double_array_tag
875875
(List.map (transl_unbox_float dbg env) args)
876+
| Punboxedfloatarray | Punboxedintarray _ ->
877+
Misc.fatal_errorf "Unboxed arrays not supported"
876878

877879
and transl_ccall env prim args dbg =
878880
let transl_arg native_repr arg =

bytecomp/bytegen.ml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,16 +492,28 @@ let comp_primitive stack_info p sz args =
492492
| Parrayrefs (Pfloatarray_ref _) -> Kccall("caml_floatarray_get", 2)
493493
| Parrayrefs (Paddrarray_ref | Pintarray_ref) ->
494494
Kccall("caml_array_get_addr", 2)
495+
| Parrayrefs (Punboxedfloatarray_ref | Punboxedintarray_ref _) ->
496+
Misc.fatal_errorf "Cannot use primitive %a for unboxed arrays in bytecode"
497+
Printlambda.primitive p
495498
| Parraysets (Pgenarray_set _) -> Kccall("caml_array_set", 3)
496499
| Parraysets Pfloatarray_set -> Kccall("caml_floatarray_set", 3)
497500
| Parraysets (Paddrarray_set _ | Pintarray_set) ->
498501
Kccall("caml_array_set_addr", 3)
502+
| Parraysets (Punboxedfloatarray_set | Punboxedintarray_set _) ->
503+
Misc.fatal_errorf "Cannot use primitive %a for unboxed arrays in bytecode"
504+
Printlambda.primitive p
499505
| Parrayrefu (Pgenarray_ref _) -> Kccall("caml_array_unsafe_get", 2)
500506
| Parrayrefu (Pfloatarray_ref _) -> Kccall("caml_floatarray_unsafe_get", 2)
501507
| Parrayrefu (Paddrarray_ref | Pintarray_ref) -> Kgetvectitem
508+
| Parrayrefu (Punboxedfloatarray_ref | Punboxedintarray_ref _) ->
509+
Misc.fatal_errorf "Cannot use primitive %a for unboxed arrays in bytecode"
510+
Printlambda.primitive p
502511
| Parraysetu (Pgenarray_set _) -> Kccall("caml_array_unsafe_set", 3)
503512
| Parraysetu Pfloatarray_set -> Kccall("caml_floatarray_unsafe_set", 3)
504513
| Parraysetu (Paddrarray_set _ | Pintarray_set) -> Ksetvectitem
514+
| Parraysetu (Punboxedfloatarray_set | Punboxedintarray_set _) ->
515+
Misc.fatal_errorf "Cannot use primitive %a for unboxed arrays in bytecode"
516+
Printlambda.primitive p
505517
| Pctconst c ->
506518
let const_name = match c with
507519
| Big_endian -> "big_endian"
@@ -826,7 +838,7 @@ let rec comp_expr stack_info env exp sz cont =
826838
let cont = add_pseudo_event loc !compunit_name cont in
827839
comp_args stack_info env args sz
828840
(Kmakefloatblock (List.length args) :: cont)
829-
| Lprim(Pmakearray (kind, _, _), args, loc) ->
841+
| Lprim((Pmakearray (kind, _, _)) as p, args, loc) ->
830842
let cont = add_pseudo_event loc !compunit_name cont in
831843
begin match kind with
832844
Pintarray | Paddrarray ->
@@ -841,6 +853,10 @@ let rec comp_expr stack_info env exp sz cont =
841853
else comp_args stack_info env args sz
842854
(Kmakeblock(List.length args, 0) ::
843855
Kccall("caml_make_array", 1) :: cont)
856+
| Punboxedfloatarray | Punboxedintarray _ ->
857+
Misc.fatal_errorf
858+
"Cannot use Pmakeblock for unboxed arrays in bytecode"
859+
Printlambda.primitive p
844860
end
845861
| Lprim((Presume|Prunstack), args, _) ->
846862
let nargs = List.length args - 1 in

lambda/lambda.ml

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,18 +305,24 @@ and block_shape =
305305

306306
and array_kind =
307307
Pgenarray | Paddrarray | Pintarray | Pfloatarray
308+
| Punboxedfloatarray
309+
| Punboxedintarray of unboxed_integer
308310

309311
and array_ref_kind =
310312
| Pgenarray_ref of alloc_mode
311313
| Paddrarray_ref
312314
| Pintarray_ref
313315
| Pfloatarray_ref of alloc_mode
316+
| Punboxedfloatarray_ref
317+
| Punboxedintarray_ref of unboxed_integer
314318

315319
and array_set_kind =
316320
| Pgenarray_set of modify_mode
317321
| Paddrarray_set of modify_mode
318322
| Pintarray_set
319323
| Pfloatarray_set
324+
| Punboxedfloatarray_set
325+
| Punboxedintarray_set of unboxed_integer
320326

321327
and boxed_integer = Primitive.boxed_integer =
322328
Pnativeint | Pint32 | Pint64
@@ -1517,8 +1523,10 @@ let primitive_may_allocate : primitive -> alloc_mode option = function
15171523
| Pduparray _ -> Some alloc_heap
15181524
| Parraylength _ -> None
15191525
| Parraysetu _ | Parraysets _
1520-
| Parrayrefu (Paddrarray_ref | Pintarray_ref)
1521-
| Parrayrefs (Paddrarray_ref | Pintarray_ref) -> None
1526+
| Parrayrefu (Paddrarray_ref | Pintarray_ref
1527+
| Punboxedfloatarray_ref | Punboxedintarray_ref _)
1528+
| Parrayrefs (Paddrarray_ref | Pintarray_ref
1529+
| Punboxedfloatarray_ref | Punboxedintarray_ref _) -> None
15221530
| Parrayrefu (Pgenarray_ref m | Pfloatarray_ref m)
15231531
| Parrayrefs (Pgenarray_ref m | Pfloatarray_ref m) -> Some m
15241532
| Pisint _ | Pisout -> None
@@ -1606,7 +1614,11 @@ let layout_of_native_repr : Primitive.native_repr -> _ = function
16061614
let array_ref_kind_result_layout = function
16071615
| Pintarray_ref -> layout_int
16081616
| Pfloatarray_ref _ -> layout_boxed_float
1617+
| Punboxedfloatarray_ref -> layout_unboxed_float
16091618
| Pgenarray_ref _ | Paddrarray_ref -> layout_field
1619+
| Punboxedintarray_ref Pint32 -> layout_unboxed_int32
1620+
| Punboxedintarray_ref Pint64 -> layout_unboxed_int64
1621+
| Punboxedintarray_ref Pnativeint -> layout_unboxed_nativeint
16101622

16111623
let primitive_result_layout (p : primitive) =
16121624
assert !Clflags.native_code;
@@ -1741,12 +1753,16 @@ let array_ref_kind mode = function
17411753
| Paddrarray -> Paddrarray_ref
17421754
| Pintarray -> Pintarray_ref
17431755
| Pfloatarray -> Pfloatarray_ref mode
1756+
| Punboxedintarray int_kind -> Punboxedintarray_ref int_kind
1757+
| Punboxedfloatarray -> Punboxedfloatarray_ref
17441758

17451759
let array_set_kind mode = function
17461760
| Pgenarray -> Pgenarray_set mode
17471761
| Paddrarray -> Paddrarray_set mode
17481762
| Pintarray -> Pintarray_set
17491763
| Pfloatarray -> Pfloatarray_set
1764+
| Punboxedintarray int_kind -> Punboxedintarray_set int_kind
1765+
| Punboxedfloatarray -> Punboxedfloatarray_set
17501766

17511767
let is_check_enabled ~opt property =
17521768
match property with

lambda/lambda.mli

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,8 @@ and float_comparison =
252252

253253
and array_kind =
254254
Pgenarray | Paddrarray | Pintarray | Pfloatarray
255+
| Punboxedfloatarray
256+
| Punboxedintarray of unboxed_integer
255257

256258
(** When accessing a flat float array, we need to know the mode which we should
257259
box the resulting float at. *)
@@ -260,6 +262,8 @@ and array_ref_kind =
260262
| Paddrarray_ref
261263
| Pintarray_ref
262264
| Pfloatarray_ref of alloc_mode
265+
| Punboxedfloatarray_ref
266+
| Punboxedintarray_ref of unboxed_integer
263267

264268
(** When updating an array that might contain pointers, we need to know what
265269
mode they're at; otherwise, access is uniform. *)
@@ -268,6 +272,8 @@ and array_set_kind =
268272
| Paddrarray_set of modify_mode
269273
| Pintarray_set
270274
| Pfloatarray_set
275+
| Punboxedfloatarray_set
276+
| Punboxedintarray_set of unboxed_integer
271277

272278
and value_kind =
273279
Pgenval | Pfloatval | Pboxedintval of boxed_integer | Pintval

lambda/printlambda.ml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ let array_kind = function
6060
| Paddrarray -> "addr"
6161
| Pintarray -> "int"
6262
| Pfloatarray -> "float"
63+
| Punboxedfloatarray -> "unboxed_float"
64+
| Punboxedintarray Pint32 -> "unboxed_int32"
65+
| Punboxedintarray Pint64 -> "unboxed_int64"
66+
| Punboxedintarray Pnativeint -> "unboxed_nativeint"
6367

6468
let array_ref_kind ppf k =
6569
let pp_mode ppf = function
@@ -71,6 +75,10 @@ let array_ref_kind ppf k =
7175
| Paddrarray_ref -> fprintf ppf "addr"
7276
| Pintarray_ref -> fprintf ppf "int"
7377
| Pfloatarray_ref mode -> fprintf ppf "float%a" pp_mode mode
78+
| Punboxedfloatarray_ref -> fprintf ppf "unboxed_float"
79+
| Punboxedintarray_ref Pint32 -> fprintf ppf "unboxed_int32"
80+
| Punboxedintarray_ref Pint64 -> fprintf ppf "unboxed_int64"
81+
| Punboxedintarray_ref Pnativeint -> fprintf ppf "unboxed_nativeint"
7482

7583
let array_set_kind ppf k =
7684
let pp_mode ppf = function
@@ -82,6 +90,10 @@ let array_set_kind ppf k =
8290
| Paddrarray_set mode -> fprintf ppf "addr%a" pp_mode mode
8391
| Pintarray_set -> fprintf ppf "int"
8492
| Pfloatarray_set -> fprintf ppf "float"
93+
| Punboxedfloatarray_set -> fprintf ppf "unboxed_float"
94+
| Punboxedintarray_set Pint32 -> fprintf ppf "unboxed_int32"
95+
| Punboxedintarray_set Pint64 -> fprintf ppf "unboxed_int64"
96+
| Punboxedintarray_set Pnativeint -> fprintf ppf "unboxed_nativeint"
8597

8698
let alloc_mode_if_local = function
8799
| Alloc_heap -> ""

lambda/printlambda.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,4 @@ val print_bigarray :
3737
Lambda.bigarray_layout -> unit
3838
val check_attribute : formatter -> check_attribute -> unit
3939
val alloc_mode : formatter -> alloc_mode -> unit
40+
val array_kind : array_kind -> string

lambda/transl_array_comprehension.ml

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,7 @@ let clause ~transl_exp ~scopes ~loc = function
565565
([Fixed_size]); otherwise, we cannot ([Dynamic_size]), and we have to
566566
dynamically grow the array as we iterate and shrink it to size at the
567567
end. *)
568+
568569
type array_sizing =
569570
| Fixed_size
570571
| Dynamic_size
@@ -696,13 +697,30 @@ let initial_array ~loc ~array_kind ~array_size ~array_sizing =
696697
| Fixed_size, (Pintarray | Paddrarray) ->
697698
Immutable StrictOpt,
698699
make_vect ~loc ~length:array_size.var ~init:(int 0)
699-
| Fixed_size, Pfloatarray ->
700+
| Fixed_size, (Pfloatarray | Punboxedfloatarray) ->
701+
(* The representations of these two are the same, it's only
702+
accesses that differ. *)
700703
Immutable StrictOpt, make_float_vect ~loc array_size.var
704+
| Fixed_size , Punboxedintarray Pint32 ->
705+
Immutable StrictOpt, make_unboxed_int32_vect ~loc array_size.var
706+
| Fixed_size, Punboxedintarray Pint64 ->
707+
Immutable StrictOpt, make_unboxed_int64_vect ~loc array_size.var
708+
| Fixed_size, Punboxedintarray Pnativeint ->
709+
Immutable StrictOpt, make_unboxed_nativeint_vect ~loc array_size.var
701710
(* Case 3: Unknown size, known array kind *)
702711
| Dynamic_size, (Pintarray | Paddrarray) ->
703712
Mutable, Resizable_array.make ~loc array_kind (int 0)
704713
| Dynamic_size, Pfloatarray ->
705714
Mutable, Resizable_array.make ~loc array_kind (float 0.)
715+
| Dynamic_size, Punboxedfloatarray ->
716+
Mutable, Resizable_array.make ~loc array_kind (unboxed_float 0.)
717+
| Dynamic_size, Punboxedintarray Pint32 ->
718+
Mutable, Resizable_array.make ~loc array_kind (unboxed_int32 0l)
719+
| Dynamic_size, Punboxedintarray Pint64 ->
720+
Mutable, Resizable_array.make ~loc array_kind (unboxed_int64 0L)
721+
| Dynamic_size, Punboxedintarray Pnativeint ->
722+
Mutable, Resizable_array.make ~loc array_kind
723+
(unboxed_nativeint Targetint.zero)
706724
in
707725
Let_binding.make array_let_kind (Pvalue Pgenval) "array" array_value
708726

@@ -790,15 +808,30 @@ let body
790808
Lassign(array.id, make_array),
791809
set_element_in_bounds elt.var,
792810
(Pvalue Pintval) (* [unit] is immediate *)))
793-
| Pintarray | Paddrarray | Pfloatarray ->
811+
| Pintarray | Paddrarray | Pfloatarray | Punboxedfloatarray
812+
| Punboxedintarray _ ->
794813
set_element_in_bounds body
795814
in
796815
Lsequence(
797816
set_element_known_kind_in_bounds,
798817
Lassign(index.id, index.var + l1))
799818

800819
let comprehension
801-
~transl_exp ~scopes ~loc ~array_kind { comp_body; comp_clauses } =
820+
~transl_exp ~scopes ~loc ~(array_kind : Lambda.array_kind)
821+
{ comp_body; comp_clauses } =
822+
(match array_kind with
823+
| Pgenarray | Paddrarray | Pintarray | Pfloatarray -> ()
824+
| Punboxedfloatarray | Punboxedintarray _ ->
825+
if not !Clflags.native_code then
826+
Misc.fatal_errorf
827+
"Array comprehensions for kind %s are not allowed in bytecode"
828+
(Printlambda.array_kind array_kind);
829+
if Targetint.size <> 64 then
830+
Misc.fatal_errorf
831+
"Array comprehensions for kind %s can only be compiled for \
832+
64-bit native targets"
833+
(Printlambda.array_kind array_kind)
834+
);
802835
let { array_sizing_info; array_size; make_comprehension } =
803836
clauses ~transl_exp ~scopes ~loc comp_clauses
804837
in

lambda/transl_comprehension_utils.ml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,16 @@ module Lambda_utils = struct
3636

3737
let float f = Lconst (Const_base (Const_float (Float.to_string f)))
3838

39+
let unboxed_float f =
40+
Lconst (Const_base (Const_unboxed_float (Float.to_string f)))
41+
42+
let unboxed_int32 i = Lconst (Const_base (Const_unboxed_int32 i))
43+
let unboxed_int64 i = Lconst (Const_base (Const_unboxed_int64 i))
44+
let unboxed_nativeint i =
45+
(* See CR in typedtree.mli *)
46+
let i = i |> Targetint.to_int64 |> Int64.to_nativeint in
47+
Lconst (Const_base (Const_unboxed_nativeint i))
48+
3949
let string ~loc s = Lconst (Const_base (Const_string(s, loc, None)))
4050
end
4151

@@ -140,6 +150,12 @@ module Lambda_utils = struct
140150

141151
let make_float_vect = unary "caml_make_float_vect"
142152

153+
let make_unboxed_int32_vect = unary "caml_make_unboxed_int32_vect"
154+
155+
let make_unboxed_int64_vect = unary "caml_make_unboxed_int64_vect"
156+
157+
let make_unboxed_nativeint_vect = unary "caml_make_unboxed_nativeint_vect"
158+
143159
let array_append = binary "caml_array_append"
144160

145161
let array_sub =

lambda/transl_comprehension_utils.mli

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@ module Lambda_utils : sig
5757
[Float.to_string] *)
5858
val float : float -> lambda
5959

60+
(** Unboxed floats and ints *)
61+
val unboxed_float : float -> lambda
62+
val unboxed_int32 : Int32.t -> lambda
63+
val unboxed_int64 : Int64.t -> lambda
64+
val unboxed_nativeint : Targetint.t -> lambda
65+
6066
(** Lambda string literals; these require a location, and are constructed as
6167
"quoted strings", not {fancy|delimited strings|fancy}. *)
6268
val string : loc:Location.t -> string -> lambda
@@ -118,6 +124,15 @@ module Lambda_utils : sig
118124
uninitialized *)
119125
val make_float_vect : loc:scoped_location -> lambda -> lambda
120126

127+
(** Like [make_float_vect] but for unboxed int32 arrays. *)
128+
val make_unboxed_int32_vect : loc:scoped_location -> lambda -> lambda
129+
130+
(** Like [make_float_vect] but for unboxed int64 arrays. *)
131+
val make_unboxed_int64_vect : loc:scoped_location -> lambda -> lambda
132+
133+
(** Like [make_float_vect] but for unboxed nativeint arrays. *)
134+
val make_unboxed_nativeint_vect : loc:scoped_location -> lambda -> lambda
135+
121136
(** [array_append a1 a2] calls the [caml_array_append] C primitive, which
122137
creates a new array by appending [a1] and [a2] *)
123138
val array_append : loc:scoped_location -> lambda -> lambda -> lambda

lambda/translcore.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,8 @@ and transl_exp0 ~in_new_scope ~scopes sort e =
643643
Lconst(Const_float_array(List.map extract_float cl))
644644
| Pgenarray ->
645645
raise Not_constant (* can this really happen? *)
646+
| Punboxedfloatarray | Punboxedintarray _ ->
647+
Misc.fatal_error "Use flambda2 for unboxed arrays"
646648
in
647649
match amut with
648650
| Mutable -> duparray_to_mutable const

0 commit comments

Comments
 (0)