Skip to content

Commit f1348da

Browse files
committed
Implement structured constants
1 parent 0d24f6a commit f1348da

21 files changed

+563
-111
lines changed

backend/cmm_helpers.ml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,11 @@ let block_header ?(scannable_prefix = Scan_all) tag sz =
152152
structured constants and static module definitions. *)
153153
let black_block_header tag sz = Nativeint.logor (block_header tag sz) caml_black
154154

155+
let black_mixed_block_header tag sz ~scannable_prefix_len =
156+
Nativeint.logor
157+
(block_header tag sz ~scannable_prefix:(Scan_prefix scannable_prefix_len))
158+
caml_black
159+
155160
let local_block_header ?scannable_prefix tag sz =
156161
Nativeint.logor (block_header ?scannable_prefix tag sz) caml_local
157162

@@ -3886,6 +3891,8 @@ let cfloat32 f = Cmm.Csingle f
38863891

38873892
let cfloat f = Cmm.Cdouble f
38883893

3894+
let cint32 f = Cmm.Cint32 f
3895+
38893896
let cvec128 bits = Cmm.Cvec128 bits
38903897

38913898
let symbol_address s = Cmm.Csymbol_address s

backend/cmm_helpers.mli

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ val block_header : int -> int -> nativeint
3737
(** Same as block_header, but with GC bits set to black *)
3838
val black_block_header : int -> int -> nativeint
3939

40+
(** Same as black_block_header, but for a mixed block *)
41+
val black_mixed_block_header :
42+
int -> int -> scannable_prefix_len:int -> nativeint
43+
4044
val black_closure_header : int -> nativeint
4145

4246
(** Infix header at the given offset *)
@@ -874,6 +878,9 @@ val infix_field_address : dbg:Debuginfo.t -> expression -> int -> expression
874878
(** Static integer. *)
875879
val cint : nativeint -> data_item
876880

881+
(** Static int32. *)
882+
val cint32 : nativeint -> data_item
883+
877884
(** Static float32. *)
878885
val cfloat32 : float -> data_item
879886

middle_end/flambda2/from_lambda/closure_conversion.ml

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,7 @@ type close_functions_result =
5252

5353
type declare_const_result =
5454
| Field of Field_of_static_block.t
55-
| Unboxed_float of Numeric_types.Float_by_bit_pattern.t
56-
| Unboxed_float32 of Numeric_types.Float32_by_bit_pattern.t
57-
| Unboxed_int32 of Numeric_types.Int32.t
58-
| Unboxed_int64 of Numeric_types.Int64.t
59-
| Unboxed_nativeint of Targetint_32_64.t
55+
| Unboxed_number of Field_of_static_block.Mixed_field.Unboxed_number.t
6056

