Skip to content

Commit 6dce5c0

Browse files
committed
simplify string access computations
1 parent 9fb57b6 commit 6dce5c0

File tree

5 files changed

+36
-36
lines changed

5 files changed

+36
-36
lines changed

backend/cmm_helpers.ml

+8-12
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ open Arch
2222

2323
let arch_bits = Arch.size_int * 8
2424

25+
let size_addr = size_addr
26+
27+
let size_float = size_float
28+
2529
type arity =
2630
{ function_kind : Lambda.function_kind;
2731
params_layout : Lambda.layout list;
@@ -1123,12 +1127,6 @@ let log2_size_addr = Misc.log2 size_addr
11231127

11241128
let log2_size_float = Misc.log2 size_float
11251129

1126-
let wordsize_shift = 9
1127-
1128-
let numfloat_shift = 9 + log2_size_float - log2_size_addr
1129-
1130-
let addr_array_length_shifted hdr dbg = lsr_const hdr wordsize_shift dbg
1131-
11321130
(* Produces a pointer to the element of the array [ptr] on the position [ofs]
11331131
with the given element [log2size] log2 element size.
11341132
@@ -1261,7 +1259,7 @@ let unboxed_packed_array_length arr dbg ~custom_ops_base_symbol
12611259
dbg)
12621260
(Cvar custom_ops_index_var) dbg ) ) ))
12631261
in
1264-
tag_int res dbg
1262+
res
12651263

12661264
let unboxed_int32_array_length =
12671265
unboxed_packed_array_length
@@ -1278,15 +1276,15 @@ let unboxed_int64_or_nativeint_array_length arr dbg =
12781276
(* need to subtract so as not to count the custom_operations field *)
12791277
sub_int (get_size arr dbg) (int ~dbg 1) dbg)
12801278
in
1281-
tag_int res dbg
1279+
res
12821280

12831281
let unboxed_vec128_array_length arr dbg =
12841282
let res =
12851283
bind "arr" arr (fun arr ->
12861284
(* need to subtract so as not to count the custom_operations field *)
12871285
sub_int (get_size arr dbg) (int ~dbg 1) dbg)
12881286
in
1289-
tag_int (lsr_int res (int ~dbg 1) dbg) dbg
1287+
lsr_int res (int ~dbg 1) dbg
12901288

12911289
let addr_array_ref arr ofs dbg =
12921290
Cop (mk_load_mut Word_val, [array_indexing log2_size_addr arr ofs dbg], dbg)
@@ -3407,9 +3405,7 @@ let raise_prim raise_kind arg dbg =
34073405

34083406
let negint arg dbg = Cop (Csubi, [Cconst_int (2, dbg); arg], dbg)
34093407

3410-
let addr_array_length arg dbg =
3411-
let hdr = get_header_masked arg dbg in
3412-
Cop (Cor, [addr_array_length_shifted hdr dbg; Cconst_int (1, dbg)], dbg)
3408+
let addr_array_length arg dbg = get_size arg dbg
34133409

