Skip to content

Commit 2f5d60b

Browse files
committed
unified unboxed field getters/setters. This will be useful once we have unboxed integers of different sizes
1 parent 6a83bba commit 2f5d60b

File tree

1 file changed

+50
-150
lines changed

1 file changed

+50
-150
lines changed

backend/cmm_helpers.ml

+50-150
Original file line numberDiff line numberDiff line change
@@ -924,32 +924,29 @@ let complex_im c dbg =
924924

925925
(* Unit *)
926926

927-
let return_unit dbg c = Csequence (c, Cconst_int (1, dbg))
927+
let return_unit dbg c =
928+
match c with
929+
| Csequence (_, Cconst_int (1, _)) as c -> c
930+
| c -> Csequence (c, Cconst_int (1, dbg))
931+
932+
let memory_chunk_width_in_bytes : memory_chunk -> int = function
933+
| Byte_unsigned | Byte_signed -> 1
934+
| Sixteen_unsigned | Sixteen_signed -> 2
935+
| Thirtytwo_unsigned | Thirtytwo_signed -> 4
936+
| Single { reg = Float64 | Float32 } -> 4
937+
| Word_int -> size_int
938+
| Word_val -> size_addr
939+
| Double -> size_float
940+
| Onetwentyeight_unaligned | Onetwentyeight_aligned -> size_vec128
928941

929942
let strided_field_address ptr ~index ~stride dbg =
930943
if index * stride = 0
931944
then ptr
932945
else Cop (Cadda, [ptr; Cconst_int (index * stride, dbg)], dbg)
933946

934947
let field_address ?(memory_chunk = Word_val) ptr n dbg =
935-
if n = 0
936-
then ptr
937-
else
938-
let field_size_in_bytes =
939-
match memory_chunk with
940-
| Byte_unsigned | Byte_signed -> 1
941-
| Sixteen_unsigned | Sixteen_signed -> 2
942-
| Thirtytwo_unsigned | Thirtytwo_signed -> 4
943-
| Single { reg = Float64 | Float32 } ->
944-
assert (size_float = 8);
945-
(* unclear what to do if this is false *)
946-
size_float / 2
947-
| Word_int -> size_int
948-
| Word_val -> size_addr
949-
| Double -> size_float
950-
| Onetwentyeight_unaligned | Onetwentyeight_aligned -> size_vec128
951-
in
952-
Cop (Cadda, [ptr; Cconst_int (n * field_size_in_bytes, dbg)], dbg)
948+
strided_field_address ptr dbg ~index:n
949+
~stride:(memory_chunk_width_in_bytes memory_chunk)
953950

954951
let get_field_gen_given_memory_chunk memory_chunk mutability ptr n dbg =
955952
Cop
@@ -1410,147 +1407,50 @@ let unboxed_int64_or_nativeint_array_set ~has_custom_ops arr ~index ~new_value
14101407
in
14111408
int_array_set arr index new_value dbg)))
14121409

1413-
(* Get the field of a block given a possibly inconstant index *)
1410+
let get_field_unboxed ~dbg memory_chunk mutability block ~index_in_words =
1411+
if Arch.big_endian && memory_chunk_width_in_bytes memory_chunk <> size_addr
1412+
then
1413+
(* CR layouts v5.1: Properly support big-endian. *)
1414+
Misc.fatal_error
1415+
"Unboxed non-word size integer fields are only supported on \
1416+
little-endian architectures";
1417+
(* CR layouts v5.1: We'll need to vary log2_size_addr among other things to
1418+
efficiently pack small integers *)
1419+
let field_address =
1420+
assert (size_float = size_addr);
1421+
array_indexing log2_size_addr block index_in_words dbg
1422+
in
1423+
Cop
1424+
(Cload { memory_chunk; mutability; is_atomic = false }, [field_address], dbg)
14141425

