Skip to content

Static allocation for mixed blocks etc. #2712

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 33 commits into from
Jul 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
adea7e5
Implement structured constants
ncik-roberts Jun 6, 2024
aa548b5
Improve tests
mshinwell Jun 20, 2024
280934d
Mixed block support for static allocation
mshinwell Jun 20, 2024
e1f7305
Improve types relating to flat suffix elements
mshinwell Jun 24, 2024
d88b411
Make P.Block_access_kind use K.Flat_suffix_element
mshinwell Jun 24, 2024
67528fc
Fix small CR about immutability
mshinwell Jun 24, 2024
4e5d71d
Comment
mshinwell Jun 24, 2024
03a22dd
Rebase fixes
mshinwell Jun 25, 2024
0c90258
Fix mutability error and refactor
mshinwell Jun 25, 2024
060176b
Refactor make_block
mshinwell Jun 25, 2024
7fdc242
Rebase fixes
mshinwell Jul 4, 2024
a365af3
Rebase fix
mshinwell Jul 10, 2024
93b5b53
Equivalent of #2763 for static blocks
lthls Jul 10, 2024
5b793e1
Fix constant mixed blocks with floats
lthls Jul 10, 2024
80cbfa2
Fix structural_constants test
lthls Jul 10, 2024
3230b3c
Make generated mixed block tests more robust
lthls Jul 10, 2024
10fae02
Formatting
lthls Jul 10, 2024
b4636dc
Use const_static
mshinwell Jul 10, 2024
136603f
Fix comment about shapes
mshinwell Jul 10, 2024
7235c25
Add error message about Const_block
mshinwell Jul 10, 2024
7079abb
Remove XXX
mshinwell Jul 10, 2024
20e519b
free_names_of_fields
mshinwell Jul 10, 2024
23c07c8
Use T.mutable_block
mshinwell Jul 10, 2024
63f2afa
Remove rebase mistake comment
mshinwell Jul 10, 2024
8d96886
_kind -> _dbg
mshinwell Jul 10, 2024
49fb603
_kind -> _dbg again
mshinwell Jul 10, 2024
5743252
Add Flat_suffix_element.to_kind_with_subkind
mshinwell Jul 10, 2024
8de4f32
field_types_and_expected_kinds
mshinwell Jul 10, 2024
b2ab3a3
kind -> expected_kind
mshinwell Jul 10, 2024
c2d0db4
Fix typo in previous commit
mshinwell Jul 10, 2024
b64fd14
Tidy up from_lambda_value_kind
mshinwell Jul 10, 2024
617d2e0
CR
mshinwell Jul 10, 2024
caf8b8d
Tweak test to make allocation toplevel in classic mode
lthls Jul 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 40 additions & 16 deletions backend/cmm_helpers.ml
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,11 @@ let block_header ?(scannable_prefix = Scan_all) tag sz =
structured constants and static module definitions. *)
let black_block_header tag sz = Nativeint.logor (block_header tag sz) caml_black

let black_mixed_block_header tag sz ~scannable_prefix_len =
Nativeint.logor
(block_header tag sz ~scannable_prefix:(Scan_prefix scannable_prefix_len))
caml_black

let local_block_header ?scannable_prefix tag sz =
Nativeint.logor (block_header ?scannable_prefix tag sz) caml_local

Expand Down Expand Up @@ -1106,11 +1111,20 @@ let addr_array_ref arr ofs dbg =
let int_array_ref arr ofs dbg =
Cop (mk_load_mut Word_int, [array_indexing log2_size_addr arr ofs dbg], dbg)

let unboxed_float_array_ref arr ofs dbg =
let unboxed_mutable_float_array_ref arr ofs dbg =
Cop (mk_load_mut Double, [array_indexing log2_size_float arr ofs dbg], dbg)

let unboxed_immutable_float_array_ref arr ofs dbg =
Cop (mk_load_immut Double, [array_indexing log2_size_float arr ofs dbg], dbg)

