Skip to content

Commit abcd725

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

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
@@ -910,32 +910,29 @@ let complex_im c dbg =
910910

911911
(* Unit *)
912912

913-
let return_unit dbg c = Csequence (c, Cconst_int (1, dbg))
913+
let return_unit dbg c =
914+
match c with
915+
| Csequence (_, Cconst_int (1, _)) as c -> c
916+
| c -> Csequence (c, Cconst_int (1, dbg))
917+
918+
let memory_chunk_width_in_bytes : memory_chunk -> int = function
919+
| Byte_unsigned | Byte_signed -> 1
920+
| Sixteen_unsigned | Sixteen_signed -> 2
921+
| Thirtytwo_unsigned | Thirtytwo_signed -> 4
922+
| Single { reg = Float64 | Float32 } -> 4
923+
| Word_int -> size_int
924+
| Word_val -> size_addr
925+
| Double -> size_float
926+
| Onetwentyeight_unaligned | Onetwentyeight_aligned -> size_vec128
914927

915928
let strided_field_address ptr ~index ~stride dbg =
916929
if index * stride = 0
917930
then ptr
918931
else Cop (Cadda, [ptr; Cconst_int (index * stride, dbg)], dbg)
919932

920933
let field_address ?(memory_chunk = Word_val) ptr n dbg =
921-
if n = 0
922-
then ptr
923-
else
924-
let field_size_in_bytes =
925-
match memory_chunk with
926-
| Byte_unsigned | Byte_signed -> 1
927-
| Sixteen_unsigned | Sixteen_signed -> 2
928-
| Thirtytwo_unsigned | Thirtytwo_signed -> 4
929-
| Single { reg = Float64 | Float32 } ->
930-
assert (size_float = 8);
931-
(* unclear what to do if this is false *)
932-
size_float / 2
933-
| Word_int -> size_int
934-
| Word_val -> size_addr
935-
| Double -> size_float
936-
| Onetwentyeight_unaligned | Onetwentyeight_aligned -> size_vec128
937-
in
938-
Cop (Cadda, [ptr; Cconst_int (n * field_size_in_bytes, dbg)], dbg)
934+
strided_field_address ptr dbg ~index:n
935+
~stride:(memory_chunk_width_in_bytes memory_chunk)
939936

940937
let get_field_gen_given_memory_chunk memory_chunk mutability ptr n dbg =
941938
Cop
@@ -1396,147 +1393,50 @@ let unboxed_int64_or_nativeint_array_set ~has_custom_ops arr ~index ~new_value
13961393
in
13971394
int_array_set arr index new_value dbg)))
13981395

1399-
(* Get the field of a block given a possibly inconstant index *)
1396+
let get_field_unboxed ~dbg memory_chunk mutability block ~index_in_words =
1397+
if Arch.big_endian && memory_chunk_width_in_bytes memory_chunk <> size_addr
1398+
then
1399+
(* CR layouts v5.1: Properly support big-endian. *)
1400+
Misc.fatal_error
1401+
"Unboxed non-word size integer fields are only supported on \
1402+
little-endian architectures";
1403+
(* CR layouts v5.1: We'll need to vary log2_size_addr among other things to
1404+
efficiently pack small integers *)
1405+
let field_address =
1406+
assert (size_float = size_addr);
1407+
array_indexing log2_size_addr block index_in_words dbg
1408+
in
1409+
Cop
1410+
(Cload { memory_chunk; mutability; is_atomic = false }, [field_address], dbg)
14001411

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

15271420
let set_field_unboxed ~dbg memory_chunk block ~index_in_words newval =
1528-
match (memory_chunk : memory_chunk) with
1529-
| Single { reg = Float32 } ->
1530-
setfield_unboxed_float32 block index_in_words newval dbg
1531-
| Double -> float_array_set block index_in_words newval dbg
1532-
| Onetwentyeight_unaligned | Onetwentyeight_aligned ->
1533-
setfield_unboxed_vec128 block ~index_in_words newval dbg
1534-
| Thirtytwo_signed -> setfield_unboxed_int32 block index_in_words newval dbg
1535-
| Word_int ->
1536-
setfield_unboxed_int64_or_nativeint block index_in_words newval dbg
1421+
match memory_chunk with
15371422
| Word_val ->
1538-
Misc.fatal_error "cannot use set_field_unboxed with a heap block"
1539-
| _ -> Misc.fatal_error "set_field_unboxed : unexpected memory chunk"
1423+
Misc.fatal_error "Attempted to set a value via [setfield_unboxed]"
1424+
| memory_chunk ->
1425+
let size_in_bytes = memory_chunk_width_in_bytes memory_chunk in
1426+
(* CR layouts v5.1: Properly support big-endian. *)
1427+
if Arch.big_endian && size_in_bytes <> size_addr
1428+
then
1429+
Misc.fatal_error
1430+
"Unboxed non-word-size fields are only supported on little-endian \
1431+
architectures";
1432+
(* CR layouts v5.1: We will need to vary log2_size_addr, among other things,
1433+
when small fields are efficiently packed. *)
1434+
let field_address =
1435+
array_indexing log2_size_addr block index_in_words dbg
1436+
in
1437+
let newval = if size_in_bytes = 4 then low_32 dbg newval else newval in
1438+
return_unit dbg
1439+
(Cop (Cstore (memory_chunk, Assignment), [field_address; newval], dbg))
15401440

15411441
(* String length *)
15421442

0 commit comments

Comments
 (0)