6157
let manufacture_symbol acc proposed_name =
6258
let acc, linkage_name =
@@ -113,10 +109,10 @@ let rec declare_const acc (const : Lambda.structured_constant) :
113109
acc, Field (Tagged_immediate (Targetint_31_63.of_char c)), "char"
114110
| Const_base (Const_unboxed_float c) ->
115111
let c = Numeric_types.Float_by_bit_pattern.of_string c in
116-
acc, Unboxed_float c, "unboxed_float"
112+
acc, Unboxed_number (Unboxed_float c), "unboxed_float"
117113
| Const_base (Const_unboxed_float32 c) ->
118114
let c = Numeric_types.Float32_by_bit_pattern.of_string c in
119-
acc, Unboxed_float32 c, "unboxed_float32"
115+
acc, Unboxed_number (Unboxed_float32 c), "unboxed_float32"
120116
| Const_base (Const_string (s, _, _)) ->
121117
register_const acc (SC.immutable_string s) "immstring"
122118
| Const_base (Const_float c) ->
@@ -133,12 +129,14 @@ let rec declare_const acc (const : Lambda.structured_constant) :
133129
(* CR pchambart: this should be pushed further to lambda *)
134130
let c = Targetint_32_64.of_int64 (Int64.of_nativeint c) in
135131
register_const acc (SC.boxed_nativeint (Const c)) "nativeint"
136-
| Const_base (Const_unboxed_int32 c) -> acc, Unboxed_int32 c, "unboxed_int32"
137-
| Const_base (Const_unboxed_int64 c) -> acc, Unboxed_int64 c, "unboxed_int64"
132+
| Const_base (Const_unboxed_int32 c) ->
133+
acc, Unboxed_number (Unboxed_int32 c), "unboxed_int32"
134+
| Const_base (Const_unboxed_int64 c) ->
135+
acc, Unboxed_number (Unboxed_int64 c), "unboxed_int64"
138136
| Const_base (Const_unboxed_nativeint c) ->
139137
(* CR pchambart: this should be pushed further to lambda *)
140138
let c = Targetint_32_64.of_int64 (Int64.of_nativeint c) in
141-
acc, Unboxed_nativeint c, "unboxed_nativeint"
139+
acc, Unboxed_number (Unboxed_nativeint c), "unboxed_nativeint"
142140
| Const_immstring c -> register_const acc (SC.immutable_string c) "immstring"
143141
| Const_float_block c ->
144142
register_const acc
@@ -169,8 +167,7 @@ let rec declare_const acc (const : Lambda.structured_constant) :
169167
let acc, f, _ = declare_const acc c in
170168
match f with
171169
| Field f -> acc, f
172-
| Unboxed_float _ | Unboxed_float32 _ | Unboxed_int32 _
173-
| Unboxed_int64 _ | Unboxed_nativeint _ ->
170+
| Unboxed_number _ ->
174171
Misc.fatal_errorf
175172
"Unboxed constants are not allowed inside of Const_block: %a"
176173
Printlambda.structured_constant const)
@@ -180,6 +177,23 @@ let rec declare_const acc (const : Lambda.structured_constant) :
180177
SC.block (Tag.Scannable.create_exn tag) Immutable field_of_blocks
181178
in
182179
register_const acc const "const_block"
180+
| Const_mixed_block (tag, shape, consts) ->
181+
let shape = K.Mixed_block_shape.from_lambda shape in
182+
let acc, field_of_blocks =
183+
List.fold_left_map
184+
(fun acc c : (_ * Field_of_static_block.Mixed_field.t) ->
185+
let acc, f, _ = declare_const acc c in
186+
match f with
187+
| Field f -> acc, Value f
188+
| Unboxed_number num -> acc, Unboxed_number num)
189+
acc consts
190+
in
191+
let const : SC.t =
192+
SC.mixed_block
193+
(Tag.Scannable.create_exn tag)
194+
Immutable shape field_of_blocks
195+
in
196+
register_const acc const "const_mixed_block"
183197

184198
let close_const0 acc (const : Lambda.structured_constant) =
185199
let acc, const, name = declare_const acc const in
@@ -189,27 +203,27 @@ let close_const0 acc (const : Lambda.structured_constant) =
189203
Simple.const (Reg_width_const.tagged_immediate i),
190204
name,
191205
Flambda_kind.With_subkind.tagged_immediate )
192-
| Unboxed_float f ->
206+
| Unboxed_number (Unboxed_float f) ->
193207
( acc,
194208
Simple.const (Reg_width_const.naked_float f),
195209
name,
196210
Flambda_kind.With_subkind.naked_float )
197-
| Unboxed_float32 f ->
211+
| Unboxed_number (Unboxed_float32 f) ->
198212
( acc,
199213
Simple.const (Reg_width_const.naked_float32 f),
200214
name,
201215
Flambda_kind.With_subkind.naked_float32 )
202-
| Unboxed_int32 i ->
216+
| Unboxed_number (Unboxed_int32 i) ->
203217
( acc,
204218
Simple.const (Reg_width_const.naked_int32 i),
205219
name,
206220
Flambda_kind.With_subkind.naked_int32 )
207-
| Unboxed_int64 i ->
221+
| Unboxed_number (Unboxed_int64 i) ->
208222
( acc,
209223
Simple.const (Reg_width_const.naked_int64 i),
210224
name,
211225
Flambda_kind.With_subkind.naked_int64 )
212-
| Unboxed_nativeint i ->
226+
| Unboxed_number (Unboxed_nativeint i) ->
213227
( acc,
214228
Simple.const (Reg_width_const.naked_nativeint i),
215229
name,

middle_end/flambda2/from_lambda/closure_conversion_aux.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,8 @@ module Acc = struct
485485
let declared_symbols = (symbol, constant) :: t.declared_symbols in
486486
let approx : _ Value_approximation.t =
487487
match (constant : Static_const.t) with
488+
(* CR layouts v5.9: Support cross-module inlining for mixed blocks. *)
489+
| Mixed_block _ -> Value_unknown
488490
| Block (tag, mut, fields) ->
489491
if not (Mutability.is_mutable mut)
490492
then

middle_end/flambda2/parser/flambda_to_fexpr.ml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,9 @@ let static_const env (sc : Static_const.t) : Fexpr.static_data =
698698
let tag = tag |> Tag.Scannable.to_int in
699699
let elements = List.map (field_of_block env) fields in
700700
Block { tag; mutability; elements }
701+
| Mixed_block _ ->
702+
Misc.fatal_error
703+
"fexpr support for statically-allocated mixed blocks not yet implemented"
701704
| Set_of_closures _ -> assert false
702705
| Boxed_float32 f -> Boxed_float32 (or_variable float32 env f)
703706
| Boxed_float f -> Boxed_float (or_variable float env f)

middle_end/flambda2/simplify/rebuilt_static_const.ml

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,18 +103,29 @@ let create_set_of_closures are_rebuilding set =
103103
free_names
104104
}
105105

