Skip to content

Commit 47a1c23

Browse files
authored
Allow unboxed float32s in mixed blocks (#2550)
1 parent 424a3cd commit 47a1c23

29 files changed

+4604
-2377
lines changed

backend/cmm_helpers.ml

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1287,6 +1287,35 @@ let setfield_unboxed_int64_or_nativeint arr ofs newval dbg =
12871287
[array_indexing log2_size_addr arr ofs dbg; newval],
12881288
dbg ))
12891289

1290+
(* Getters and setters for unboxed float32 fields *)
1291+
1292+
let get_field_unboxed_float32 mutability ~block ~index dbg =
1293+
(* CR layouts v5.1: Properly support big-endian. *)
1294+
if Arch.big_endian
1295+
then
1296+
Misc.fatal_error
1297+
"Unboxed float32 fields only supported on little-endian architectures";
1298+
let memory_chunk = Single { reg = Float32 } in
1299+
(* CR layouts v5.1: We'll need to vary log2_size_addr to efficiently pack
1300+
* float32s *)
1301+
let field_address = array_indexing log2_size_addr block index dbg in
1302+
Cop
1303+
(Cload { memory_chunk; mutability; is_atomic = false }, [field_address], dbg)
1304+
1305+
let setfield_unboxed_float32 arr ofs newval dbg =
1306+
(* CR layouts v5.1: Properly support big-endian. *)
1307+
if Arch.big_endian
1308+
then
1309+
Misc.fatal_error
1310+
"Unboxed float32 fields only supported on little-endian architectures";
1311+
(* CR layouts v5.1: We will need to vary log2_size_addr when float32 fields
1312+
are efficiently packed. *)
1313+
return_unit dbg
1314+
(Cop
1315+
( Cstore (Single { reg = Float32 }, Assignment),
1316+
[array_indexing log2_size_addr arr ofs dbg; newval],
1317+
dbg ))
1318+
12901319
(* String length *)
12911320

12921321
(* Length of string block *)
@@ -1566,12 +1595,13 @@ let make_mixed_alloc ~mode dbg tag shape args =
15661595
match flat_suffix.(idx - value_prefix_len) with
15671596
| Imm -> int_array_set arr ofs newval dbg
15681597
| Float | Float64 -> float_array_set arr ofs newval dbg
1598+
| Float32 -> setfield_unboxed_float32 arr ofs newval dbg
15691599
| Bits32 -> setfield_unboxed_int32 arr ofs newval dbg
15701600
| Bits64 | Word -> setfield_unboxed_int64_or_nativeint arr ofs newval dbg
15711601
in
15721602
let size =
1573-
(* CR layouts 5.1: When we pack int32s more efficiently, this code will need
1574-
to change. *)
1603+
(* CR layouts 5.1: When we pack int32s/float32s more efficiently, this code
1604+
will need to change. *)
15751605
value_prefix_len + Array.length flat_suffix
15761606
in
15771607
if size_float <> size_addr

backend/cmm_helpers.mli

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1006,7 +1006,8 @@ val unboxed_int64_or_nativeint_array_set :
10061006
Debuginfo.t ->
10071007
expression
10081008

1009-
(** {2 Getters and setters for unboxed int fields of mixed blocks} *)
1009+
(** {2 Getters and setters for unboxed int and float32 fields of mixed
1010+
blocks} *)
10101011

10111012
(** The argument structure for getters is parallel to [get_field_computed]. *)
10121013

@@ -1017,6 +1018,13 @@ val get_field_unboxed_int32 :
10171018
Debuginfo.t ->
10181019
expression
10191020

1021+
val get_field_unboxed_float32 :
1022+
Asttypes.mutable_flag ->
1023+
block:expression ->
1024+
index:expression ->
1025+
Debuginfo.t ->
1026+
expression
1027+
10201028
val get_field_unboxed_int64_or_nativeint :
10211029
Asttypes.mutable_flag ->
10221030
block:expression ->
@@ -1032,4 +1040,6 @@ val get_field_unboxed_int64_or_nativeint :
10321040

10331041
val setfield_unboxed_int32 : ternary_primitive
10341042

1043+
val setfield_unboxed_float32 : ternary_primitive
1044+
10351045
val setfield_unboxed_int64_or_nativeint : ternary_primitive

