Skip to content

Commit 562f49e

Browse files
committed
Code review
1 parent c22db78 commit 562f49e

38 files changed

+673
-744
lines changed

backend/cmm_helpers.ml

Lines changed: 72 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ let mk_load_atomic memory_chunk =
6464

6565
let floatarray_tag dbg = Cconst_int (Obj.double_array_tag, dbg)
6666

67+
(* CR mshinwell: update to use NOT_MARKABLE terminology *)
6768
let block_header tag sz =
6869
Nativeint.add
6970
(Nativeint.shift_left (Nativeint.of_int sz) 10)
@@ -118,6 +119,8 @@ let boxedint64_local_header =
118119

119120
let boxedintnat_local_header = local_block_header Obj.custom_tag 2
120121

122+
let black_custom_header ~size = black_block_header Obj.custom_tag size
123+
121124
let custom_header ~size = block_header Obj.custom_tag size
122125

123126
let custom_local_header ~size = local_block_header Obj.custom_tag size
@@ -924,7 +927,6 @@ let unboxed_int32_array_length arr dbg =
924927
sub_int (get_size arr dbg) (int ~dbg 1) dbg,
925928
Clet
926929
( VP.create custom_ops_var,
927-
(* CR gbury/mshinwell: check the atomicity of this load *)
928930
Cop (mk_load_immut Word_int, [arr], dbg),
929931
Cifthenelse
930932
( Cop
@@ -1024,6 +1026,36 @@ let addr_array_initialize arr ofs newval dbg =
10241026
[array_indexing log2_size_addr arr ofs dbg; newval],
10251027
dbg )
10261028

1029+
(* low_32 x is a value which agrees with x on at least the low 32 bits *)
1030+
let rec low_32 dbg = function
1031+
(* Ignore sign and zero extensions, which do not affect the low bits *)
1032+
| Cop (Casr, [Cop (Clsl, [x; Cconst_int (32, _)], _); Cconst_int (32, _)], _)
1033+
| Cop (Cand, [x; Cconst_natint (0xFFFFFFFFn, _)], _) ->
1034+
low_32 dbg x
1035+
| Clet (id, e, body) -> Clet (id, e, low_32 dbg body)
1036+
| x -> x
1037+
1038+
(* sign_extend_32 sign-extends values from 32 bits to the word size. *)
1039+
let sign_extend_32 dbg e =
1040+
match low_32 dbg e with
1041+
| Cop
1042+
( Cload
1043+
{ memory_chunk = Thirtytwo_unsigned | Thirtytwo_signed;
1044+
mutability;
1045+
is_atomic
1046+
},
1047+
args,
1048+
dbg ) ->
1049+
Cop
1050+
( Cload { memory_chunk = Thirtytwo_signed; mutability; is_atomic },
1051+
args,
1052+
dbg )
1053+
| e ->
1054+
Cop
1055+
( Casr,
1056+
[Cop (Clsl, [e; Cconst_int (32, dbg)], dbg); Cconst_int (32, dbg)],
1057+
dbg )
1058+
10271059
let unboxed_int32_array_ref arr index dbg =
10281060
bind "arr" arr (fun arr ->
10291061
bind "index" index (fun index ->
@@ -1034,11 +1066,12 @@ let unboxed_int32_array_ref arr index dbg =
10341066
add_int index (int ~dbg 2) dbg
10351067
in
10361068
let log2_size_addr = 2 in
1037-
Cop
1038-
(* CR gbury/mshinwell: check the atomicity of the load *)
1039-
( mk_load_mut Thirtytwo_signed,
1040-
[array_indexing log2_size_addr arr index dbg],
1041-
dbg )))
1069+
(* N.B. The resulting value must be sign extended! *)
1070+
sign_extend_32 dbg
1071+
(Cop
1072+
( mk_load_mut Thirtytwo_signed,
1073+
[array_indexing log2_size_addr arr index dbg],
1074+
dbg ))))
10421075