106+
let free_names_of_fields fields free_names_of_field =
107+
ListLabels.fold_left fields ~init:Name_occurrences.empty
108+
~f:(fun free_names field ->
109+
Name_occurrences.union free_names (free_names_of_field field))
110+
106111
let create_block are_rebuilding tag is_mutable ~fields =
107112
if ART.do_not_rebuild_terms are_rebuilding
108113
then
109114
let free_names =
110-
ListLabels.fold_left fields ~init:Name_occurrences.empty
111-
~f:(fun free_names field ->
112-
Name_occurrences.union free_names
113-
(Field_of_static_block.free_names field))
115+
free_names_of_fields fields Field_of_static_block.free_names
114116
in
115117
Block_not_rebuilt { free_names }
116118
else create_normal_non_code (SC.block tag is_mutable fields)
117119

120+
let create_mixed_block are_rebuilding tag is_mutable shape ~fields =
121+
if ART.do_not_rebuild_terms are_rebuilding
122+
then
123+
let free_names =
124+
free_names_of_fields fields Field_of_static_block.Mixed_field.free_names
125+
in
126+
Block_not_rebuilt { free_names }
127+
else create_normal_non_code (SC.mixed_block tag is_mutable shape fields)
128+
118129
let create_boxed_float32 are_rebuilding or_var =
119130
if ART.do_not_rebuild_terms are_rebuilding
120131
then Block_not_rebuilt { free_names = Or_variable.free_names or_var }
@@ -224,8 +235,8 @@ let map_set_of_closures t ~f =
224235
(SC.set_of_closures set_of_closures);
225236
free_names = Set_of_closures.free_names set_of_closures
226237
}
227-
| Block _ | Boxed_float _ | Boxed_float32 _ | Boxed_int32 _
228-
| Boxed_int64 _ | Boxed_vec128 _ | Boxed_nativeint _
238+
| Block _ | Mixed_block _ | Boxed_float _ | Boxed_float32 _
239+
| Boxed_int32 _ | Boxed_int64 _ | Boxed_vec128 _ | Boxed_nativeint _
229240
| Immutable_float_block _ | Immutable_float_array _
230241
| Immutable_float32_array _ | Immutable_int32_array _
231242
| Immutable_int64_array _ | Immutable_nativeint_array _

middle_end/flambda2/simplify/rebuilt_static_const.mli

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ val create_block :
4747
fields:Field_of_static_block.t list ->
4848
t
4949

50+
val create_mixed_block :
51+
Are_rebuilding_terms.t ->
52+
Tag.Scannable.t ->
53+
Mutability.t ->
54+
Flambda_kind.Mixed_block_shape.t ->
55+
fields:Field_of_static_block.Mixed_field.t list ->
56+
t
57+
5058
val create_boxed_float32 :
5159
Are_rebuilding_terms.t ->
5260
Numeric_types.Float32_by_bit_pattern.t Or_variable.t ->