backend/selectgen.ml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,9 @@ let size_component : machtype_component -> int = function
206206
| Int -> Arch.size_int
207207
| Float -> Arch.size_float
208208
| Float32 ->
209-
assert (Arch.size_float = 8);
210-
Arch.size_float / 2
209+
(* CR layouts v5.1: reconsider when float32 fields are efficiently packed.
210+
Note that packed float32# arrays are handled via a separate path. *)
211+
Arch.size_float
211212
| Vec128 -> Arch.size_vec128
212213

213214
let size_machtype mty =
@@ -222,10 +223,11 @@ let size_expr (env:environment) exp =
222223
Cconst_int _ | Cconst_natint _ -> Arch.size_int
223224
| Cconst_symbol _ ->
224225
Arch.size_addr
225-
| Cconst_float32 _ ->
226-
assert (Arch.size_float = 8);
227-
Arch.size_float / 2
228226
| Cconst_float _ -> Arch.size_float
227+
| Cconst_float32 _ ->
228+
(* CR layouts v5.1: reconsider when float32 fields are efficiently packed.
229+
Note that packed float32# arrays are handled via a separate path. *)
230+
Arch.size_float
229231
| Cconst_vec128 _ -> Arch.size_vec128
230232
| Cvar id ->
231233
begin try

middle_end/flambda2/from_lambda/lambda_to_flambda_primitives.ml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -991,8 +991,8 @@ let convert_lprim ~big_endian (prim : L.primitive) (args : Simple.t list list)
991991
List.mapi
992992
(fun i arg ->
993993
match Lambda.get_mixed_block_element shape i with
994-
| Value_prefix | Flat_suffix (Float64 | Imm | Bits32 | Bits64 | Word)
995-
->
994+
| Value_prefix
995+
| Flat_suffix (Float64 | Float32 | Imm | Bits32 | Bits64 | Word) ->
996996
arg
997997
| Flat_suffix Float -> unbox_float arg)
998998
args
@@ -1533,7 +1533,7 @@ let convert_lprim ~big_endian (prim : L.primitive) (args : Simple.t list list)
15331533
let value =
15341534
match write with
15351535
| Mwrite_value_prefix _
1536-
| Mwrite_flat_suffix (Imm | Float64 | Bits32 | Bits64 | Word) ->
1536+
| Mwrite_flat_suffix (Imm | Float64 | Float32 | Bits32 | Bits64 | Word) ->
15371537
value
15381538
| Mwrite_flat_suffix Float -> unbox_float value
15391539
in

middle_end/flambda2/terms/code_size.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,8 @@ let block_set (kind : Flambda_primitive.Block_access_kind.t)
162162
| ( Mixed
163163
{ field_kind =
164164
( Value_prefix _
165-
| Flat_suffix (Imm | Float | Float64 | Bits32 | Bits64 | Word) );
165+
| Flat_suffix
166+
(Imm | Float | Float64 | Float32 | Bits32 | Bits64 | Word) );
166167
_
167168
},
168169
(Assignment _ | Initialization) ) ->

middle_end/flambda2/terms/flambda_primitive.ml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ module Mixed_block_flat_element = struct
6363
| Imm
6464
| Float
6565
| Float64
66+
| Float32
6667
| Bits32
6768
| Bits64
6869
| Word
@@ -71,6 +72,7 @@ module Mixed_block_flat_element = struct
7172
| Imm -> Imm
7273
| Float -> Float
7374
| Float64 -> Float64
75+
| Float32 -> Float32
7476
| Bits32 -> Bits32
7577
| Bits64 -> Bits64
7678
| Word -> Word
@@ -79,6 +81,7 @@ module Mixed_block_flat_element = struct
7981
| Imm -> Imm
8082
| Float -> Float
8183
| Float64 -> Float64
84+
| Float32 -> Float32
8285
| Bits32 -> Bits32
8386
| Bits64 -> Bits64
8487
| Word -> Word
@@ -87,6 +90,7 @@ module Mixed_block_flat_element = struct
8790
| Imm -> "Imm"
8891
| Float -> "Float"
8992
| Float64 -> "Float64"
93+
| Float32 -> "Float32"
9094
| Bits32 -> "Bits32"
9195
| Bits64 -> "Bits64"
9296
| Word -> "Word"
@@ -96,6 +100,7 @@ module Mixed_block_flat_element = struct
96100
| Imm, Imm
97101
| Float, Float
98102
| Float64, Float64
103+
| Float32, Float32
99104
| Word, Word
100105
| Bits32, Bits32
101106
| Bits64, Bits64 ->
@@ -106,6 +111,8 @@ module Mixed_block_flat_element = struct
106111
| _, Float -> 1
107112
| Float64, _ -> -1
108113
| _, Float64 -> 1
114+
| Float32, _ -> -1
115+
| _, Float32 -> 1
109116
| Word, _ -> -1
110117
| _, Word -> 1
111118
| Bits32, _ -> -1
@@ -116,6 +123,7 @@ module Mixed_block_flat_element = struct
116123
let element_kind = function
117124
| Imm -> K.value
118125
| Float | Float64 -> K.naked_float
126+
| Float32 -> K.naked_float32
119127
| Bits32 -> K.naked_int32
120128
| Bits64 -> K.naked_int64
121129
| Word -> K.naked_nativeint
@@ -532,6 +540,7 @@ module Block_access_kind = struct
532540
match field_kind with
533541
| Imm -> K.With_subkind.tagged_immediate
534542
| Float | Float64 -> K.With_subkind.naked_float
543+
| Float32 -> K.With_subkind.naked_float32
535544
| Bits32 -> K.With_subkind.naked_int32
536545
| Bits64 -> K.With_subkind.naked_int64
537546
| Word -> K.With_subkind.naked_nativeint)