10431076
let unboxed_int64_or_nativeint_array_ref arr index dbg =
10441077
bind "arr" arr (fun arr ->
@@ -1416,15 +1449,6 @@ let check_64_bit_target func =
14161449
Misc.fatal_errorf
14171450
"Cmm helpers function %s can only be used on 64-bit targets" func
14181451

1419-
(* low_32 x is a value which agrees with x on at least the low 32 bits *)
1420-
let rec low_32 dbg = function
1421-
(* Ignore sign and zero extensions, which do not affect the low bits *)
1422-
| Cop (Casr, [Cop (Clsl, [x; Cconst_int (32, _)], _); Cconst_int (32, _)], _)
1423-
| Cop (Cand, [x; Cconst_natint (0xFFFFFFFFn, _)], _) ->
1424-
low_32 dbg x
1425-
| Clet (id, e, body) -> Clet (id, e, low_32 dbg body)
1426-
| x -> x
1427-
14281452
(* Like [low_32] but for 63-bit integers held in 64-bit registers. *)
14291453
(* CR gbury: Why not use Cmm.map_tail here ? It seems designed for that kind of
14301454
thing (and covers more cases than just Clet). *)
@@ -1438,27 +1462,6 @@ let rec low_63 dbg e =
14381462
| Clet (id, x, body) -> Clet (id, x, low_63 dbg body)
14391463
| _ -> e
14401464

1441-
(* sign_extend_32 sign-extends values from 32 bits to the word size. *)
1442-
let sign_extend_32 dbg e =
1443-
match low_32 dbg e with
1444-
| Cop
1445-
( Cload
1446-
{ memory_chunk = Thirtytwo_unsigned | Thirtytwo_signed;
1447-
mutability;
1448-
is_atomic
1449-
},
1450-
args,
1451-
dbg ) ->
1452-
Cop
1453-
( Cload { memory_chunk = Thirtytwo_signed; mutability; is_atomic },
1454-
args,
1455-
dbg )
1456-
| e ->
1457-
Cop
1458-
( Casr,
1459-
[Cop (Clsl, [e; Cconst_int (32, dbg)], dbg); Cconst_int (32, dbg)],
1460-
dbg )
1461-
14621465
(* CR-someday mshinwell/gbury: sign_extend_63 then tag_int should simplify to
14631466
just tag_int. Similarly, untag_int then sign_extend_63 should simplify to
14641467
untag_int. *)
@@ -2860,13 +2863,13 @@ let arraylength kind arg dbg =
28602863
in
28612864
Cop (Cor, [len; Cconst_int (1, dbg)], dbg)
28622865
| Paddrarray | Pintarray ->
2863-
(* Note we only support 64 bit targets now, so this is ok for
2864-
Punboxedfloatarray *)
28652866
Cop (Cor, [addr_array_length_shifted hdr dbg; Cconst_int (1, dbg)], dbg)
2866-
| Punboxedintarray Pint64 | Punboxedintarray Pnativeint ->
2867-
unboxed_int64_or_nativeint_array_length arg dbg
28682867
| Pfloatarray | Punboxedfloatarray ->
2868+
(* Note: we only support 64 bit targets now, so this is ok for
2869+
Punboxedfloatarray *)
28692870
Cop (Cor, [float_array_length_shifted hdr dbg; Cconst_int (1, dbg)], dbg)
2871+
| Punboxedintarray Pint64 | Punboxedintarray Pnativeint ->
2872+
unboxed_int64_or_nativeint_array_length arg dbg
28702873
| Punboxedintarray Pint32 -> unboxed_int32_array_length arg dbg
28712874

28722875
(* CR-soon gyorsh: effects and coeffects for primitives are set conservatively
@@ -3708,32 +3711,39 @@ let atomic_compare_and_set ~dbg atomic ~old_value ~new_value =
37083711
[atomic; old_value; new_value],
37093712
dbg )
37103713

3714+
type even_or_odd =
3715+
| Even
3716+
| Odd
3717+
37113718
let make_unboxed_int32_array_payload dbg unboxed_int32_list =
3719+
(* CR mshinwell/gbury: potential big-endian implementations:
3720+
*
3721+
* let i =
3722+
* if big_endian
3723+
* then Cop (Clsl, [a; Cconst_int (32, dbg)], dbg)
3724+
* else a
3725+
* in
3726+
* ...
3727+
* let i =
3728+
* if big_endian
3729+
* then Cop (Cor, [Cop (Clsl, [a; Cconst_int (32, dbg)], dbg); b], dbg)
3730+
* else Cop (Cor, [a; Cop (Clsl, [b; Cconst_int (32, dbg)], dbg)], dbg)
3731+
* in
3732+
*)
3733+
if Sys.big_endian
3734+
then
3735+
Misc.fatal_error "Big-endian platforms not yet supported for unboxed arrays";
37123736
let rec aux acc = function
3713-
| [] -> true, List.rev acc
3714-
| a :: [] ->
3715-
let i =
3716-
(* CR gbury: check/test that this is correct *)
3717-
if big_endian
3718-
then Cop (Clsl, [a; Cconst_int (32, dbg)], dbg)
3719-
else sign_extend_32 dbg a
3720-
in
3721-
false, List.rev (i :: acc)
3737+
| [] -> Even, List.rev acc
3738+
| a :: [] -> Odd, List.rev (a :: acc)
37223739
| a :: b :: r ->
3723-
let i =
3724-
(* CR gbury: check/test that this is correct *)
3725-
if big_endian
3726-
then Cop (Cor, [Cop (Clsl, [a; Cconst_int (32, dbg)], dbg); b], dbg)
3727-
else Cop (Cor, [a; Cop (Clsl, [b; Cconst_int (32, dbg)], dbg)], dbg)
3728-
in
3740+
let i = Cop (Cor, [a; Cop (Clsl, [b; Cconst_int (32, dbg)], dbg)], dbg) in
37293741
aux (i :: acc) r
37303742
in
37313743
aux [] unboxed_int32_list
37323744

37333745
let allocate_unboxed_int32_array ~elements (mode : Lambda.alloc_mode) dbg =
3734-
let even_num_of_elts, payload =
3735-
make_unboxed_int32_array_payload dbg elements
3736-
in
3746+
let num_elts, payload = make_unboxed_int32_array_payload dbg elements in
37373747
let header =
37383748
let size = 1 (* custom_ops field *) + List.length payload in
37393749
match mode with
@@ -3742,10 +3752,10 @@ let allocate_unboxed_int32_array ~elements (mode : Lambda.alloc_mode) dbg =
37423752
in
37433753
let custom_ops =
37443754
(* For odd-length unboxed int32 arrays there are 32 bits spare at the end of
3745-
the block *)
3746-
if even_num_of_elts
3747-
then custom_ops_unboxed_int32_even_array
3748-
else custom_ops_unboxed_int32_odd_array
3755+
the block, which are never read. *)
3756+
match num_elts with
3757+
| Even -> custom_ops_unboxed_int32_even_array
3758+
| Odd -> custom_ops_unboxed_int32_odd_array
37493759
in
37503760
Cop (Calloc mode, Cconst_natint (header, dbg) :: custom_ops :: payload, dbg)
37513761

