Skip to content

Commit 625a416

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

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

917917
(* Unit *)
918918

919-
let return_unit dbg c = Csequence (c, Cconst_int (1, dbg))
919+
let return_unit dbg c =
920+
match c with
921+
| Csequence (_, Cconst_int (1, _)) as c -> c
922+
| c -> Csequence (c, Cconst_int (1, dbg))
923+
924+
let memory_chunk_width_in_bytes : memory_chunk -> int = function
925+
| Byte_unsigned | Byte_signed -> 1
926+
| Sixteen_unsigned | Sixteen_signed -> 2
927+
| Thirtytwo_unsigned | Thirtytwo_signed -> 4
928+
| Single { reg = Float64 | Float32 } -> 4
929+
| Word_int -> size_int
930+
| Word_val -> size_addr
931+
| Double -> size_float
932+
| Onetwentyeight_unaligned | Onetwentyeight_aligned -> size_vec128
920933

921934
let strided_field_address ptr ~index ~stride dbg =
922935
if index * stride = 0
923936
then ptr
924937
else Cop (Cadda, [ptr; Cconst_int (index * stride, dbg)], dbg)
925938

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

946943
let get_field_gen_given_memory_chunk memory_chunk mutability ptr n dbg =
947944
Cop
@@ -1402,147 +1399,50 @@ let unboxed_int64_or_nativeint_array_set ~has_custom_ops arr ~index ~new_value
14021399
in
14031400
int_array_set arr index new_value dbg)))
14041401

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

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

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

15471447
(* String length *)
15481448

0 commit comments

Comments
 (0)