middle_end/flambda2/simplify/simplify_static_const.ml

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,24 @@ let simplify_field_of_block dacc (field : Field_of_static_block.t) =
4141
(* CR mshinwell: This should be "invalid" and propagate up *)
4242
field, ty)
4343

44+
let simplify_field_of_mixed_block dacc
45+
(field : Field_of_static_block.Mixed_field.t) :
46+
Field_of_static_block.Mixed_field.t * _ =
47+
match field with
48+
| Value value ->
49+
let value', ty = simplify_field_of_block dacc value in
50+
(if value == value' then field else Value value'), ty
51+
| Unboxed_number num ->
52+
let ty =
53+
match num with
54+
| Unboxed_float _ -> T.any_naked_float
55+
| Unboxed_float32 _ -> T.any_naked_float32
56+
| Unboxed_int32 _ -> T.any_naked_int32
57+
| Unboxed_int64 _ -> T.any_naked_int64
58+
| Unboxed_nativeint _ -> T.any_naked_nativeint
59+
in
60+
field, ty
61+
4462
let simplify_or_variable dacc type_for_const (or_variable : _ Or_variable.t)
4563
kind =
4664
let denv = DA.denv dacc in
@@ -65,6 +83,19 @@ let rebuild_naked_number_array dacc ~bind_result_sym kind type_creator creator
6583
in
6684
creator (DA.are_rebuilding_terms dacc) fields, dacc
6785

86+
let simplify_static_const_block_type ~tag ~fields ~shape
87+
~(is_mutable : Mutability.t) =
88+
(* Same as Simplify_variadic_primitive.simplify_make_block_of_values *)
89+
let tag = Tag.Scannable.to_tag tag in
90+
match is_mutable with
91+
| Immutable ->
92+
T.immutable_block ~is_unique:false tag ~shape ~fields
93+
Alloc_mode.For_types.heap
94+
| Immutable_unique ->
95+
T.immutable_block ~is_unique:true tag ~shape ~fields
96+
Alloc_mode.For_types.heap
97+
| Mutable -> T.any_value
98+
6899
let simplify_static_const_of_kind_value dacc (static_const : Static_const.t)
69100
~result_sym : Rebuilt_static_const.t * DA.t =
70101
let bind_result_sym typ =
@@ -79,23 +110,28 @@ let simplify_static_const_of_kind_value dacc (static_const : Static_const.t)
79110
in
80111
let fields, field_tys = List.split fields_with_tys in
81112
let ty =
82-
(* Same as Simplify_variadic_primitive.simplify_make_block_of_values *)
83-
let tag = Tag.Scannable.to_tag tag in
84-
let fields = field_tys in
85-
match is_mutable with
86-
| Immutable ->
87-
T.immutable_block ~is_unique:false tag ~shape:K.Block_shape.Value_only
88-
~fields Alloc_mode.For_types.heap
89-
| Immutable_unique ->
90-
T.immutable_block ~is_unique:true tag ~shape:K.Block_shape.Value_only
91-
~fields Alloc_mode.For_types.heap
92-
| Mutable -> T.any_value
113+
simplify_static_const_block_type ~tag ~fields:field_tys ~shape:Value_only
114+
~is_mutable
93115
in
94116
let dacc = bind_result_sym ty in
95117
( Rebuilt_static_const.create_block
96118
(DA.are_rebuilding_terms dacc)
97119
tag is_mutable ~fields,
98120
dacc )
121+
| Mixed_block (tag, is_mutable, shape, fields) ->
122+
let fields_with_tys =
123+
List.map (fun field -> simplify_field_of_mixed_block dacc field) fields
124+
in
125+
let fields, field_tys = List.split fields_with_tys in
126+
let ty =
127+
simplify_static_const_block_type ~tag ~fields:field_tys
128+
~shape:(Mixed_record shape) ~is_mutable
129+
in
130+
let dacc = bind_result_sym ty in
131+
( Rebuilt_static_const.create_mixed_block
132+
(DA.are_rebuilding_terms dacc)
133+
tag is_mutable shape ~fields,
134+
dacc )
99135
| Boxed_float32 or_var ->
100136
let or_var, ty =
101137
simplify_or_variable dacc

0 commit comments

Comments
 (0)