middle_end/flambda2/terms/flambda_primitive.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ module Mixed_block_flat_element : sig
6767
| Imm
6868
| Float
6969
| Float64
70+
| Float32
7071
| Bits32
7172
| Bits64
7273
| Word

middle_end/flambda2/to_cmm/to_cmm_primitive.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ let block_load ~dbg (kind : P.Block_access_kind.t) (mutability : Mutability.t)
111111
(* CR layouts v5.1: We should use the mutability here to generate better
112112
code if the load is immutable. *)
113113
C.unboxed_float_array_ref block index dbg
114+
| Float32 -> C.get_field_unboxed_float32 mutability ~block ~index dbg
114115
| Bits32 -> C.get_field_unboxed_int32 mutability ~block ~index dbg
115116
| Bits64 | Word ->
116117
C.get_field_unboxed_int64_or_nativeint mutability ~block ~index dbg)
@@ -132,6 +133,7 @@ let block_set ~dbg (kind : P.Block_access_kind.t) (init : P.Init_or_assign.t)
132133
| Imm ->
133134
C.setfield_computed Immediate init_or_assign block index new_value dbg
134135
| Float | Float64 -> C.float_array_set block index new_value dbg
136+
| Float32 -> C.setfield_unboxed_float32 block index new_value dbg
135137
| Bits32 -> C.setfield_unboxed_int32 block index new_value dbg
136138
| Bits64 | Word ->
137139
C.setfield_unboxed_int64_or_nativeint block index new_value dbg)

ocaml/lambda/lambda.ml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ and block_shape =
343343
value_kind list option
344344

345345
and flat_element = Types.flat_element =
346-
Imm | Float | Float64 | Bits32 | Bits64 | Word
346+
Imm | Float | Float64 | Float32 | Bits32 | Bits64 | Word
347347
and flat_element_read =
348348
| Flat_read of flat_element (* invariant: not [Float] *)
349349
| Flat_read_float of alloc_mode
@@ -1249,7 +1249,7 @@ let get_mixed_block_element = Types.get_mixed_product_element
12491249
let flat_read_non_float flat_element =
12501250
match flat_element with
12511251
| Float -> Misc.fatal_error "flat_element_read_non_float Float"
1252-
| Imm | Float64 | Bits32 | Bits64 | Word as flat_element ->
1252+
| Imm | Float64 | Float32 | Bits32 | Bits64 | Word as flat_element ->
12531253
Flat_read flat_element
12541254

12551255
let flat_read_float alloc_mode = Flat_read_float alloc_mode
@@ -1789,6 +1789,7 @@ let layout_of_mixed_field (kind : mixed_block_read) =
17891789
match proj with
17901790
| Imm -> layout_int
17911791
| Float64 -> layout_unboxed_float Pfloat64
1792+
| Float32 -> layout_unboxed_float Pfloat32
17921793
| Bits32 -> layout_unboxed_int32
17931794
| Bits64 -> layout_unboxed_int64
17941795
| Word -> layout_unboxed_nativeint

ocaml/lambda/lambda.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ and block_shape =
351351
value_kind list option
352352

353353
and flat_element = Types.flat_element =
354-
Imm | Float | Float64 | Bits32 | Bits64 | Word
354+
Imm | Float | Float64 | Float32 | Bits32 | Bits64 | Word
355355
and flat_element_read = private
356356
| Flat_read of flat_element (* invariant: not [Float] *)
357357
| Flat_read_float of alloc_mode

ocaml/lambda/matching.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2183,7 +2183,7 @@ let get_expr_args_record ~scopes head (arg, _mut, sort, layout) rem =
21832183
else
21842184
let read =
21852185
match flat_suffix.(pos - value_prefix_len) with
2186-
| Imm | Float64 | Bits32 | Bits64 | Word as non_float ->
2186+
| Imm | Float64 | Float32 | Bits32 | Bits64 | Word as non_float ->
21872187
flat_read_non_float non_float
21882188
| Float ->
21892189
(* TODO: could optimise to Alloc_local sometimes *)

ocaml/lambda/translcore.ml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,7 @@ let layout_pat sort p = layout p.pat_env p.pat_loc sort p.pat_type
5555

5656
let check_record_field_sort loc sort =
5757
match Jkind.Sort.get_default_value sort with
58-
| Value | Float64 | Bits32 | Bits64 | Word -> ()
59-
| Float32 ->
60-
(* CR mslater: (float32) float32# records *)
61-
Misc.fatal_error "Found unboxed float32 record field."
58+
| Value | Float64 | Float32 | Bits32 | Bits64 | Word -> ()
6259
| Void -> raise (Error (loc, Illegal_void_record_field))
6360

6461
(* Forward declaration -- to be filled in by Translmod.transl_module *)

0 commit comments

Comments
 (0)