Skip to content

Commit f038173

Browse files
authored
flambda-backend: Support unboxed ints in mixed blocks (#2515)
* start work * Implement support * Broken attempt to type-check these * Fix bugs * Gets off the ground * Generate new test cases * A bad attempt to make the testsuite better * Improve generated test * Self-review * Clean up unnecessary field * Get some layouts tests working * Add some mixed block tests and fix bug * Move unboxed-float relevant mixed block tests back to typing-layouts-float64 directory * Add tests for other kinds of mixed blocks * Flesh out constructor arg tests * Fix upstream build * Mint separate mixed block shape type for flambda2 (#2530) * Ban void in mixed products (#2531) * Flesh out constructor arg tests to have more combos of flat suffixes * Review: fix comments; add case for disallowed value in flat suffix * Fix up both alpha and beta versions of tests according to review * Review: add and clarify comments * Remove stale comment (Max confirmed) * Revert unintended change to test from review response * Disallow big-endian for now * Update comment to clarify why it would be better to use mutability (optimization, not soundness) * make fmt
1 parent 79fdc00 commit f038173

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+7016
-6299
lines changed

lambda/lambda.ml

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -342,11 +342,11 @@ and layout =
342342
and block_shape =
343343
value_kind list option
344344

345-
and flat_element = Types.flat_element = Imm | Float | Float64
345+
and flat_element = Types.flat_element =
346+
Imm | Float | Float64 | Bits32 | Bits64 | Word
346347
and flat_element_read =
347-
| Flat_read_imm
348+
| Flat_read of flat_element (* invariant: not [Float] *)
348349
| Flat_read_float of alloc_mode
349-
| Flat_read_float64
350350
and mixed_block_read =
351351
| Mread_value_prefix of immediate_or_pointer
352352
| Mread_flat_suffix of flat_element_read
@@ -472,13 +472,6 @@ let join_boxed_vector_layout v1 v2 =
472472
match v1, v2 with
473473
| Pvec128 v1, Pvec128 v2 -> Punboxed_vector (Pvec128 (join_vec128_types v1 v2))
474474

475-
let equal_flat_element e1 e2 =
476-
match e1, e2 with
477-
| Imm, Imm -> true
478-
| Float, Float -> true
479-
| Float64, Float64 -> true
480-
| (Imm | Float | Float64), _ -> false
481-
482475
let rec equal_value_kind x y =
483476
match x, y with
484477
| Pgenval, Pgenval -> true
@@ -513,7 +506,7 @@ and equal_constructor_shape x y =
513506
List.length p1 = List.length p2
514507
&& List.for_all2 equal_value_kind p1 p2
515508
&& List.length s1 = List.length s2
516-
&& List.for_all2 equal_flat_element s1 s2
509+
&& List.for_all2 Types.equal_flat_element s1 s2
517510
| (Constructor_uniform _ | Constructor_mixed _), _ -> false
518511

519512
let equal_layout x y =
@@ -1246,15 +1239,20 @@ let transl_prim mod_name name =
12461239
let transl_mixed_product_shape : Types.mixed_product_shape -> mixed_block_shape =
12471240
fun x -> x
12481241

1249-
let count_mixed_block_values_and_floats =
1250-
Types.count_mixed_record_values_and_floats
1251-
12521242
type mixed_block_element = Types.mixed_product_element =
12531243
| Value_prefix
12541244
| Flat_suffix of flat_element
12551245

12561246
let get_mixed_block_element = Types.get_mixed_product_element
12571247

1248+
let flat_read_non_float flat_element =
1249+
match flat_element with
1250+
| Float -> Misc.fatal_error "flat_element_read_non_float Float"
1251+
| Imm | Float64 | Bits32 | Bits64 | Word as flat_element ->
1252+
Flat_read flat_element
1253+
1254+
let flat_read_float alloc_mode = Flat_read_float alloc_mode
1255+
12581256
(* Compile a sequence of expressions *)
12591257

12601258
let rec make_sequence fn = function
@@ -1635,7 +1633,7 @@ let primitive_may_allocate : primitive -> alloc_mode option = function
16351633
match read with
16361634
| Mread_value_prefix _ -> None
16371635
| Mread_flat_suffix (Flat_read_float m) -> Some m
1638-
| Mread_flat_suffix (Flat_read_float64 | Flat_read_imm) -> None
1636+
| Mread_flat_suffix (Flat_read _) -> None
16391637
end
16401638
| Psetfloatfield _ -> None
16411639
| Psetufloatfield _ -> None
@@ -1779,6 +1777,20 @@ let array_ref_kind_result_layout = function
17791777
| Punboxedintarray_ref Pint64 -> layout_unboxed_int64
17801778
| Punboxedintarray_ref Pnativeint -> layout_unboxed_nativeint
17811779

1780+
let layout_of_mixed_field (kind : mixed_block_read) =
1781+
match kind with
1782+
| Mread_value_prefix _ -> layout_value_field
1783+
| Mread_flat_suffix (Flat_read_float (_ : alloc_mode)) ->
1784+
layout_boxed_float Pfloat64
1785+
| Mread_flat_suffix (Flat_read proj) ->
1786+
match proj with
1787+
| Imm -> layout_int
1788+
| Float64 -> layout_unboxed_float Pfloat64
1789+
| Bits32 -> layout_unboxed_int32
1790+
| Bits64 -> layout_unboxed_int64
1791+
| Word -> layout_unboxed_nativeint
1792+
| Float -> layout_boxed_float Pfloat64
1793+
17821794
let primitive_result_layout (p : primitive) =
17831795
assert !Clflags.native_code;
17841796
match p with
@@ -1808,16 +1820,7 @@ let primitive_result_layout (p : primitive) =
18081820
| Pbox_float (f, _) -> layout_boxed_float f
18091821
| Pufloatfield _ -> Punboxed_float Pfloat64
18101822
| Punbox_float float_kind -> Punboxed_float float_kind
1811-
| Pmixedfield (_, kind, _) -> begin
1812-
match kind with
1813-
| Mread_value_prefix _ -> layout_value_field
1814-
| Mread_flat_suffix proj -> begin
1815-
match proj with
1816-
| Flat_read_imm -> layout_int
1817-
| Flat_read_float _ -> layout_boxed_float Pfloat64
1818-
| Flat_read_float64 -> layout_unboxed_float Pfloat64
1819-
end
1820-
end
1823+
| Pmixedfield (_, kind, _) -> layout_of_mixed_field kind
18211824
| Pccall { prim_native_repr_res = _, repr_res } -> layout_of_extern_repr repr_res
18221825
| Praise _ -> layout_bottom
18231826
| Psequor | Psequand | Pnot

lambda/lambda.mli

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -350,11 +350,11 @@ and layout =
350350
and block_shape =
351351
value_kind list option
352352

353-
and flat_element = Types.flat_element = Imm | Float | Float64
354-
and flat_element_read =
355-
| Flat_read_imm
353+
and flat_element = Types.flat_element =
354+
Imm | Float | Float64 | Bits32 | Bits64 | Word
355+
and flat_element_read = private
356+
| Flat_read of flat_element (* invariant: not [Float] *)
356357
| Flat_read_float of alloc_mode
357-
| Flat_read_float64
358358
and mixed_block_read =
359359
| Mread_value_prefix of immediate_or_pointer
360360
| Mread_flat_suffix of flat_element_read
@@ -790,7 +790,6 @@ val transl_extension_path: scoped_location -> Env.t -> Path.t -> lambda
790790
val transl_class_path: scoped_location -> Env.t -> Path.t -> lambda
791791

792792
val transl_mixed_product_shape: Types.mixed_product_shape -> mixed_block_shape
793-
val count_mixed_block_values_and_floats : mixed_block_shape -> int * int
794793

795794
type mixed_block_element =
796795
| Value_prefix
@@ -799,6 +798,10 @@ type mixed_block_element =
799798
(** Raises if the int is out of bounds. *)
800799
val get_mixed_block_element : mixed_block_shape -> int -> mixed_block_element
801800

801+
(** Raises if [flat_element] is float. *)
802+
val flat_read_non_float : flat_element -> flat_element_read
803+
val flat_read_float : alloc_mode -> flat_element_read
804+
802805
val make_sequence: ('a -> lambda) -> 'a list -> lambda
803806

804807
val subst:

lambda/matching.ml

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ module Scoped_location = Debuginfo.Scoped_location
100100

101101
type error =
102102
| Void_layout
103-
| Illegal_record_field of Jkind.const
104103

105104
exception Error of Location.t * error
106105

@@ -112,20 +111,6 @@ let jkind_layout_default_to_value_and_check_not_void loc jkind =
112111
| _ -> ()
113112
;;
114113

115-
(* CR layouts v5: This function is only used for sanity checking the
116-
typechecker. When we allow arbitrary layouts in structures, it will have
117-
outlived its usefulness and should be deleted. *)
118-
let check_record_field_jkind lbl =
119-
match Jkind.(get_default_value lbl.lbl_jkind), lbl.lbl_repres with
120-
| (Value | Immediate | Immediate64 | Non_null_value), _ -> ()
121-
| Float64, (Record_ufloat | Record_mixed _) -> ()
122-
| Float64, (Record_boxed _ | Record_inlined _
123-
| Record_unboxed | Record_float) ->
124-
raise (Error (lbl.lbl_loc, Illegal_record_field Float64))
125-
| (Any | Void | Word | Bits32 | Bits64) as c, _ ->
126-
(* CR layouts v2.1: support unboxed ints here *)
127-
raise (Error (lbl.lbl_loc, Illegal_record_field c))
128-
129114
(*
130115
Compatibility predicate that considers potential rebindings of constructors
131116
of an extension type.
@@ -1824,12 +1809,11 @@ let get_expr_args_constr ~scopes head (arg, _mut, sort, layout) rem =
18241809
| Flat_suffix flat ->
18251810
let flat_read =
18261811
match flat with
1827-
| Imm -> Flat_read_imm
1828-
| Float64 -> Flat_read_float64
18291812
| Float ->
18301813
Misc.fatal_error
18311814
"unexpected flat float of layout value in \
1832-
constructor field"
1815+
constructor field"
1816+
| non_float -> flat_read_non_float non_float
18331817
in
18341818
Mread_flat_suffix flat_read
18351819
in
@@ -2136,7 +2120,7 @@ let record_matching_line num_fields lbl_pat_list =
21362120
List.iter (fun (_, lbl, pat) ->
21372121
(* CR layouts v5: This void sanity check can be removed when we add proper
21382122
void support (or whenever we remove `lbl_pos_void`) *)
2139-
check_record_field_jkind lbl;
2123+
jkind_layout_default_to_value_and_check_not_void pat.pat_loc lbl.lbl_jkind;
21402124
patv.(lbl.lbl_pos) <- pat)
21412125
lbl_pat_list;
21422126
Array.to_list patv
@@ -2163,7 +2147,8 @@ let get_expr_args_record ~scopes head (arg, _mut, sort, layout) rem =
21632147
rem
21642148
else
21652149
let lbl = all_labels.(pos) in
2166-
check_record_field_jkind lbl;
2150+
jkind_layout_default_to_value_and_check_not_void
2151+
head.pat_loc lbl.lbl_jkind;
21672152
let ptr = Typeopt.maybe_pointer_type head.pat_env lbl.lbl_arg in
21682153
let lbl_sort = Jkind.sort_of_jkind lbl.lbl_jkind in
21692154
let lbl_layout = Typeopt.layout_of_sort lbl.lbl_loc lbl_sort in
@@ -2196,11 +2181,11 @@ let get_expr_args_record ~scopes head (arg, _mut, sort, layout) rem =
21962181
else
21972182
let read =
21982183
match flat_suffix.(pos - value_prefix_len) with
2199-
| Imm -> Flat_read_imm
2200-
| Float64 -> Flat_read_float64
2184+
| Imm | Float64 | Bits32 | Bits64 | Word as non_float ->
2185+
flat_read_non_float non_float
22012186
| Float ->
22022187
(* TODO: could optimise to Alloc_local sometimes *)
2203-
Flat_read_float alloc_heap
2188+
flat_read_float alloc_heap
22042189
in
22052190
Mread_flat_suffix read
22062191
in
@@ -4187,11 +4172,6 @@ let report_error ppf = function
41874172
fprintf ppf
41884173
"Void layout detected in translation:@ Please report this error to \
41894174
the Jane Street compilers team."
4190-
| Illegal_record_field c ->
4191-
fprintf ppf
4192-
"Sort %s detected where value was expected in a record field:@ Please \
4193-
report this error to the Jane Street compilers team."
4194-
(Jkind.string_of_const c)
41954175

41964176
let () =
41974177
Location.register_error_of_exn

lambda/printlambda.ml

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -141,10 +141,9 @@ let constructor_shape print_value_kind ppf shape =
141141
| _ :: _ ->
142142
fprintf ppf ";@%a"
143143
(Format.pp_print_list ~pp_sep:(fun ppf () -> fprintf ppf ",@")
144-
(fun ppf -> function
145-
| Imm -> fprintf ppf "[imm]"
146-
| Float -> fprintf ppf "[float]"
147-
| Float64 -> fprintf ppf "[float64]"))
144+
(fun ppf flat_element ->
145+
fprintf ppf "[%s]"
146+
(Types.flat_element_to_lowercase_string flat_element)))
148147
flat_fields)
149148

150149
let tag_and_constructor_shape print_value_kind ppf (tag, shape) =
@@ -317,15 +316,13 @@ let block_shape ppf shape = match shape with
317316
t;
318317
Format.fprintf ppf ")"
319318

320-
let flat_element ppf : flat_element -> unit = function
321-
| Imm -> pp_print_string ppf "int"
322-
| Float -> pp_print_string ppf "float"
323-
| Float64 -> pp_print_string ppf "float64"
319+
let flat_element ppf : flat_element -> unit = fun x ->
320+
pp_print_string ppf (Types.flat_element_to_lowercase_string x)
324321

325322
let flat_element_read ppf : flat_element_read -> unit = function
326-
| Flat_read_imm -> pp_print_string ppf "int"
323+
| Flat_read flat ->
324+
pp_print_string ppf (Types.flat_element_to_lowercase_string flat)
327325
| Flat_read_float m -> fprintf ppf "float[%a]" alloc_mode m
328-
| Flat_read_float64 -> pp_print_string ppf "float64"
329326

330327
let mixed_block_read ppf : mixed_block_read -> unit = function
331328
| Mread_value_prefix Immediate -> pp_print_string ppf "value_int"

0 commit comments

Comments
 (0)