34143410
(* CR-soon gyorsh: effects and coeffects for primitives are set conservatively
34153411
to Arbitrary_effects and Has_coeffects, resp. Check if this can be improved

backend/cmm_helpers.mli

+5-7
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ open Cmm
1717

1818
val arch_bits : int
1919

20+
val size_float : int
21+
22+
val size_addr : int
23+
2024
type arity =
2125
{ function_kind : Lambda.function_kind;
2226
params_layout : Lambda.layout list;
@@ -202,12 +206,6 @@ val get_header : expression -> Debuginfo.t -> expression
202206
(** Load a block's tag *)
203207
val get_tag : expression -> Debuginfo.t -> expression
204208

205-
(** Arrays *)
206-
207-
val wordsize_shift : int
208-
209-
val numfloat_shift : int
210-
211209
(** Array loads and stores
212210
213211
[unboxed_float_array_ref] and [float_array_ref] differ in the boxing of the
@@ -448,7 +446,7 @@ val raise_prim : Lambda.raise_kind -> unary_primitive
448446
(** Unary negation of an OCaml integer *)
449447
val negint : unary_primitive
450448

451-
(** Return the length of the array argument, as an OCaml integer *)
449+
(** Return the length of the array argument, as a register-width integer *)
452450
val addr_array_length : unary_primitive
453451

454452
(** Byte swap primitive Operates on Cmm integers (unboxed values) *)

middle_end/flambda2/flambda2.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ let lambda_to_cmm ~ppf_dump:ppf ~prefixname ~keep_symbol_tables
153153
to be computed differently according to the array kind, in the case where
154154
the width of a float is not equal to the machine word width (at present,
155155
this happens only on 32-bit targets). *)
156-
if Cmm_helpers.wordsize_shift <> Cmm_helpers.numfloat_shift
156+
if Cmm_helpers.size_addr <> Cmm_helpers.size_float
157157
&& Flambda_features.flat_float_array ()
158158
then
159159
Misc.fatal_error

middle_end/flambda2/from_lambda/lambda_to_flambda_primitives.ml

+17-13
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,7 @@ let max_with_zero ~size_int x =
660660
ret
661661

662662
(* actual (strict) upper bound for an index in a string-like read/write *)
663-
let actual_max_length_for_string_like_access_as_nativeint ~size_int
663+
let actual_max_length_for_string_like_access ~size_int
664664
~(access_size : Flambda_primitive.string_accessor_width) length =
665665
(* offset to subtract from the length depending on the size of the
666666
read/write *)
@@ -675,29 +675,33 @@ let actual_max_length_for_string_like_access_as_nativeint ~size_int
675675
in
676676
Targetint_32_64.of_int offset
677677
in
678+
(* We need to convert the length into a naked_nativeint because the optimised
679+
version of the max_with_zero function needs to be on machine-width integers
680+
to work (or at least on an integer number of bytes to work). *)
681+
let length =
682+
H.Prim
683+
(Unary (Num_conv { src = Naked_immediate; dst = Naked_nativeint }, length))
684+
in
678685
match access_size with
679686
| Eight -> length (* micro-optimization *)
680687
| Sixteen | Thirty_two | Single | Sixty_four | One_twenty_eight _ ->
681688
let offset = length_offset_of_size access_size in
682-
H.Prim
683-
(Binary
684-
( Int_arith (Naked_nativeint, Sub),
685-
length,
686-
Simple (Simple.const (Reg_width_const.naked_nativeint offset)) ))
687-
|> max_with_zero ~size_int
689+
let reduced_length =
690+
H.Prim
691+
(Binary
692+
( Int_arith (Naked_nativeint, Sub),
693+
length,
694+
Simple (Simple.const (Reg_width_const.naked_nativeint offset)) ))
695+
in
696+
max_with_zero ~size_int reduced_length
688697

689698
(* String-like validity conditions *)
690699

691700
let string_like_access_validity_condition ~size_int ~access_size ~length
692701
~index_kind index : H.expr_primitive =
693-
let length =
694-
H.Prim
695-
(Unary (Num_conv { src = Naked_immediate; dst = Naked_nativeint }, length))
696-
in
697702
check_bound ~index_kind ~bound_kind:Naked_nativeint ~index
698703
~bound:
699-
(actual_max_length_for_string_like_access_as_nativeint ~size_int
700-
~access_size length)
704+
(actual_max_length_for_string_like_access ~size_int ~access_size length)
701705

702706
let string_or_bytes_access_validity_condition ~size_int str kind access_size
703707
~index_kind index : H.expr_primitive =

middle_end/flambda2/to_cmm/to_cmm_primitive.ml

+5-3
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ let array_length ~dbg arr (kind : P.Array_kind.t) =
251251
represented by mixed blocks with tag zero (not custom blocks), and that
252252
arrays of unboxed products are not packed in any way (e.g. int32#
253253
elements occupy 64 bits). *)
254-
assert (C.wordsize_shift = C.numfloat_shift);
254+
assert (C.size_addr = C.size_float);
255255
C.addr_array_length arr dbg
256256
| Naked_float32s -> C.unboxed_float32_array_length arr dbg
257257
| Naked_int32s -> C.unboxed_int32_array_length arr dbg
@@ -861,10 +861,12 @@ let unary_primitive env res dbg f arg =
861861
| Is_null -> None, res, C.eq ~dbg arg (C.nativeint ~dbg 0n)
862862
| Get_tag -> None, res, C.get_tag arg dbg
863863
| Array_length (Array_kind array_kind) ->
864-
None, res, array_length ~dbg arg array_kind
864+
let len = array_length ~dbg arg array_kind in
865+
None, res, C.tag_int len dbg
865866
| Array_length Float_array_opt_dynamic ->
866867
(* See flambda2.ml (and comment in [array_length], above). *)
867-
None, res, array_length ~dbg arg Values
868+
let len = array_length ~dbg arg Values in
869+
None, res, C.tag_int len dbg
868870
| Bigarray_length { dimension } ->
869871
( None,
870872
res,

0 commit comments

Comments
 (0)