let unboxed_float_array_ref (mutability : Asttypes.mutable_flag) ~block:arr
~index:ofs dbg =
match mutability with
| Immutable -> unboxed_immutable_float_array_ref arr ofs dbg
| Mutable -> unboxed_mutable_float_array_ref arr ofs dbg

let float_array_ref mode arr ofs dbg =
box_float dbg mode (unboxed_float_array_ref arr ofs dbg)
box_float dbg mode (unboxed_mutable_float_array_ref arr ofs dbg)

let addr_array_set_heap arr ofs newval dbg =
Cop
Expand Down Expand Up @@ -1618,43 +1632,53 @@ let addr_array_init arr ofs newval dbg =
[array_indexing log2_size_addr arr ofs dbg; newval],
dbg )

let make_alloc ~mode dbg tag args =
let make_alloc ~mode dbg ~tag args =
make_alloc_generic ~mode
(fun _ arr ofs newval dbg -> addr_array_init arr ofs newval dbg)
dbg tag (List.length args) args

let make_float_alloc ~mode dbg tag args =
let make_float_alloc ~mode dbg ~tag args =
make_alloc_generic ~mode
(fun _ -> float_array_set)
dbg tag
(List.length args * size_float / size_addr)
args

let make_mixed_alloc ~mode dbg tag shape args =
let ({ value_prefix_len; flat_suffix } : Lambda.mixed_block_shape) = shape in
module Flat_suffix_element = struct
type t =
| Tagged_immediate
| Naked_float
| Naked_float32
| Naked_int32
| Naked_int64_or_nativeint
end

let make_mixed_alloc ~mode dbg ~tag ~value_prefix_size
~(flat_suffix : Flat_suffix_element.t array) args =
(* args with shape [Float] must already have been unboxed. *)
let set_fn idx arr ofs newval dbg =
if idx < value_prefix_len
if idx < value_prefix_size
then addr_array_init arr ofs newval dbg
else
match flat_suffix.(idx - value_prefix_len) with
| Imm -> int_array_set arr ofs newval dbg
| Float_boxed | Float64 -> float_array_set arr ofs newval dbg
| Float32 -> setfield_unboxed_float32 arr ofs newval dbg
| Bits32 -> setfield_unboxed_int32 arr ofs newval dbg
| Bits64 | Word -> setfield_unboxed_int64_or_nativeint arr ofs newval dbg
match flat_suffix.(idx - value_prefix_size) with
| Tagged_immediate -> int_array_set arr ofs newval dbg
| Naked_float -> float_array_set arr ofs newval dbg
| Naked_float32 -> setfield_unboxed_float32 arr ofs newval dbg
| Naked_int32 -> setfield_unboxed_int32 arr ofs newval dbg
| Naked_int64_or_nativeint ->
setfield_unboxed_int64_or_nativeint arr ofs newval dbg
in
let size =
(* CR layouts 5.1: When we pack int32s/float32s more efficiently, this code
will need to change. *)
value_prefix_len + Array.length flat_suffix
value_prefix_size + Array.length flat_suffix
in
if size_float <> size_addr
then
Misc.fatal_error
"Unable to compile mixed blocks on a platform where a float is not the \
same width as a value.";
make_alloc_generic ~scannable_prefix:(Scan_prefix value_prefix_len) ~mode
make_alloc_generic ~scannable_prefix:(Scan_prefix value_prefix_size) ~mode
set_fn dbg tag size args

(* Record application and currying functions *)
Expand Down Expand Up @@ -4124,7 +4148,7 @@ let dls_get ~dbg = Cop (Cdls_get, [], dbg)

let perform ~dbg eff =
let cont =
make_alloc dbg Runtimetags.cont_tag
make_alloc dbg ~tag:Runtimetags.cont_tag
[int_const dbg 0]
~mode:Lambda.alloc_heap
in
Expand Down
36 changes: 31 additions & 5 deletions backend/cmm_helpers.mli
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ val block_header : int -> int -> nativeint
(** Same as block_header, but with GC bits set to black *)
val black_block_header : int -> int -> nativeint

(** Same as black_block_header, but for a mixed block *)
val black_mixed_block_header :
int -> int -> scannable_prefix_len:int -> nativeint