backend/cmm_helpers.mli

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ val black_closure_header : int -> nativeint
4242
(** Infix header at the given offset *)
4343
val infix_header : int -> nativeint
4444

45-
val custom_header : size:int -> nativeint
45+
val black_custom_header : size:int -> nativeint
4646

4747
(** Closure info for a closure of given arity and distance to environment *)
4848
val closure_info : arity:arity -> startenv:int -> is_last:bool -> nativeint
@@ -918,19 +918,20 @@ val unboxed_int32_array_ref :
918918
expression -> expression -> Debuginfo.t -> expression
919919

920920
(** Read from an unboxed int64 or unboxed nativeint array (without bounds
921-
check). *)
921+
check). *)
922922
val unboxed_int64_or_nativeint_array_ref :
923923
expression -> expression -> Debuginfo.t -> expression
924924

925-
(** Update an unboxed int64 or unboxed nativeint array. *)
925+
(** Update an unboxed int32 array (without bounds check). *)
926926
val unboxed_int32_array_set :
927927
expression ->
928928
index:expression ->
929929
new_value:expression ->
930930
Debuginfo.t ->
931931
expression
932932

933-
(** Update an unboxed int64 or unboxed nativeint array. *)
933+
(** Update an unboxed int64 or unboxed nativeint array (without bounds
934+
check). *)
934935
val unboxed_int64_or_nativeint_array_set :
935936
expression ->
936937
index:expression ->