14151426
let get_field_computed imm_or_ptr mutability ~block ~index dbg =
14161427
let memory_chunk =
14171428
match imm_or_ptr with
14181429
| Lambda.Immediate -> Word_int
14191430
| Lambda.Pointer -> Word_val
14201431
in
1421-
let field_address = array_indexing log2_size_addr block index dbg in
1422-
Cop
1423-
(Cload { memory_chunk; mutability; is_atomic = false }, [field_address], dbg)
1424-
1425-
(* Getters for unboxed int fields *)
1426-
1427-
let get_field_unboxed_int32 mutability ~block ~index dbg =
1428-
let memory_chunk = Thirtytwo_signed in
1429-
(* CR layouts v5.1: Properly support big-endian. *)
1430-
if Arch.big_endian
1431-
then
1432-
Misc.fatal_error
1433-
"Unboxed int32 fields only supported on little-endian architectures";
1434-
(* CR layouts v5.1: We'll need to vary log2_size_addr to efficiently pack
1435-
* int32s *)
1436-
let field_address = array_indexing log2_size_addr block index dbg in
1437-
Cop
1438-
(Cload { memory_chunk; mutability; is_atomic = false }, [field_address], dbg)
1439-
1440-
let get_field_unboxed_int64_or_nativeint mutability ~block ~index dbg =
1441-
let memory_chunk = Word_int in
1442-
let field_address = array_indexing log2_size_addr block index dbg in
1443-
Cop
1444-
(Cload { memory_chunk; mutability; is_atomic = false }, [field_address], dbg)
1445-
1446-
(* Setters for unboxed int fields *)
1447-
1448-
let setfield_unboxed_int32 arr ofs newval dbg =
1449-
(* CR layouts v5.1: Properly support big-endian. *)
1450-
if Arch.big_endian
1451-
then
1452-
Misc.fatal_error
1453-
"Unboxed int32 fields only supported on little-endian architectures";
1454-
(* CR layouts v5.1: We will need to vary log2_size_addr when int32 fields are
1455-
efficiently packed. *)
1456-
return_unit dbg
1457-
(Cop
1458-
( Cstore (Thirtytwo_signed, Assignment),
1459-
[array_indexing log2_size_addr arr ofs dbg; newval],
1460-
dbg ))
1461-
1462-
let setfield_unboxed_int64_or_nativeint arr ofs newval dbg =
1463-
return_unit dbg
1464-
(Cop
1465-
( Cstore (Word_int, Assignment),
1466-
[array_indexing log2_size_addr arr ofs dbg; newval],
1467-
dbg ))
1468-
1469-
(* Getters and setters for unboxed float32 fields *)
1470-
1471-
let get_field_unboxed_float32 mutability ~block ~index dbg =
1472-
(* CR layouts v5.1: Properly support big-endian. *)
1473-
if Arch.big_endian
1474-
then
1475-
Misc.fatal_error
1476-
"Unboxed float32 fields only supported on little-endian architectures";
1477-
let memory_chunk = Single { reg = Float32 } in
1478-
(* CR layouts v5.1: We'll need to vary log2_size_addr to efficiently pack
1479-
* float32s *)
1480-
let field_address = array_indexing log2_size_addr block index dbg in
1481-
Cop
1482-
(Cload { memory_chunk; mutability; is_atomic = false }, [field_address], dbg)
1483-
1484-
let setfield_unboxed_float32 arr ofs newval dbg =
1485-
(* CR layouts v5.1: Properly support big-endian. *)
1486-
if Arch.big_endian
1487-
then
1488-
Misc.fatal_error
1489-
"Unboxed float32 fields only supported on little-endian architectures";
1490-
(* CR layouts v5.1: We will need to vary log2_size_addr when float32 fields
1491-
are efficiently packed. *)
1492-
return_unit dbg
1493-
(Cop
1494-
( Cstore (Single { reg = Float32 }, Assignment),
1495-
[array_indexing log2_size_addr arr ofs dbg; newval],
1496-
dbg ))
1497-
1498-
(* Getters and setters for unboxed vec128 fields *)
1499-
1500-
let get_field_unboxed_vec128 mutability ~block ~index_in_words dbg =
1501-
(* CR layouts v5.1: Properly support big-endian. *)
1502-
if Arch.big_endian
1503-
then
1504-
Misc.fatal_error
1505-
"Unboxed vec128 fields only supported on little-endian architectures";
1506-
let memory_chunk = Onetwentyeight_unaligned in
1507-
let field_address = array_indexing log2_size_addr block index_in_words dbg in
1508-
Cop
1509-
(Cload { memory_chunk; mutability; is_atomic = false }, [field_address], dbg)
1510-
1511-
let setfield_unboxed_vec128 arr ~index_in_words newval dbg =
1512-
(* CR layouts v5.1: Properly support big-endian. *)
1513-
if Arch.big_endian
1514-
then
1515-
Misc.fatal_error
1516-
"Unboxed vec128 fields only supported on little-endian architectures";
1517-
let field_address = array_indexing log2_size_addr arr index_in_words dbg in
1518-
return_unit dbg
1519-
(Cop
1520-
( Cstore (Onetwentyeight_unaligned, Assignment),
1521-
[field_address; newval],
1522-
dbg ))
1523-
1524-
let get_field_unboxed ~dbg memory_chunk mutability block ~index_in_words =
1525-
match (memory_chunk : memory_chunk) with
1526-
| Single { reg = Float32 } ->
1527-
get_field_unboxed_float32 mutability ~block ~index:index_in_words dbg
1528-
| Double ->
1529-
unboxed_float_array_ref mutability ~block ~index:index_in_words dbg
1530-
| Onetwentyeight_unaligned | Onetwentyeight_aligned ->
1531-
get_field_unboxed_vec128 mutability ~block ~index_in_words dbg
1532-
| Thirtytwo_signed ->
1533-
get_field_unboxed_int32 mutability ~block ~index:index_in_words dbg
1534-
| Word_int ->
1535-
get_field_unboxed_int64_or_nativeint mutability ~block ~index:index_in_words
1536-
dbg
1537-
| Word_val ->
1538-
Misc.fatal_error "cannot use get_field_unboxed with a heap block"
1539-
| _ -> Misc.fatal_error "get_field_unboxed: unexpected memory chunk"
1432+
get_field_unboxed ~dbg memory_chunk mutability block ~index_in_words:index
15401433