val black_closure_header : int -> nativeint

(** Infix header at the given offset *)
Expand Down Expand Up @@ -216,7 +220,11 @@ val addr_array_ref : expression -> expression -> Debuginfo.t -> expression
val int_array_ref : expression -> expression -> Debuginfo.t -> expression

val unboxed_float_array_ref :
expression -> expression -> Debuginfo.t -> expression
Asttypes.mutable_flag ->
block:expression ->
index:expression ->
Debuginfo.t ->
expression

val float_array_ref :
Lambda.alloc_mode -> expression -> expression -> Debuginfo.t -> expression
Expand Down Expand Up @@ -303,19 +311,37 @@ end

(** Allocate a block of regular values with the given tag *)
val make_alloc :
mode:Lambda.alloc_mode -> Debuginfo.t -> int -> expression list -> expression
mode:Lambda.alloc_mode ->
Debuginfo.t ->
tag:int ->
expression list ->
expression

(** Allocate a block of unboxed floats with the given tag *)
val make_float_alloc :
mode:Lambda.alloc_mode -> Debuginfo.t -> int -> expression list -> expression
mode:Lambda.alloc_mode ->
Debuginfo.t ->
tag:int ->
expression list ->
expression

module Flat_suffix_element : sig
type t =
| Tagged_immediate
| Naked_float
| Naked_float32
| Naked_int32
| Naked_int64_or_nativeint
end

(** Allocate an mixed block of the corresponding tag and shape. Initial values
of the flat suffix should be provided unboxed. *)
val make_mixed_alloc :
mode:Lambda.alloc_mode ->
Debuginfo.t ->
int ->
Lambda.mixed_block_shape ->
tag:int ->
value_prefix_size:int ->
flat_suffix:Flat_suffix_element.t array ->
expression list ->
expression

Expand Down
17 changes: 10 additions & 7 deletions middle_end/flambda2/classic_mode_types/value_approximation.ml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
type 'code t =
| Value_unknown
| Value_symbol of Symbol.t
| Value_int of Targetint_31_63.t
| Value_const of Reg_width_const.t
| Closure_approximation of
{ code_id : Code_id.t;
function_slot : Function_slot.t;
Expand All @@ -29,15 +29,18 @@ type 'code t =
symbol : Symbol.t option
}
| Block_approximation of
Tag.Scannable.t * 'code t array * Alloc_mode.For_types.t
Tag.Scannable.t
* Flambda_kind.Scannable_block_shape.t
* 'code t array
* Alloc_mode.For_types.t

let rec print fmt = function
| Value_unknown -> Format.fprintf fmt "?"
| Value_symbol sym -> Symbol.print fmt sym
| Value_int i -> Targetint_31_63.print fmt i
| Value_const i -> Reg_width_const.print fmt i
| Closure_approximation { code_id; _ } ->
Format.fprintf fmt "[%a]" Code_id.print code_id
| Block_approximation (tag, fields, _) ->
| Block_approximation (tag, _shape, fields, _) ->
let len = Array.length fields in
if len < 1
then Format.fprintf fmt "{}"
Expand All @@ -51,15 +54,15 @@ let rec print fmt = function

let is_unknown = function
| Value_unknown -> true
| Value_symbol _ | Value_int _ | Closure_approximation _
| Value_symbol _ | Value_const _ | Closure_approximation _
| Block_approximation _ ->
false

let rec free_names ~code_free_names approx =
match approx with
| Value_unknown | Value_int _ -> Name_occurrences.empty
| Value_unknown | Value_const _ -> Name_occurrences.empty
| Value_symbol sym -> Name_occurrences.singleton_symbol sym Name_mode.normal
| Block_approximation (_tag, approxs, _) ->
| Block_approximation (_tag, _shape, approxs, _) ->
Array.fold_left
(fun names approx ->
Name_occurrences.union names (free_names ~code_free_names approx))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
type 'code t =
| Value_unknown
| Value_symbol of Symbol.t
| Value_int of Targetint_31_63.t
| Value_const of Reg_width_const.t
| Closure_approximation of
{ code_id : Code_id.t;
function_slot : Function_slot.t;
Expand All @@ -29,7 +29,10 @@ type 'code t =
symbol : Symbol.t option
}
| Block_approximation of
Tag.Scannable.t * 'code t array * Alloc_mode.For_types.t
Tag.Scannable.t
* Flambda_kind.Scannable_block_shape.t
* 'code t array
* Alloc_mode.For_types.t