middle_end/flambda2/flambda2.ml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,11 @@ let lambda_to_cmm ~ppf_dump:ppf ~prefixname ~filename:_ ~keep_symbol_tables
103103
[Name_occurrences]. *)
104104
if Sys.word_size <> 64
105105
then Misc.fatal_error "Flambda 2 can only run on 64-bit hosts at present";
106+
(* At least one place in the Cmm translation code (for unboxed arrays) cannot
107+
cope with big-endian systems, and it seems unlikely any such systems will
108+
have to be supported in the future anyway. *)
109+
if Arch.big_endian
110+
then Misc.fatal_error "Flambda2 only supports little-endian hosts";
106111
(* When the float array optimisation is enabled, the length of an array needs
107112
to be computed differently according to the array kind, in the case where
108113
the width of a float is not equal to the machine word width (at present,

middle_end/flambda2/kinds/flambda_kind.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ module With_subkind = struct
334334
| Value_array, Value_array
335335
| Generic_array, Generic_array
336336
| Unboxed_int32_array, Unboxed_int32_array
337-
| Unboxed_int64_array, Unboxed_int32_array
337+
| Unboxed_int64_array, Unboxed_int64_array
338338
| Unboxed_nativeint_array, Unboxed_nativeint_array ->
339339
true
340340
| ( Variant { consts = consts1; non_consts = non_consts1 },

middle_end/flambda2/parser/fexpr.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ type binop =
355355
| Bigarray_get_alignment of int
356356

357357
type ternop =
358-
(* XXX mshinwell: Array_set should use "array_set_kind" *)
358+
(* CR mshinwell: Array_set should use "array_set_kind" *)
359359
| Array_set of array_kind * init_or_assign
360360
| Block_set of block_access_kind * init_or_assign
361361
| Bytes_or_bigstring_set of bytes_like_value * string_accessor_width

middle_end/flambda2/parser/fexpr_to_flambda.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,8 @@ let ternop env (ternop : Fexpr.ternop) : Flambda_primitive.ternary_primitive =
452452
| Values, ia -> Values (init_or_assign env ia)
453453
| (Naked_int32s | Naked_int64s | Naked_nativeints), _ ->
454454
Misc.fatal_error
455-
"XXX fexpr support for unboxed int32/64/nativeint arrays"
455+
"fexpr support for unboxed int32/64/nativeint arrays not yet \
456+
implemented"
456457
in
457458
Array_set ask
458459
| Block_set (bk, ia) -> Block_set (block_access_kind bk, init_or_assign env ia)

middle_end/flambda2/parser/flambda_to_fexpr.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ let nullop _env (op : Flambda_primitive.nullary_primitive) : Fexpr.nullop =
516516

517517
let unop env (op : Flambda_primitive.unary_primitive) : Fexpr.unop =
518518
match op with
519-
| Array_length _ak -> Array_length (Array_kind Values) (* XXX *)
519+
| Array_length ak -> Array_length ak
520520
| Box_number (bk, alloc) ->
521521
Box_number (bk, alloc_mode_for_allocations env alloc)
522522
| Tag_immediate -> Tag_immediate

middle_end/flambda2/simplify/rebuilt_static_const.ml

Lines changed: 11 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ let create_immutable_float_block are_rebuilding fields =
151151
Block_not_rebuilt { free_names }
152152
else create_normal_non_code (SC.immutable_float_block fields)
153153

154-
let create_immutable_float_array are_rebuilding fields =
154+
let create_immutable_naked_number_array builder are_rebuilding fields =
155155
if ART.do_not_rebuild_terms are_rebuilding
156156
then
157157
let free_names =
@@ -160,40 +160,19 @@ let create_immutable_float_array are_rebuilding fields =
160160
Name_occurrences.union free_names (Or_variable.free_names field))
161161
in
162162
Block_not_rebuilt { free_names }
163-
else create_normal_non_code (SC.immutable_float_array fields)
163+
else create_normal_non_code (builder fields)
164164

165-
let create_immutable_int32_array are_rebuilding fields =
166-
if ART.do_not_rebuild_terms are_rebuilding
167-
then
168-
let free_names =
169-
ListLabels.fold_left fields ~init:Name_occurrences.empty
170-
~f:(fun free_names field ->
171-
Name_occurrences.union free_names (Or_variable.free_names field))
172-
in
173-
Block_not_rebuilt { free_names }
174-
else create_normal_non_code (SC.immutable_int32_array fields)
165+
let create_immutable_float_array =
166+
create_immutable_naked_number_array SC.immutable_float_array
175167

176-
let create_immutable_int64_array are_rebuilding fields =
177-
if ART.do_not_rebuild_terms are_rebuilding
178-
then
179-
let free_names =
180-
ListLabels.fold_left fields ~init:Name_occurrences.empty
181-
~f:(fun free_names field ->
182-
Name_occurrences.union free_names (Or_variable.free_names field))
183-
in
184-
Block_not_rebuilt { free_names }
185-
else create_normal_non_code (SC.immutable_int64_array fields)
168+
let create_immutable_int32_array =
169+
create_immutable_naked_number_array SC.immutable_int32_array
186170

187-
let create_immutable_nativeint_array are_rebuilding fields =
188-
if ART.do_not_rebuild_terms are_rebuilding
189-
then
190-
let free_names =
191-
ListLabels.fold_left fields ~init:Name_occurrences.empty
192-
~f:(fun free_names field ->
193-
Name_occurrences.union free_names (Or_variable.free_names field))
194-
in
195-
Block_not_rebuilt { free_names }
196-
else create_normal_non_code (SC.immutable_nativeint_array fields)
171+
let create_immutable_int64_array =
172+
create_immutable_naked_number_array SC.immutable_int64_array
173+
174+
let create_immutable_nativeint_array =
175+
create_immutable_naked_number_array SC.immutable_nativeint_array
197176

198177
let create_immutable_value_array are_rebuilding fields =
199178
if ART.do_not_rebuild_terms are_rebuilding

0 commit comments

Comments
 (0)