From bc70ebf5ebb0b24fec8ddcce58ced84be6b500f0 Mon Sep 17 00:00:00 2001 From: Guillaume Bury Date: Tue, 11 Mar 2025 15:34:13 +0100 Subject: [PATCH 1/5] Add new primitives to create blocks for lazy values This adds a new primitive in Lambda and Flambda2 to create a block for a (not short-circuited) lazy value. These primitives allow to more systematically handle lazy blocks correctly, for instance with respect to the value-let-rec size computation, and in flambda to better ensure that we do not track block appromixations for lazy values (without relying on the frontend to insert opaque identities). --- bug.ml | 9 +++ bytecomp/bytegen.ml | 11 +++- lambda/lambda.ml | 10 +++- lambda/lambda.mli | 5 ++ lambda/matching.ml | 2 +- lambda/printlambda.ml | 5 ++ lambda/tmc.ml | 3 + lambda/translcore.ml | 12 ++-- lambda/translprim.ml | 2 +- lambda/value_rec_compiler.ml | 2 +- .../from_lambda/closure_conversion.ml | 3 +- .../lambda_to_flambda_primitives.ml | 5 +- .../flambda2/parser/flambda_to_fexpr.ml | 2 +- .../simplify/simplify_unary_primitive.ml | 7 +++ middle_end/flambda2/terms/code_size.ml | 1 + .../flambda2/terms/flambda_primitive.ml | 59 +++++++++++++++++-- .../flambda2/terms/flambda_primitive.mli | 13 ++++ .../flambda2/to_cmm/to_cmm_primitive.ml | 4 ++ testsuite/tests/lazy/lazy9.ml | 37 ++++++++++++ testsuite/tests/lazy/lazy9.reference | 0 20 files changed, 171 insertions(+), 21 deletions(-) create mode 100644 bug.ml create mode 100644 testsuite/tests/lazy/lazy9.ml create mode 100644 testsuite/tests/lazy/lazy9.reference diff --git a/bug.ml b/bug.ml new file mode 100644 index 00000000000..1e8629a247f --- /dev/null +++ b/bug.ml @@ -0,0 +1,9 @@ + +type t = + | C of t Lazy.t Lazy.t + +let rec x = + let y = (lazy (C x)) in + lazy y + + diff --git a/bytecomp/bytegen.ml b/bytecomp/bytegen.ml index 81edccec5c4..cfe8d14b3e9 100644 --- a/bytecomp/bytegen.ml +++ b/bytecomp/bytegen.ml @@ -153,7 +153,7 @@ let preserve_tailcall_for_prim = function | Pget_header _ | Pignore | Pgetglobal _ | Psetglobal _ | Pgetpredef _ - | Pmakeblock _ | Pmakefloatblock _ | Pmakeufloatblock _ | Pmakemixedblock _ + | Pmakeblock _ | Pmakefloatblock _ | Pmakeufloatblock _ | Pmakemixedblock _ | Pmakelazyblock _ | Pfield _ | Pfield_computed _ | Psetfield _ | Psetfield_computed _ | Pfloatfield _ | Psetfloatfield _ | Pduprecord _ | Pufloatfield _ | Psetufloatfield _ | Pmixedfield _ | Psetmixedfield _ @@ -741,6 +741,7 @@ let comp_primitive stack_info p sz args = | Pmakefloatblock _ | Pmakeufloatblock _ | Pmakemixedblock _ + | Pmakelazyblock _ | Pprobe_is_enabled _ | Punbox_float _ | Pbox_float (_, _) | Punbox_int _ | Pbox_int _ -> @@ -1137,6 +1138,14 @@ and comp_expr stack_info env exp sz cont = let cont = add_pseudo_event loc !compunit_name cont in comp_args stack_info env args sz (Kmakeblock(List.length args, tag) :: cont) + | Lprim (Pmakelazyblock (Lazy_tag, _), args, loc) -> + let cont = add_pseudo_event loc !compunit_name cont in + comp_args stack_info env args sz + (Kmakeblock(List.length args, Config.lazy_tag) :: cont) + | Lprim (Pmakelazyblock (Forward_tag, _), args, loc) -> + let cont = add_pseudo_event loc !compunit_name cont in + comp_args stack_info env args sz + (Kmakeblock(List.length args, Obj.forward_tag) :: cont) | Lprim(Pmake_unboxed_product _, args, loc) -> let cont = add_pseudo_event loc !compunit_name cont in comp_args stack_info env args sz diff --git a/lambda/lambda.ml b/lambda/lambda.ml index f1488532dcf..2b329aca25a 100644 --- a/lambda/lambda.ml +++ b/lambda/lambda.ml @@ -124,6 +124,10 @@ type region_close = | Rc_nontail | Rc_close_at_apply +type lazy_block_tag = + | Lazy_tag + | Forward_tag + type primitive = | Pbytes_to_string | Pbytes_of_string @@ -137,6 +141,7 @@ type primitive = | Pmakefloatblock of mutable_flag * locality_mode | Pmakeufloatblock of mutable_flag * locality_mode | Pmakemixedblock of int * mutable_flag * mixed_block_shape * locality_mode + | Pmakelazyblock of lazy_block_tag * locality_mode | Pfield of int * immediate_or_pointer * field_read_semantics | Pfield_computed of field_read_semantics | Psetfield of int * immediate_or_pointer * initialization_or_assignment @@ -1823,6 +1828,7 @@ let primitive_may_allocate : primitive -> locality_mode option = function | Pmakefloatblock (_, m) -> Some m | Pmakeufloatblock (_, m) -> Some m | Pmakemixedblock (_, _, _, m) -> Some m + | Pmakelazyblock (_, m) -> Some m | Pfield _ | Pfield_computed _ | Psetfield _ | Psetfield_computed _ -> None | Pfloatfield (_, _, m) -> Some m | Pufloatfield _ -> None @@ -2056,7 +2062,7 @@ let primitive_can_raise prim = | Pmakefloatblock _ | Pfield _ | Pfield_computed _ | Psetfield _ | Psetfield_computed _ | Pfloatfield _ | Psetfloatfield _ | Pduprecord _ | Pmakeufloatblock _ | Pufloatfield _ | Psetufloatfield _ | Psequand | Psequor - | Pmixedfield _ | Psetmixedfield _ | Pmakemixedblock _ | Pnot | Pnegint + | Pmixedfield _ | Psetmixedfield _ | Pmakemixedblock _ | Pmakelazyblock _ | Pnot | Pnegint | Paddint | Psubint | Pmulint | Pandint | Porint | Pxorint | Plslint | Plsrint | Pasrint | Pintcomp _ | Pcompare_ints | Pcompare_floats _ | Pcompare_bints _ | Poffsetint _ | Poffsetref _ | Pintoffloat _ @@ -2254,7 +2260,7 @@ let primitive_result_layout (p : primitive) = -> layout_unit | Pgetglobal _ | Psetglobal _ | Pgetpredef _ -> layout_module_field | Pmakeblock _ | Pmakefloatblock _ | Pmakearray _ | Pmakearray_dynamic _ - | Pduprecord _ | Pmakeufloatblock _ | Pmakemixedblock _ + | Pduprecord _ | Pmakeufloatblock _ | Pmakemixedblock _ | Pmakelazyblock _ | Pduparray _ | Pbigarraydim _ | Pobj_dup -> layout_block | Pfield _ | Pfield_computed _ -> layout_value_field | Punboxed_product_field (field, layouts) -> (Array.of_list layouts).(field) diff --git a/lambda/lambda.mli b/lambda/lambda.mli index ffa24714465..2a83038fd4b 100644 --- a/lambda/lambda.mli +++ b/lambda/lambda.mli @@ -104,6 +104,10 @@ type region_close = tail call because the outer region needs to end there.) *) +type lazy_block_tag = + | Lazy_tag + | Forward_tag + (* CR layouts v5: When we add more blocks of non-scannable values, consider whether some of the primitives specific to ufloat records ([Pmakeufloatblock], [Pufloatfield], and [Psetufloatfield]) can/should be @@ -121,6 +125,7 @@ type primitive = | Pmakefloatblock of mutable_flag * locality_mode | Pmakeufloatblock of mutable_flag * locality_mode | Pmakemixedblock of int * mutable_flag * mixed_block_shape * locality_mode + | Pmakelazyblock of lazy_block_tag * locality_mode | Pfield of int * immediate_or_pointer * field_read_semantics | Pfield_computed of field_read_semantics | Psetfield of int * immediate_or_pointer * initialization_or_assignment diff --git a/lambda/matching.ml b/lambda/matching.ml index 8ca101b7242..aedc2c915c3 100644 --- a/lambda/matching.ml +++ b/lambda/matching.ml @@ -2124,7 +2124,7 @@ let inline_lazy_force_cond arg pos loc = ( Strict, Lambda.layout_lazy, idarg, - arg, + Lprim (Popaque Lambda.layout_lazy, [arg], loc), Llet ( Alias, Lambda.layout_int, diff --git a/lambda/printlambda.ml b/lambda/printlambda.ml index 571a9e8648f..7a4102b280f 100644 --- a/lambda/printlambda.ml +++ b/lambda/printlambda.ml @@ -469,6 +469,10 @@ let primitive ppf = function | Pmakemixedblock (tag, Mutable, abs, mode) -> fprintf ppf "make%amixedblock %i Mutable%a" locality_mode mode tag (mixed_block_shape (fun _ _ -> ())) abs + | Pmakelazyblock (Lazy_tag, mode) -> + fprintf ppf "make%alazyblock" locality_mode mode + | Pmakelazyblock (Forward_tag, mode) -> + fprintf ppf "make%aforwardblock" locality_mode mode | Pfield (n, ptr, sem) -> let instr = match ptr, sem with @@ -918,6 +922,7 @@ let name_of_primitive = function | Pmakefloatblock _ -> "Pmakefloatblock" | Pmakeufloatblock _ -> "Pmakeufloatblock" | Pmakemixedblock _ -> "Pmakemixedblock" + | Pmakelazyblock _ -> "Pmakelazyblock" | Pfield _ -> "Pfield" | Pfield_computed _ -> "Pfield_computed" | Psetfield _ -> "Psetfield" diff --git a/lambda/tmc.ml b/lambda/tmc.ml index 39d0f68d057..1fe9dfae161 100644 --- a/lambda/tmc.ml +++ b/lambda/tmc.ml @@ -910,6 +910,9 @@ let rec choice ctx t = | Punbox_int _ | Pbox_int _ | Punbox_vector _ | Pbox_vector (_, _) + (* it doesn't seem worth it to support lazy blocks for tmc *) + | Pmakelazyblock _ + (* we don't handle array indices as destinations yet *) | (Pmakearray _ | Pduparray _ | Pmakearray_dynamic _) diff --git a/lambda/translcore.ml b/lambda/translcore.ml index 4b82dede9bf..a95a0a1a8f8 100644 --- a/lambda/translcore.ml +++ b/lambda/translcore.ml @@ -1012,8 +1012,7 @@ and transl_exp0 ~in_new_scope ~scopes sort e = (* We don't need to wrap with Popaque: this forward block will never be shortcutted since it points to a float and Config.flat_float_array is true. *) - Lprim(Pmakeblock(Obj.forward_tag, Immutable, None, - alloc_heap), + Lprim(Pmakelazyblock(Forward_tag, alloc_heap), [transl_exp ~scopes Jkind.Sort.Const.for_lazy_body e], of_location ~scopes e.exp_loc) | `Identifier `Forward_value -> @@ -1023,11 +1022,8 @@ and transl_exp0 ~in_new_scope ~scopes sort e = optimisation in Flambda, but the concept of a mutable block doesn't really match what is going on here. This value may subsequently turn into an immediate... *) - Lprim (Popaque Lambda.layout_lazy, - [Lprim(Pmakeblock(Obj.forward_tag, Immutable, None, - alloc_heap), - [transl_exp ~scopes Jkind.Sort.Const.for_lazy_body e], - of_location ~scopes e.exp_loc)], + Lprim(Pmakelazyblock(Forward_tag, alloc_heap), + [transl_exp ~scopes Jkind.Sort.Const.for_lazy_body e], of_location ~scopes e.exp_loc) | `Identifier `Other -> transl_exp ~scopes Jkind.Sort.Const.for_lazy_body e @@ -1053,7 +1049,7 @@ and transl_exp0 ~in_new_scope ~scopes sort e = Lambda.layout_lazy_contents (transl_exp ~scopes Jkind.Sort.Const.for_lazy_body e)) in - Lprim(Pmakeblock(Config.lazy_tag, Mutable, None, alloc_heap), [fn], + Lprim(Pmakelazyblock(Lazy_tag, alloc_heap), [fn], of_location ~scopes e.exp_loc) end | Texp_object (cs, meths) -> diff --git a/lambda/translprim.ml b/lambda/translprim.ml index 16d0753a84e..158e2ac4a74 100644 --- a/lambda/translprim.ml +++ b/lambda/translprim.ml @@ -1929,7 +1929,7 @@ let lambda_primitive_needs_event_after = function | Parray_to_iarray | Parray_of_iarray | Pignore | Psetglobal _ | Pgetglobal _ | Pgetpredef _ | Pmakeblock _ | Pmakefloatblock _ - | Pmakeufloatblock _ | Pmakemixedblock _ + | Pmakeufloatblock _ | Pmakemixedblock _ | Pmakelazyblock _ | Pmake_unboxed_product _ | Punboxed_product_field _ | Parray_element_size_in_bytes _ | Pfield _ | Pfield_computed _ | Psetfield _ diff --git a/lambda/value_rec_compiler.ml b/lambda/value_rec_compiler.ml index 2f7acaefa25..24ebe75634e 100644 --- a/lambda/value_rec_compiler.ml +++ b/lambda/value_rec_compiler.ml @@ -245,7 +245,7 @@ let compute_static_size lam = | Record_inlined (_, _, (Variant_unboxed | Variant_with_null)) -> Misc.fatal_error "size_of_primitive" end - | Pmakeblock _ -> + | Pmakeblock _ | Pmakelazyblock _ -> (* The block shape is unfortunately an option, so we rely on the number of arguments instead. Note that flat float arrays/records use Pmakearray, so we don't need diff --git a/middle_end/flambda2/from_lambda/closure_conversion.ml b/middle_end/flambda2/from_lambda/closure_conversion.ml index 9e21c2e9a63..18dd7fcf9cf 100644 --- a/middle_end/flambda2/from_lambda/closure_conversion.ml +++ b/middle_end/flambda2/from_lambda/closure_conversion.ml @@ -1053,7 +1053,8 @@ let close_primitive acc env ~let_bound_ids_with_kinds named | Patomic_fetch_add | Patomic_add | Patomic_sub | Patomic_land | Patomic_lor | Patomic_lxor | Pdls_get | Ppoll | Patomic_load _ | Patomic_set _ | Preinterpret_tagged_int63_as_unboxed_int64 - | Preinterpret_unboxed_int64_as_tagged_int63 | Ppeek _ | Ppoke _ -> + | Preinterpret_unboxed_int64_as_tagged_int63 | Ppeek _ | Ppoke _ + | Pmakelazyblock _ -> (* Inconsistent with outer match *) assert false in diff --git a/middle_end/flambda2/from_lambda/lambda_to_flambda_primitives.ml b/middle_end/flambda2/from_lambda/lambda_to_flambda_primitives.ml index 39ef2582fe2..9452a71ea3e 100644 --- a/middle_end/flambda2/from_lambda/lambda_to_flambda_primitives.ml +++ b/middle_end/flambda2/from_lambda/lambda_to_flambda_primitives.ml @@ -1382,6 +1382,9 @@ let convert_lprim ~big_endian (prim : L.primitive) (args : Simple.t list list) let shape = convert_block_shape shape ~num_fields:(List.length args) in let mutability = Mutability.from_lambda mutability in [Variadic (Make_block (Values (tag, shape), mutability, mode), args)] + | Pmakelazyblock (lazy_tag, mode), [[arg]] -> + let mode = Alloc_mode.For_allocations.from_lambda mode ~current_region in + [Unary (Make_lazy (lazy_tag, mode), arg)] | Pmake_unboxed_product layouts, _ -> (* CR mshinwell: this should check the unarized lengths of [layouts] and [args] (like [Parray_element_size_in_bytes] below) *) @@ -2492,7 +2495,7 @@ let convert_lprim ~big_endian (prim : L.primitive) (args : Simple.t list list) | Pufloatfield _ | Patomic_load _ | Pmixedfield _ | Preinterpret_unboxed_int64_as_tagged_int63 | Preinterpret_tagged_int63_as_unboxed_int64 - | Parray_element_size_in_bytes _ | Ppeek _ ), + | Parray_element_size_in_bytes _ | Ppeek _ | Pmakelazyblock _ ), ([] | _ :: _ :: _ | [([] | _ :: _ :: _)]) ) -> Misc.fatal_errorf "Closure_conversion.convert_primitive: Wrong arity for unary primitive \ diff --git a/middle_end/flambda2/parser/flambda_to_fexpr.ml b/middle_end/flambda2/parser/flambda_to_fexpr.ml index 52adfce0c8a..211601ff5d5 100644 --- a/middle_end/flambda2/parser/flambda_to_fexpr.ml +++ b/middle_end/flambda2/parser/flambda_to_fexpr.ml @@ -582,7 +582,7 @@ let unop env (op : Flambda_primitive.unary_primitive) : Fexpr.unop = | Boolean_not -> Boolean_not | Int_as_pointer _ | Duplicate_block _ | Duplicate_array _ | Bigarray_length _ | Float_arith _ | Reinterpret_64_bit_word _ | Is_boxed_float | Obj_dup - | Get_header | Atomic_load _ | Peek _ -> + | Get_header | Atomic_load _ | Peek _ | Make_lazy _ -> Misc.fatal_errorf "TODO: Unary primitive: %a" Flambda_primitive.Without_args.print (Flambda_primitive.Without_args.Unary op) diff --git a/middle_end/flambda2/simplify/simplify_unary_primitive.ml b/middle_end/flambda2/simplify/simplify_unary_primitive.ml index 54d3ea9b4cf..311d9f5a385 100644 --- a/middle_end/flambda2/simplify/simplify_unary_primitive.ml +++ b/middle_end/flambda2/simplify/simplify_unary_primitive.ml @@ -888,6 +888,12 @@ let simplify_mutable_block_load _access_kind ~field:_ ~original_prim dacc (P.result_kind' original_prim) ~original_term +let simplify_lazy ~original_prim dacc ~original_term ~arg:_ ~arg_ty:_ + ~result_var = + SPR.create_unknown dacc ~result_var + (P.result_kind' original_prim) + ~original_term + (* CR layouts v3: implement a real simplifier. *) let simplify_is_null dacc ~original_term ~arg:scrutinee ~arg_ty:scrutinee_ty ~result_var = @@ -962,5 +968,6 @@ let simplify_unary_primitive dacc original_prim (prim : P.unary_primitive) ~arg | Atomic_load block_access_field_kind -> simplify_atomic_load block_access_field_kind ~original_prim | Peek _ -> simplify_peek ~original_prim + | Make_lazy _ -> simplify_lazy ~original_prim in simplifier dacc ~original_term ~arg ~arg_ty ~result_var diff --git a/middle_end/flambda2/terms/code_size.ml b/middle_end/flambda2/terms/code_size.ml index 2ec09c6ce22..3cd413732f5 100644 --- a/middle_end/flambda2/terms/code_size.ml +++ b/middle_end/flambda2/terms/code_size.ml @@ -380,6 +380,7 @@ let unary_prim_size prim = | Obj_dup -> needs_caml_c_call_extcall_size + 1 | Get_header -> 2 | Atomic_load _ | Peek _ -> 1 + | Make_lazy (_, _alloc_mode) -> alloc_size let binary_prim_size prim = match (prim : Flambda_primitive.binary_primitive) with diff --git a/middle_end/flambda2/terms/flambda_primitive.ml b/middle_end/flambda2/terms/flambda_primitive.ml index 9c4171f94a0..bee3c242775 100644 --- a/middle_end/flambda2/terms/flambda_primitive.ml +++ b/middle_end/flambda2/terms/flambda_primitive.ml @@ -25,6 +25,26 @@ type classification_for_printing = | Destructive | Neither +module Lazy_block_tag = struct + type t = Lambda.lazy_block_tag = + | Lazy_tag + | Forward_tag + + let print ppf t = + match t with + | Lazy_tag -> Format.fprintf ppf "Lazy_block" + | Forward_tag -> Format.fprintf ppf "Forward_block" + + let compare t1 t2 = + match t1, t2 with + | Lazy_tag, Lazy_tag | Forward_tag, Forward_tag -> 0 + | Lazy_tag, Forward_tag -> -1 + | Forward_tag, Lazy_tag -> 1 + + let to_tag t = + match t with Lazy_tag -> Tag.lazy_tag | Forward_tag -> Tag.forward_tag +end + module Block_kind = struct type t = | Values of Tag.Scannable.t * K.With_subkind.t list @@ -57,7 +77,7 @@ module Block_kind = struct @[(shape@ @[(%a)@])@])@]" Tag.Scannable.print tag (Format.pp_print_list ~pp_sep:Format.pp_print_space - K.print) (Array.to_list (K.Mixed_block_shape.field_kinds shape)) + K.print) (Array.to_list (K.Mixed_block_shape.field_kinds shape)) let compare t1 t2 = match t1, t2 with @@ -1060,6 +1080,7 @@ type unary_primitive = | Get_header | Atomic_load of Block_access_field_kind.t | Peek of Flambda_kind.Standard_int_or_float.t + | Make_lazy of Lazy_block_tag.t * Alloc_mode.For_allocations.t (* Here and below, operations that are genuine projections shouldn't be eligible for CSE, since we deal with projections through types. *) @@ -1091,7 +1112,9 @@ let unary_primitive_eligible_for_cse p ~arg = Simple.is_var arg | Project_function_slot _ | Project_value_slot _ -> false | Is_boxed_float | Is_flat_float_array -> true - | End_region _ | End_try_region _ | Obj_dup | Atomic_load _ | Peek _ -> false + | End_region _ | End_try_region _ | Obj_dup | Atomic_load _ | Peek _ + | Make_lazy _ -> + false let compare_unary_primitive p1 p2 = let unary_primitive_numbering p = @@ -1126,6 +1149,7 @@ let compare_unary_primitive p1 p2 = | Atomic_load _ -> 27 | Is_null -> 28 | Peek _ -> 29 + | Make_lazy _ -> 30 in match p1, p2 with | ( Block_load { kind = kind1; mut = mut1; field = field1 }, @@ -1212,6 +1236,11 @@ let compare_unary_primitive p1 p2 = Bool.compare ghost1 ghost2 | Peek kind1, Peek kind2 -> Flambda_kind.Standard_int_or_float.compare kind1 kind2 + | Make_lazy (lazy_tag1, alloc_mode1), Make_lazy (lazy_tag2, alloc_mode2) -> + let c = Lazy_block_tag.compare lazy_tag1 lazy_tag2 in + if c <> 0 + then c + else Alloc_mode.For_allocations.compare alloc_mode1 alloc_mode2 | ( ( Block_load _ | Duplicate_array _ | Duplicate_block _ | Is_int _ | Is_null | Get_tag | String_length _ | Int_as_pointer _ | Opaque_identity _ | Int_arith _ | Num_conv _ | Boolean_not @@ -1219,7 +1248,7 @@ let compare_unary_primitive p1 p2 = | Bigarray_length _ | Unbox_number _ | Box_number _ | Untag_immediate | Tag_immediate | Project_function_slot _ | Project_value_slot _ | Is_boxed_float | Is_flat_float_array | End_region _ | End_try_region _ - | Obj_dup | Get_header | Atomic_load _ | Peek _ ), + | Obj_dup | Get_header | Atomic_load _ | Peek _ | Make_lazy _ ), _ ) -> Stdlib.compare (unary_primitive_numbering p1) (unary_primitive_numbering p2) @@ -1289,6 +1318,9 @@ let print_unary_primitive ppf p = | Peek kind -> fprintf ppf "@[(Peek@ %a)@]" Flambda_kind.Standard_int_or_float.print_lowercase kind + | Make_lazy (lazy_tag, alloc_mode) -> + fprintf ppf "@[(Make_lazy@ %a@ %a)@]" Lazy_block_tag.print lazy_tag + Alloc_mode.For_allocations.print alloc_mode let arg_kind_of_unary_primitive p = match p with @@ -1324,6 +1356,7 @@ let arg_kind_of_unary_primitive p = | Get_header -> K.value | Atomic_load _ -> K.value | Peek _ -> K.naked_nativeint + | Make_lazy _ -> K.value let result_kind_of_unary_primitive p : result_kind = match p with @@ -1362,6 +1395,7 @@ let result_kind_of_unary_primitive p : result_kind = | Get_header -> Singleton K.naked_nativeint | Atomic_load _ -> Singleton K.value | Peek kind -> Singleton (K.Standard_int_or_float.to_kind kind) + | Make_lazy _ -> Singleton K.value let effects_and_coeffects_of_unary_primitive p : Effects_and_coeffects.t = match p with @@ -1453,6 +1487,13 @@ let effects_and_coeffects_of_unary_primitive p : Effects_and_coeffects.t = | Atomic_load _ | Peek _ -> (* For the moment, prevent [Peek] from being moved. *) Arbitrary_effects, Has_coeffects, Strict + | Make_lazy (_, alloc_mode) -> + let coeffects : Coeffects.t = + match alloc_mode with + | Heap -> Coeffects.No_coeffects + | Local _ -> Coeffects.Has_coeffects + in + Effects.Only_generative_effects Mutable, coeffects, Placement.Strict let unary_classify_for_printing p = match p with @@ -1471,6 +1512,7 @@ let unary_classify_for_printing p = | End_region _ | End_try_region _ -> Neither | Get_header -> Neither | Peek _ -> Neither + | Make_lazy _ -> Constructive let free_names_unary_primitive p = match p with @@ -1495,6 +1537,8 @@ let free_names_unary_primitive p = | Atomic_load (_ : Block_access_field_kind.t) | Peek (_ : Flambda_kind.Standard_int_or_float.t) -> Name_occurrences.empty + | Make_lazy (_, alloc_mode) -> + Alloc_mode.For_allocations.free_names alloc_mode let apply_renaming_unary_primitive p renaming = match p with @@ -1508,6 +1552,11 @@ let apply_renaming_unary_primitive p renaming = Alloc_mode.For_allocations.apply_renaming alloc_mode renaming in if alloc_mode == alloc_mode' then p else Int_as_pointer alloc_mode' + | Make_lazy (tag, alloc_mode) -> + let alloc_mode' = + Alloc_mode.For_allocations.apply_renaming alloc_mode renaming + in + if alloc_mode == alloc_mode' then p else Make_lazy (tag, alloc_mode') | Block_load _ | Duplicate_array _ | Duplicate_block _ | Is_int _ | Is_null | Get_tag | String_length _ | Opaque_identity _ | Int_arith _ | Num_conv _ | Boolean_not | Reinterpret_64_bit_word _ | Float_arith _ | Array_length _ @@ -1520,7 +1569,9 @@ let apply_renaming_unary_primitive p renaming = let ids_for_export_unary_primitive p = match p with - | Box_number (_, alloc_mode) | Int_as_pointer alloc_mode -> + | Box_number (_, alloc_mode) + | Int_as_pointer alloc_mode + | Make_lazy (_, alloc_mode) -> Alloc_mode.For_allocations.ids_for_export alloc_mode | Block_load _ | Duplicate_array _ | Duplicate_block _ | Is_int _ | Is_null | Get_tag | String_length _ | Opaque_identity _ | Int_arith _ | Num_conv _ diff --git a/middle_end/flambda2/terms/flambda_primitive.mli b/middle_end/flambda2/terms/flambda_primitive.mli index 851d44b0d35..3e392a902f7 100644 --- a/middle_end/flambda2/terms/flambda_primitive.mli +++ b/middle_end/flambda2/terms/flambda_primitive.mli @@ -24,6 +24,18 @@ No primitive raises an exception. (Bounds checking is handled separately.) *) +module Lazy_block_tag : sig + type t = Lambda.lazy_block_tag = + | Lazy_tag + | Forward_tag + + val print : Format.formatter -> t -> unit + + val compare : t -> t -> int + + val to_tag : t -> Tag.t +end + module Block_kind : sig type t = | Values of Tag.Scannable.t * Flambda_kind.With_subkind.t list @@ -439,6 +451,7 @@ type unary_primitive = (* CR mshinwell: consider putting atomicity onto [Peek] and [Poke] then deleting [Atomic_load] *) | Peek of Flambda_kind.Standard_int_or_float.t + | Make_lazy of Lazy_block_tag.t * Alloc_mode.For_allocations.t (** Whether a comparison is to yield a boolean result, as given by a particular comparison operator, or whether it is to behave in the manner of "compare" diff --git a/middle_end/flambda2/to_cmm/to_cmm_primitive.ml b/middle_end/flambda2/to_cmm/to_cmm_primitive.ml index 70694e79c5b..ad381dbf1e4 100644 --- a/middle_end/flambda2/to_cmm/to_cmm_primitive.ml +++ b/middle_end/flambda2/to_cmm/to_cmm_primitive.ml @@ -989,6 +989,10 @@ let unary_primitive env res dbg f arg = |> C.memory_chunk_of_kind in None, res, C.load ~dbg memory_chunk Mutable ~addr:arg + | Make_lazy (lazy_tag, alloc_mode) -> + let mode = C.alloc_mode_for_allocations_to_cmm alloc_mode in + let tag = Tag.to_int (P.Lazy_block_tag.to_tag lazy_tag) in + None, res, C.make_alloc ~mode dbg ~tag [arg] let binary_primitive env dbg f x y = match (f : P.binary_primitive) with diff --git a/testsuite/tests/lazy/lazy9.ml b/testsuite/tests/lazy/lazy9.ml new file mode 100644 index 00000000000..746726777c4 --- /dev/null +++ b/testsuite/tests/lazy/lazy9.ml @@ -0,0 +1,37 @@ +(* TEST *) + +(* In some situations, these code snippets would cause the + let-rec size computation to raise a fatal error. *) + +(* *) +type t = + | C of t Lazy.t Lazy.t + +let rec x = + let y = (lazy (C x)) in + lazy y + +(* *) +let todo () : float = + let rec l = + let x = lazy (Lazy.force (Lazy.force l)) in + lazy x + in + Lazy.force (Lazy.force l) + +(* *) +let () = + begin match Lazy.force (Lazy.force x) with + | C _ -> () + end; + begin match todo () with + | f -> + (* trying to get the actual value of the float will cause a segfault *) + let f' = f +. 1. in + print_float f'; + print_newline () + | exception CamlinternalLazy.Undefined -> + (* this is what should happen if `todo` is compiled correctly *) + () + end; + diff --git a/testsuite/tests/lazy/lazy9.reference b/testsuite/tests/lazy/lazy9.reference new file mode 100644 index 00000000000..e69de29bb2d From ff808a60eccada902b2ea7f49dab2c12b8a2b2a7 Mon Sep 17 00:00:00 2001 From: Guillaume Bury Date: Wed, 12 Mar 2025 18:24:27 +0100 Subject: [PATCH 2/5] cleanup --- bug.ml | 9 --------- lambda/matching.ml | 2 +- 2 files changed, 1 insertion(+), 10 deletions(-) delete mode 100644 bug.ml diff --git a/bug.ml b/bug.ml deleted file mode 100644 index 1e8629a247f..00000000000 --- a/bug.ml +++ /dev/null @@ -1,9 +0,0 @@ - -type t = - | C of t Lazy.t Lazy.t - -let rec x = - let y = (lazy (C x)) in - lazy y - - diff --git a/lambda/matching.ml b/lambda/matching.ml index aedc2c915c3..8ca101b7242 100644 --- a/lambda/matching.ml +++ b/lambda/matching.ml @@ -2124,7 +2124,7 @@ let inline_lazy_force_cond arg pos loc = ( Strict, Lambda.layout_lazy, idarg, - Lprim (Popaque Lambda.layout_lazy, [arg], loc), + arg, Llet ( Alias, Lambda.layout_int, From ef243d7315c1764b8be4a77293cc657c8ada852f Mon Sep 17 00:00:00 2001 From: Vincent Laviron Date: Thu, 13 Mar 2025 15:18:22 +0100 Subject: [PATCH 3/5] Update code size of Make_lazy to match Make_block --- middle_end/flambda2/terms/code_size.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/middle_end/flambda2/terms/code_size.ml b/middle_end/flambda2/terms/code_size.ml index 3cd413732f5..0cfa5c90b1e 100644 --- a/middle_end/flambda2/terms/code_size.ml +++ b/middle_end/flambda2/terms/code_size.ml @@ -380,7 +380,7 @@ let unary_prim_size prim = | Obj_dup -> needs_caml_c_call_extcall_size + 1 | Get_header -> 2 | Atomic_load _ | Peek _ -> 1 - | Make_lazy (_, _alloc_mode) -> alloc_size + | Make_lazy _ -> alloc_size + 1 let binary_prim_size prim = match (prim : Flambda_primitive.binary_primitive) with From ea64f6c1e8c10acaaef261071416cc77bd53e37b Mon Sep 17 00:00:00 2001 From: Vincent Laviron Date: Thu, 13 Mar 2025 15:18:43 +0100 Subject: [PATCH 4/5] Remove allocation mode from lazy primitives --- bytecomp/bytegen.ml | 4 +- lambda/lambda.ml | 4 +- lambda/lambda.mli | 2 +- lambda/printlambda.ml | 8 ++-- lambda/translcore.ml | 6 +-- .../lambda_to_flambda_primitives.ml | 5 +-- .../flambda2/terms/flambda_primitive.ml | 42 +++++++------------ .../flambda2/terms/flambda_primitive.mli | 2 +- .../flambda2/to_cmm/to_cmm_primitive.ml | 5 +-- 9 files changed, 31 insertions(+), 47 deletions(-) diff --git a/bytecomp/bytegen.ml b/bytecomp/bytegen.ml index cfe8d14b3e9..fcd03657384 100644 --- a/bytecomp/bytegen.ml +++ b/bytecomp/bytegen.ml @@ -1138,11 +1138,11 @@ and comp_expr stack_info env exp sz cont = let cont = add_pseudo_event loc !compunit_name cont in comp_args stack_info env args sz (Kmakeblock(List.length args, tag) :: cont) - | Lprim (Pmakelazyblock (Lazy_tag, _), args, loc) -> + | Lprim (Pmakelazyblock Lazy_tag, args, loc) -> let cont = add_pseudo_event loc !compunit_name cont in comp_args stack_info env args sz (Kmakeblock(List.length args, Config.lazy_tag) :: cont) - | Lprim (Pmakelazyblock (Forward_tag, _), args, loc) -> + | Lprim (Pmakelazyblock Forward_tag, args, loc) -> let cont = add_pseudo_event loc !compunit_name cont in comp_args stack_info env args sz (Kmakeblock(List.length args, Obj.forward_tag) :: cont) diff --git a/lambda/lambda.ml b/lambda/lambda.ml index 2b329aca25a..c364575a69e 100644 --- a/lambda/lambda.ml +++ b/lambda/lambda.ml @@ -141,7 +141,7 @@ type primitive = | Pmakefloatblock of mutable_flag * locality_mode | Pmakeufloatblock of mutable_flag * locality_mode | Pmakemixedblock of int * mutable_flag * mixed_block_shape * locality_mode - | Pmakelazyblock of lazy_block_tag * locality_mode + | Pmakelazyblock of lazy_block_tag | Pfield of int * immediate_or_pointer * field_read_semantics | Pfield_computed of field_read_semantics | Psetfield of int * immediate_or_pointer * initialization_or_assignment @@ -1828,7 +1828,7 @@ let primitive_may_allocate : primitive -> locality_mode option = function | Pmakefloatblock (_, m) -> Some m | Pmakeufloatblock (_, m) -> Some m | Pmakemixedblock (_, _, _, m) -> Some m - | Pmakelazyblock (_, m) -> Some m + | Pmakelazyblock _ -> Some alloc_heap | Pfield _ | Pfield_computed _ | Psetfield _ | Psetfield_computed _ -> None | Pfloatfield (_, _, m) -> Some m | Pufloatfield _ -> None diff --git a/lambda/lambda.mli b/lambda/lambda.mli index 2a83038fd4b..a5188bb51a1 100644 --- a/lambda/lambda.mli +++ b/lambda/lambda.mli @@ -125,7 +125,7 @@ type primitive = | Pmakefloatblock of mutable_flag * locality_mode | Pmakeufloatblock of mutable_flag * locality_mode | Pmakemixedblock of int * mutable_flag * mixed_block_shape * locality_mode - | Pmakelazyblock of lazy_block_tag * locality_mode + | Pmakelazyblock of lazy_block_tag | Pfield of int * immediate_or_pointer * field_read_semantics | Pfield_computed of field_read_semantics | Psetfield of int * immediate_or_pointer * initialization_or_assignment diff --git a/lambda/printlambda.ml b/lambda/printlambda.ml index 7a4102b280f..1bb5f0366ab 100644 --- a/lambda/printlambda.ml +++ b/lambda/printlambda.ml @@ -469,10 +469,10 @@ let primitive ppf = function | Pmakemixedblock (tag, Mutable, abs, mode) -> fprintf ppf "make%amixedblock %i Mutable%a" locality_mode mode tag (mixed_block_shape (fun _ _ -> ())) abs - | Pmakelazyblock (Lazy_tag, mode) -> - fprintf ppf "make%alazyblock" locality_mode mode - | Pmakelazyblock (Forward_tag, mode) -> - fprintf ppf "make%aforwardblock" locality_mode mode + | Pmakelazyblock Lazy_tag -> + fprintf ppf "makelazyblock" + | Pmakelazyblock Forward_tag -> + fprintf ppf "makeforwardblock" | Pfield (n, ptr, sem) -> let instr = match ptr, sem with diff --git a/lambda/translcore.ml b/lambda/translcore.ml index a95a0a1a8f8..48072b2c84a 100644 --- a/lambda/translcore.ml +++ b/lambda/translcore.ml @@ -1012,7 +1012,7 @@ and transl_exp0 ~in_new_scope ~scopes sort e = (* We don't need to wrap with Popaque: this forward block will never be shortcutted since it points to a float and Config.flat_float_array is true. *) - Lprim(Pmakelazyblock(Forward_tag, alloc_heap), + Lprim(Pmakelazyblock Forward_tag, [transl_exp ~scopes Jkind.Sort.Const.for_lazy_body e], of_location ~scopes e.exp_loc) | `Identifier `Forward_value -> @@ -1022,7 +1022,7 @@ and transl_exp0 ~in_new_scope ~scopes sort e = optimisation in Flambda, but the concept of a mutable block doesn't really match what is going on here. This value may subsequently turn into an immediate... *) - Lprim(Pmakelazyblock(Forward_tag, alloc_heap), + Lprim(Pmakelazyblock Forward_tag, [transl_exp ~scopes Jkind.Sort.Const.for_lazy_body e], of_location ~scopes e.exp_loc) | `Identifier `Other -> @@ -1049,7 +1049,7 @@ and transl_exp0 ~in_new_scope ~scopes sort e = Lambda.layout_lazy_contents (transl_exp ~scopes Jkind.Sort.Const.for_lazy_body e)) in - Lprim(Pmakelazyblock(Lazy_tag, alloc_heap), [fn], + Lprim(Pmakelazyblock Lazy_tag, [fn], of_location ~scopes e.exp_loc) end | Texp_object (cs, meths) -> diff --git a/middle_end/flambda2/from_lambda/lambda_to_flambda_primitives.ml b/middle_end/flambda2/from_lambda/lambda_to_flambda_primitives.ml index 9452a71ea3e..26e3255f7f9 100644 --- a/middle_end/flambda2/from_lambda/lambda_to_flambda_primitives.ml +++ b/middle_end/flambda2/from_lambda/lambda_to_flambda_primitives.ml @@ -1382,9 +1382,8 @@ let convert_lprim ~big_endian (prim : L.primitive) (args : Simple.t list list) let shape = convert_block_shape shape ~num_fields:(List.length args) in let mutability = Mutability.from_lambda mutability in [Variadic (Make_block (Values (tag, shape), mutability, mode), args)] - | Pmakelazyblock (lazy_tag, mode), [[arg]] -> - let mode = Alloc_mode.For_allocations.from_lambda mode ~current_region in - [Unary (Make_lazy (lazy_tag, mode), arg)] + | Pmakelazyblock lazy_tag, [[arg]] -> + [Unary (Make_lazy lazy_tag, arg)] | Pmake_unboxed_product layouts, _ -> (* CR mshinwell: this should check the unarized lengths of [layouts] and [args] (like [Parray_element_size_in_bytes] below) *) diff --git a/middle_end/flambda2/terms/flambda_primitive.ml b/middle_end/flambda2/terms/flambda_primitive.ml index bee3c242775..1ccb402fc14 100644 --- a/middle_end/flambda2/terms/flambda_primitive.ml +++ b/middle_end/flambda2/terms/flambda_primitive.ml @@ -1080,7 +1080,7 @@ type unary_primitive = | Get_header | Atomic_load of Block_access_field_kind.t | Peek of Flambda_kind.Standard_int_or_float.t - | Make_lazy of Lazy_block_tag.t * Alloc_mode.For_allocations.t + | Make_lazy of Lazy_block_tag.t (* Here and below, operations that are genuine projections shouldn't be eligible for CSE, since we deal with projections through types. *) @@ -1236,11 +1236,8 @@ let compare_unary_primitive p1 p2 = Bool.compare ghost1 ghost2 | Peek kind1, Peek kind2 -> Flambda_kind.Standard_int_or_float.compare kind1 kind2 - | Make_lazy (lazy_tag1, alloc_mode1), Make_lazy (lazy_tag2, alloc_mode2) -> - let c = Lazy_block_tag.compare lazy_tag1 lazy_tag2 in - if c <> 0 - then c - else Alloc_mode.For_allocations.compare alloc_mode1 alloc_mode2 + | Make_lazy lazy_tag1, Make_lazy lazy_tag2 -> + Lazy_block_tag.compare lazy_tag1 lazy_tag2 | ( ( Block_load _ | Duplicate_array _ | Duplicate_block _ | Is_int _ | Is_null | Get_tag | String_length _ | Int_as_pointer _ | Opaque_identity _ | Int_arith _ | Num_conv _ | Boolean_not @@ -1318,9 +1315,8 @@ let print_unary_primitive ppf p = | Peek kind -> fprintf ppf "@[(Peek@ %a)@]" Flambda_kind.Standard_int_or_float.print_lowercase kind - | Make_lazy (lazy_tag, alloc_mode) -> - fprintf ppf "@[(Make_lazy@ %a@ %a)@]" Lazy_block_tag.print lazy_tag - Alloc_mode.For_allocations.print alloc_mode + | Make_lazy lazy_tag -> + fprintf ppf "@[(Make_lazy@ %a)@]" Lazy_block_tag.print lazy_tag let arg_kind_of_unary_primitive p = match p with @@ -1487,13 +1483,8 @@ let effects_and_coeffects_of_unary_primitive p : Effects_and_coeffects.t = | Atomic_load _ | Peek _ -> (* For the moment, prevent [Peek] from being moved. *) Arbitrary_effects, Has_coeffects, Strict - | Make_lazy (_, alloc_mode) -> - let coeffects : Coeffects.t = - match alloc_mode with - | Heap -> Coeffects.No_coeffects - | Local _ -> Coeffects.Has_coeffects - in - Effects.Only_generative_effects Mutable, coeffects, Placement.Strict + | Make_lazy _ -> + Only_generative_effects Mutable, No_coeffects, Strict let unary_classify_for_printing p = match p with @@ -1535,10 +1526,9 @@ let free_names_unary_primitive p = | Is_boxed_float | Is_flat_float_array | End_region _ | End_try_region _ | Obj_dup | Get_header | Atomic_load (_ : Block_access_field_kind.t) - | Peek (_ : Flambda_kind.Standard_int_or_float.t) -> + | Peek (_ : Flambda_kind.Standard_int_or_float.t) + | Make_lazy _ -> Name_occurrences.empty - | Make_lazy (_, alloc_mode) -> - Alloc_mode.For_allocations.free_names alloc_mode let apply_renaming_unary_primitive p renaming = match p with @@ -1552,11 +1542,6 @@ let apply_renaming_unary_primitive p renaming = Alloc_mode.For_allocations.apply_renaming alloc_mode renaming in if alloc_mode == alloc_mode' then p else Int_as_pointer alloc_mode' - | Make_lazy (tag, alloc_mode) -> - let alloc_mode' = - Alloc_mode.For_allocations.apply_renaming alloc_mode renaming - in - if alloc_mode == alloc_mode' then p else Make_lazy (tag, alloc_mode') | Block_load _ | Duplicate_array _ | Duplicate_block _ | Is_int _ | Is_null | Get_tag | String_length _ | Opaque_identity _ | Int_arith _ | Num_conv _ | Boolean_not | Reinterpret_64_bit_word _ | Float_arith _ | Array_length _ @@ -1564,14 +1549,14 @@ let apply_renaming_unary_primitive p renaming = | Is_boxed_float | Is_flat_float_array | End_region _ | End_try_region _ | Project_function_slot _ | Project_value_slot _ | Obj_dup | Get_header | Atomic_load (_ : Block_access_field_kind.t) - | Peek (_ : Flambda_kind.Standard_int_or_float.t) -> + | Peek (_ : Flambda_kind.Standard_int_or_float.t) + | Make_lazy _ -> p let ids_for_export_unary_primitive p = match p with | Box_number (_, alloc_mode) - | Int_as_pointer alloc_mode - | Make_lazy (_, alloc_mode) -> + | Int_as_pointer alloc_mode -> Alloc_mode.For_allocations.ids_for_export alloc_mode | Block_load _ | Duplicate_array _ | Duplicate_block _ | Is_int _ | Is_null | Get_tag | String_length _ | Opaque_identity _ | Int_arith _ | Num_conv _ @@ -1580,7 +1565,8 @@ let ids_for_export_unary_primitive p = | Is_boxed_float | Is_flat_float_array | End_region _ | End_try_region _ | Project_function_slot _ | Project_value_slot _ | Obj_dup | Get_header | Atomic_load (_ : Block_access_field_kind.t) - | Peek (_ : Flambda_kind.Standard_int_or_float.t) -> + | Peek (_ : Flambda_kind.Standard_int_or_float.t) + | Make_lazy _ -> Ids_for_export.empty type binary_int_arith_op = diff --git a/middle_end/flambda2/terms/flambda_primitive.mli b/middle_end/flambda2/terms/flambda_primitive.mli index 3e392a902f7..e0128c88294 100644 --- a/middle_end/flambda2/terms/flambda_primitive.mli +++ b/middle_end/flambda2/terms/flambda_primitive.mli @@ -451,7 +451,7 @@ type unary_primitive = (* CR mshinwell: consider putting atomicity onto [Peek] and [Poke] then deleting [Atomic_load] *) | Peek of Flambda_kind.Standard_int_or_float.t - | Make_lazy of Lazy_block_tag.t * Alloc_mode.For_allocations.t + | Make_lazy of Lazy_block_tag.t (** Whether a comparison is to yield a boolean result, as given by a particular comparison operator, or whether it is to behave in the manner of "compare" diff --git a/middle_end/flambda2/to_cmm/to_cmm_primitive.ml b/middle_end/flambda2/to_cmm/to_cmm_primitive.ml index ad381dbf1e4..c82ad32bfd7 100644 --- a/middle_end/flambda2/to_cmm/to_cmm_primitive.ml +++ b/middle_end/flambda2/to_cmm/to_cmm_primitive.ml @@ -989,10 +989,9 @@ let unary_primitive env res dbg f arg = |> C.memory_chunk_of_kind in None, res, C.load ~dbg memory_chunk Mutable ~addr:arg - | Make_lazy (lazy_tag, alloc_mode) -> - let mode = C.alloc_mode_for_allocations_to_cmm alloc_mode in + | Make_lazy lazy_tag -> let tag = Tag.to_int (P.Lazy_block_tag.to_tag lazy_tag) in - None, res, C.make_alloc ~mode dbg ~tag [arg] + None, res, C.make_alloc ~mode:Heap dbg ~tag [arg] let binary_primitive env dbg f x y = match (f : P.binary_primitive) with From 455d6a213f0bd6643a135bd0067476f1fa78026b Mon Sep 17 00:00:00 2001 From: Vincent Laviron Date: Thu, 13 Mar 2025 15:24:12 +0100 Subject: [PATCH 5/5] Formatting --- .../flambda2/from_lambda/lambda_to_flambda_primitives.ml | 3 +-- middle_end/flambda2/terms/flambda_primitive.ml | 6 ++---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/middle_end/flambda2/from_lambda/lambda_to_flambda_primitives.ml b/middle_end/flambda2/from_lambda/lambda_to_flambda_primitives.ml index 26e3255f7f9..1bd1bf7fd18 100644 --- a/middle_end/flambda2/from_lambda/lambda_to_flambda_primitives.ml +++ b/middle_end/flambda2/from_lambda/lambda_to_flambda_primitives.ml @@ -1382,8 +1382,7 @@ let convert_lprim ~big_endian (prim : L.primitive) (args : Simple.t list list) let shape = convert_block_shape shape ~num_fields:(List.length args) in let mutability = Mutability.from_lambda mutability in [Variadic (Make_block (Values (tag, shape), mutability, mode), args)] - | Pmakelazyblock lazy_tag, [[arg]] -> - [Unary (Make_lazy lazy_tag, arg)] + | Pmakelazyblock lazy_tag, [[arg]] -> [Unary (Make_lazy lazy_tag, arg)] | Pmake_unboxed_product layouts, _ -> (* CR mshinwell: this should check the unarized lengths of [layouts] and [args] (like [Parray_element_size_in_bytes] below) *) diff --git a/middle_end/flambda2/terms/flambda_primitive.ml b/middle_end/flambda2/terms/flambda_primitive.ml index 1ccb402fc14..0580b662ac2 100644 --- a/middle_end/flambda2/terms/flambda_primitive.ml +++ b/middle_end/flambda2/terms/flambda_primitive.ml @@ -1483,8 +1483,7 @@ let effects_and_coeffects_of_unary_primitive p : Effects_and_coeffects.t = | Atomic_load _ | Peek _ -> (* For the moment, prevent [Peek] from being moved. *) Arbitrary_effects, Has_coeffects, Strict - | Make_lazy _ -> - Only_generative_effects Mutable, No_coeffects, Strict + | Make_lazy _ -> Only_generative_effects Mutable, No_coeffects, Strict let unary_classify_for_printing p = match p with @@ -1555,8 +1554,7 @@ let apply_renaming_unary_primitive p renaming = let ids_for_export_unary_primitive p = match p with - | Box_number (_, alloc_mode) - | Int_as_pointer alloc_mode -> + | Box_number (_, alloc_mode) | Int_as_pointer alloc_mode -> Alloc_mode.For_allocations.ids_for_export alloc_mode | Block_load _ | Duplicate_array _ | Duplicate_block _ | Is_int _ | Is_null | Get_tag | String_length _ | Opaque_identity _ | Int_arith _ | Num_conv _