val print : Format.formatter -> 'a t -> unit

Expand Down
31 changes: 14 additions & 17 deletions middle_end/flambda2/compare/compare.ml
Original file line number Diff line number Diff line change
Expand Up @@ -285,10 +285,10 @@ let subst_rec_info_expr _env ri =
symbols and other global names *)
ri

let subst_field env (field : Field_of_static_block.t) =
match field with
| Symbol symbol -> Field_of_static_block.Symbol (subst_symbol env symbol)
| Tagged_immediate _ | Dynamically_computed _ -> field
let subst_field env field =
Simple.With_debuginfo.create
(subst_simple env (Simple.With_debuginfo.simple field))
(Simple.With_debuginfo.dbg field)

let subst_call_kind env (call_kind : Call_kind.t) : Call_kind.t =
match call_kind with
Expand Down Expand Up @@ -359,9 +359,10 @@ and subst_static_const env (static_const : Static_const_or_code.t) :
Static_const_or_code.t =
match static_const with
| Code code -> Static_const_or_code.create_code (subst_code env code)
| Static_const (Block (tag, mut, fields)) ->
| Static_const (Block (tag, mut, shape, fields)) ->
let fields = List.map (subst_field env) fields in
Static_const_or_code.create_static_const (Static_const.block tag mut fields)
Static_const_or_code.create_static_const
(Static_const.block tag mut shape fields)
| Static_const (Set_of_closures set_of_closures) ->
Static_const_or_code.create_static_const
(Static_const.set_of_closures (subst_set_of_closures env set_of_closures))
Expand Down Expand Up @@ -908,14 +909,9 @@ let bound_static env bound_static1 bound_static2 : Bound_static.t Comparison.t =
(bound_static2 |> Bound_static.to_list)
|> Comparison.map ~f:Bound_static.create

let fields env (field1 : Field_of_static_block.t)
(field2 : Field_of_static_block.t) : Field_of_static_block.t Comparison.t =
match field1, field2 with
| Symbol symbol1, Symbol symbol2 ->
symbols env symbol1 symbol2
|> Comparison.map ~f:(fun symbol1' -> Field_of_static_block.Symbol symbol1')
| _, _ ->
Comparator.of_predicate Field_of_static_block.equal env field1 field2
let fields env (field1 : Simple.With_debuginfo.t)
(field2 : Simple.With_debuginfo.t) : Simple.With_debuginfo.t Comparison.t =
Comparator.of_predicate Simple.With_debuginfo.equal env field1 field2

let blocks env block1 block2 =
triples
Expand Down Expand Up @@ -1181,13 +1177,14 @@ and static_consts env (const1 : Static_const_or_code.t)
match const1, const2 with
| Code code1, Code code2 ->
codes env code1 code2 |> Comparison.map ~f:Static_const_or_code.create_code
| ( Static_const (Block (tag1, mut1, fields1)),
Static_const (Block (tag2, mut2, fields2)) ) ->
| ( Static_const (Block (tag1, mut1, shape1, fields1)),
Static_const (Block (tag2, mut2, _shape2, fields2)) ) ->
(* XXX compare the shapes *)
blocks env (tag1, mut1, fields1) (tag2, mut2, fields2)
|> Comparison.map
~f:(fun (tag1', mut1', fields1') : Static_const_or_code.t ->
Static_const_or_code.create_static_const
(Static_const.block tag1' mut1' fields1'))
(Static_const.block tag1' mut1' shape1 fields1'))
| Static_const (Set_of_closures set1), Static_const (Set_of_closures set2) ->
sets_of_closures env set1 set2
|> Comparison.map ~f:(fun set1' : Static_const_or_code.t ->
Expand Down
Loading
Loading