15411434
let set_field_unboxed ~dbg memory_chunk block ~index_in_words newval =
1542-
match (memory_chunk : memory_chunk) with
1543-
| Single { reg = Float32 } ->
1544-
setfield_unboxed_float32 block index_in_words newval dbg
1545-
| Double -> float_array_set block index_in_words newval dbg
1546-
| Onetwentyeight_unaligned | Onetwentyeight_aligned ->
1547-
setfield_unboxed_vec128 block ~index_in_words newval dbg
1548-
| Thirtytwo_signed -> setfield_unboxed_int32 block index_in_words newval dbg
1549-
| Word_int ->
1550-
setfield_unboxed_int64_or_nativeint block index_in_words newval dbg
1435+
match memory_chunk with
15511436
| Word_val ->
1552-
Misc.fatal_error "cannot use set_field_unboxed with a heap block"
1553-
| _ -> Misc.fatal_error "set_field_unboxed : unexpected memory chunk"
1437+
Misc.fatal_error "Attempted to set a value via [setfield_unboxed]"
1438+
| memory_chunk ->
1439+
let size_in_bytes = memory_chunk_width_in_bytes memory_chunk in
1440+
(* CR layouts v5.1: Properly support big-endian. *)
1441+
if Arch.big_endian && size_in_bytes <> size_addr
1442+
then
1443+
Misc.fatal_error
1444+
"Unboxed non-word-size fields are only supported on little-endian \
1445+
architectures";
1446+
(* CR layouts v5.1: We will need to vary log2_size_addr, among other things,
1447+
when small fields are efficiently packed. *)
1448+
let field_address =
1449+
array_indexing log2_size_addr block index_in_words dbg
1450+
in
1451+
let newval = if size_in_bytes = 4 then low_32 dbg newval else newval in
1452+
return_unit dbg
1453+
(Cop (Cstore (memory_chunk, Assignment), [field_address; newval], dbg))
15541454

15551455
(* String length *)
15561456

0 commit comments

Comments
 (0)