Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

add the %get_header primitive #1539

Merged
merged 7 commits into from
Aug 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 5 additions & 3 deletions backend/cmmgen.ml
Original file line number Diff line number Diff line change
Expand Up @@ -722,7 +722,7 @@ let rec transl env e =
| Pasrbint _ | Pbintcomp (_, _) | Pstring_load _ | Pbytes_load _
| Pbytes_set _ | Pbigstring_load _ | Pbigstring_set _
| Punbox_float | Pbox_float _ | Punbox_int _ | Pbox_int _
| Pbbswap _), _)
| Pbbswap _ | Pget_header _), _)
->
fatal_error "Cmmgen.transl:prim"
end
Expand Down Expand Up @@ -1036,6 +1036,8 @@ and transl_prim_1 env p arg dbg =
| Pbswap16 ->
tag_int (bswap16 (ignore_high_bit_int (untag_int
(transl env arg) dbg)) dbg) dbg
| Pget_header m ->
box_int dbg Pnativeint m (get_header (transl env arg) dbg)
| (Pfield_computed | Psequand | Psequor
| Paddint | Psubint | Pmulint | Pandint
| Porint | Pxorint | Plslint | Plsrint | Pasrint
Expand Down Expand Up @@ -1231,7 +1233,7 @@ and transl_prim_2 env p arg1 arg2 dbg =
| Pnegbint _ | Pbigarrayref (_, _, _, _) | Pbigarrayset (_, _, _, _)
| Pbigarraydim _ | Pbytes_set _ | Pbigstring_set _ | Pbbswap _
| Pprobe_is_enabled _
| Punbox_float | Pbox_float _ | Punbox_int _ | Pbox_int _
| Punbox_float | Pbox_float _ | Punbox_int _ | Pbox_int _ | Pget_header _
->
fatal_errorf "Cmmgen.transl_prim_2: %a"
Printclambda_primitives.primitive p
Expand Down Expand Up @@ -1292,7 +1294,7 @@ and transl_prim_3 env p arg1 arg2 arg3 dbg =
| Pbigarrayref (_, _, _, _) | Pbigarrayset (_, _, _, _) | Pbigarraydim _
| Pstring_load _ | Pbytes_load _ | Pbigstring_load _ | Pbbswap _
| Pprobe_is_enabled _
| Punbox_float | Pbox_float _ | Punbox_int _ | Pbox_int _
| Punbox_float | Pbox_float _ | Punbox_int _ | Pbox_int _ | Pget_header _
->
fatal_errorf "Cmmgen.transl_prim_3: %a"
Printclambda_primitives.primitive p
Expand Down
1 change: 1 addition & 0 deletions middle_end/clambda_primitives.ml
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ type primitive =
| Pbox_float of alloc_mode
| Punbox_int of boxed_integer
| Pbox_int of boxed_integer * alloc_mode
| Pget_header of alloc_mode

and integer_comparison = Lambda.integer_comparison =
Ceq | Cne | Clt | Cgt | Cle | Cge
Expand Down
1 change: 1 addition & 0 deletions middle_end/clambda_primitives.mli
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ type primitive =
| Pbox_float of alloc_mode
| Punbox_int of boxed_integer
| Pbox_int of boxed_integer * alloc_mode
| Pget_header of alloc_mode

and integer_comparison = Lambda.integer_comparison =
Ceq | Cne | Clt | Cgt | Cle | Cge
Expand Down
1 change: 1 addition & 0 deletions middle_end/convert_primitives.ml
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ let convert (prim : Lambda.primitive) : Clambda_primitives.primitive =
| Pbox_float m -> Pbox_float m
| Punbox_int bi -> Punbox_int bi
| Pbox_int (bi, m) -> Pbox_int (bi, m)
| Pget_header m -> Pget_header m
| Pobj_magic _
| Pbytes_to_string
| Pbytes_of_string
Expand Down
2 changes: 1 addition & 1 deletion middle_end/flambda2/from_lambda/closure_conversion.ml
Original file line number Diff line number Diff line change
Expand Up @@ -755,7 +755,7 @@ let close_primitive acc env ~let_bound_ids_with_kinds named
| Pbigstring_set_64 _ | Pctconst _ | Pbswap16 | Pbbswap _
| Pint_as_pointer _ | Popaque _ | Pprobe_is_enabled _ | Pobj_dup
| Pobj_magic _ | Punbox_float | Pbox_float _ | Punbox_int _ | Pbox_int _
->
| Pget_header _ ->
(* Inconsistent with outer match *)
assert false
in
Expand Down
2 changes: 1 addition & 1 deletion middle_end/flambda2/from_lambda/lambda_to_flambda.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1004,7 +1004,7 @@ let primitive_can_raise (prim : Lambda.primitive) =
| Pbigstring_set_64 true
| Pctconst _ | Pbswap16 | Pbbswap _ | Pint_as_pointer _ | Popaque _
| Pprobe_is_enabled _ | Pobj_dup | Pobj_magic _ | Pbox_float _ | Punbox_float
| Punbox_int _ | Pbox_int _ ->
| Punbox_int _ | Pbox_int _ | Pget_header _ ->
false

type cps_continuation =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,10 @@ let string_like_load_unsafe ~access_size kind mode string index ~current_region
in
wrap (Binary (String_or_bigstring_load (kind, access_size), string, index))

let get_header obj mode ~current_region =
let wrap hd = box_bint Pnativeint mode hd ~current_region in
wrap (Unary (Get_header, obj))

let string_like_load_safe ~dbg ~size_int ~access_size kind mode str index
~current_region =
match (kind : P.string_like_value) with
Expand Down Expand Up @@ -1257,6 +1261,7 @@ let convert_lprim ~big_endian (prim : L.primitive) (args : Simple.t list list)
| Pprobe_is_enabled { name }, [] ->
[tag_int (Nullary (Probe_is_enabled { name }))]
| Pobj_dup, [[v]] -> [Unary (Obj_dup, v)]
| Pget_header m, [[obj]] -> [get_header obj m ~current_region]
| ( ( Pmodint Unsafe
| Pdivbint { is_safe = Unsafe; size = _; mode = _ }
| Pmodbint { is_safe = Unsafe; size = _; mode = _ }
Expand All @@ -1279,7 +1284,7 @@ let convert_lprim ~big_endian (prim : L.primitive) (args : Simple.t list list)
| Pduparray _ | Pfloatfield _ | Pcvtbint _ | Poffsetref _ | Pbswap16
| Pbbswap _ | Pisint _ | Pint_as_pointer _ | Pbigarraydim _ | Pobj_dup
| Pobj_magic _ | Punbox_float | Pbox_float _ | Punbox_int _ | Pbox_int _
),
| Pget_header _ ),
([] | _ :: _ :: _ | [([] | _ :: _ :: _)]) ) ->
Misc.fatal_errorf
"Closure_conversion.convert_primitive: Wrong arity for unary primitive \
Expand Down
3 changes: 2 additions & 1 deletion middle_end/flambda2/parser/flambda_to_fexpr.ml
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,8 @@ let unop env (op : Flambda_primitive.unary_primitive) : Fexpr.unop =
| String_length string_or_bytes -> String_length string_or_bytes
| Boolean_not -> Boolean_not
| Int_as_pointer _ | Duplicate_block _ | Duplicate_array _ | Bigarray_length _
| Float_arith _ | Reinterpret_int64_as_float | Is_boxed_float | Obj_dup ->
| Float_arith _ | Reinterpret_int64_as_float | Is_boxed_float | Obj_dup
| Get_header ->
Misc.fatal_errorf "TODO: Unary primitive: %a"
Flambda_primitive.Without_args.print
(Flambda_primitive.Without_args.Unary op)
Expand Down
7 changes: 7 additions & 0 deletions middle_end/flambda2/simplify/simplify_unary_primitive.ml
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,12 @@ let simplify_obj_dup dbg dacc ~original_term ~arg ~arg_ty ~result_var =
| Proved ((Heap_or_local | Local), _) | Unknown ->
SPR.create_unknown dacc ~result_var K.value ~original_term)

let simplify_get_header ~original_prim dacc ~original_term ~arg:_ ~arg_ty:_
~result_var =
SPR.create_unknown dacc ~result_var
(P.result_kind' original_prim)
~original_term

let simplify_unary_primitive dacc original_prim (prim : P.unary_primitive) ~arg
~arg_ty dbg ~result_var =
let min_name_mode = Bound_var.name_mode result_var in
Expand Down Expand Up @@ -642,5 +648,6 @@ let simplify_unary_primitive dacc original_prim (prim : P.unary_primitive) ~arg
| Begin_try_region -> simplify_begin_try_region
| End_region -> simplify_end_region
| Obj_dup -> simplify_obj_dup dbg
| Get_header -> simplify_get_header ~original_prim
in
simplifier dacc ~original_term ~arg ~arg_ty ~result_var
1 change: 1 addition & 0 deletions middle_end/flambda2/terms/code_size.ml
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ let unary_prim_size prim =
| Begin_try_region -> 1
| End_region -> 1
| Obj_dup -> alloc_extcall_size + 1
| Get_header -> 2

let binary_prim_size prim =
match (prim : Flambda_primitive.binary_primitive) with
Expand Down
17 changes: 12 additions & 5 deletions middle_end/flambda2/terms/flambda_primitive.ml
Original file line number Diff line number Diff line change
Expand Up @@ -730,14 +730,15 @@ type unary_primitive =
| Begin_try_region
| End_region
| Obj_dup
| Get_header

(* Here and below, operations that are genuine projections shouldn't be eligible
for CSE, since we deal with projections through types. *)
let unary_primitive_eligible_for_cse p ~arg =
match p with
| Duplicate_array _ -> false
| Duplicate_block { kind = _ } -> false
| Is_int _ | Get_tag -> true
| Is_int _ | Get_tag | Get_header -> true
riaqn marked this conversation as resolved.
Show resolved Hide resolved
| Array_length -> true
| Bigarray_length _ -> false
| String_length _ -> true
Expand Down Expand Up @@ -790,6 +791,7 @@ let compare_unary_primitive p1 p2 =
| Begin_try_region -> 22
| End_region -> 23
| Obj_dup -> 24
| Get_header -> 25
in
match p1, p2 with
| ( Duplicate_array
Expand Down Expand Up @@ -867,7 +869,7 @@ let compare_unary_primitive p1 p2 =
| Array_length | Bigarray_length _ | Unbox_number _ | Box_number _
| Untag_immediate | Tag_immediate | Project_function_slot _
| Project_value_slot _ | Is_boxed_float | Is_flat_float_array
| Begin_try_region | End_region | Obj_dup ),
| Begin_try_region | End_region | Obj_dup | Get_header ),
_ ) ->
Stdlib.compare (unary_primitive_numbering p1) (unary_primitive_numbering p2)

Expand Down Expand Up @@ -921,6 +923,7 @@ let print_unary_primitive ppf p =
| Begin_try_region -> Format.pp_print_string ppf "Begin_try_region"
| End_region -> Format.pp_print_string ppf "End_region"
| Obj_dup -> Format.pp_print_string ppf "Obj_dup"
| Get_header -> Format.pp_print_string ppf "Get_header"

let arg_kind_of_unary_primitive p =
match p with
Expand All @@ -945,6 +948,7 @@ let arg_kind_of_unary_primitive p =
| Begin_try_region -> K.region
| End_region -> K.region
| Obj_dup -> K.value
| Get_header -> K.value

let result_kind_of_unary_primitive p : result_kind =
match p with
Expand All @@ -971,6 +975,7 @@ let result_kind_of_unary_primitive p : result_kind =
| Begin_try_region -> Singleton K.region
| End_region -> Singleton K.value
| Obj_dup -> Singleton K.value
| Get_header -> Singleton K.naked_nativeint

let effects_and_coeffects_of_unary_primitive p : Effects_and_coeffects.t =
match p with
Expand Down Expand Up @@ -1058,6 +1063,7 @@ let effects_and_coeffects_of_unary_primitive p : Effects_and_coeffects.t =
( Only_generative_effects Mutable (* Mutable is conservative *),
Has_coeffects,
Strict )
| Get_header -> No_effects, No_coeffects, Strict
mshinwell marked this conversation as resolved.
Show resolved Hide resolved

let unary_classify_for_printing p =
match p with
Expand All @@ -1072,6 +1078,7 @@ let unary_classify_for_printing p =
| Project_function_slot _ | Project_value_slot _ -> Destructive
| Is_boxed_float | Is_flat_float_array -> Neither
| Begin_try_region | End_region -> Neither
| Get_header -> Neither

let free_names_unary_primitive p =
match p with
Expand All @@ -1092,7 +1099,7 @@ let free_names_unary_primitive p =
| Boolean_not | Reinterpret_int64_as_float | Float_arith _ | Array_length
| Bigarray_length _ | Unbox_number _ | Untag_immediate | Tag_immediate
| Is_boxed_float | Is_flat_float_array | Begin_try_region | End_region
| Obj_dup ->
| Obj_dup | Get_header ->
Name_occurrences.empty

let apply_renaming_unary_primitive p renaming =
Expand All @@ -1107,7 +1114,7 @@ let apply_renaming_unary_primitive p renaming =
| Boolean_not | Reinterpret_int64_as_float | Float_arith _ | Array_length
| Bigarray_length _ | Unbox_number _ | Untag_immediate | Tag_immediate
| Is_boxed_float | Is_flat_float_array | Begin_try_region | End_region
| Project_function_slot _ | Project_value_slot _ | Obj_dup ->
| Project_function_slot _ | Project_value_slot _ | Obj_dup | Get_header ->
p

let ids_for_export_unary_primitive p =
Expand All @@ -1119,7 +1126,7 @@ let ids_for_export_unary_primitive p =
| Boolean_not | Reinterpret_int64_as_float | Float_arith _ | Array_length
| Bigarray_length _ | Unbox_number _ | Untag_immediate | Tag_immediate
| Is_boxed_float | Is_flat_float_array | Begin_try_region | End_region
| Project_function_slot _ | Project_value_slot _ | Obj_dup ->
| Project_function_slot _ | Project_value_slot _ | Obj_dup | Get_header ->
Ids_for_export.empty

type binary_int_arith_op =
Expand Down
5 changes: 5 additions & 0 deletions middle_end/flambda2/terms/flambda_primitive.mli
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,11 @@ type unary_primitive =
| End_region
(** Ending delimiter of local allocation region, accepting a region name. *)
| Obj_dup (** Corresponds to [Obj.dup]; see the documentation in obj.mli. *)
| Get_header
(** Get the header of a block. This primitive is invalid if provided with
an immediate value.
Note: The GC color bits in the header are not reliable except for
checking if the value is locally allocated *)

(** 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"
Expand Down
1 change: 1 addition & 0 deletions middle_end/flambda2/to_cmm/to_cmm_primitive.ml
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,7 @@ let unary_primitive env res dbg f arg =
None, res, C.eq ~dbg (C.get_tag arg dbg) (C.floatarray_tag dbg)
| Begin_try_region -> None, res, C.beginregion ~dbg
| End_region -> None, res, C.return_unit dbg (C.endregion ~dbg arg)
| Get_header -> None, res, C.get_header arg dbg

let binary_primitive env dbg f x y =
match (f : P.binary_primitive) with
Expand Down
4 changes: 4 additions & 0 deletions middle_end/internal_variable_names.ml
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ let pxorint = "Pxorint"
let pprobe_is_enabled = "Pprobe_is_enabled"
let parray_of_iarray = "Parray_of_iarray"
let parray_to_iarray = "Parray_to_iarray"
let pget_header = "Pget_header"
let pabsfloat_arg = "Pabsfloat_arg"
let paddbint_arg = "Paddbint_arg"
let paddfloat_arg = "Paddfloat_arg"
Expand Down Expand Up @@ -289,6 +290,7 @@ let pxorint_arg = "Pxorint_arg"
let pprobe_is_enabled_arg = "Pprobe_is_enabled_arg"
let parray_of_iarray_arg = "Parray_of_iarray_arg"
let parray_to_iarray_arg = "Parray_to_iarray_arg"
let pget_header_arg = "Pget_header_arg"
let raise = "raise"
let raise_arg = "raise_arg"
let read_mutable = "read_mutable"
Expand Down Expand Up @@ -444,6 +446,7 @@ let of_primitive : Lambda.primitive -> string = function
| Pbox_int _ -> pbox_int
| Parray_of_iarray -> parray_of_iarray
| Parray_to_iarray -> parray_to_iarray
| Pget_header _ -> pget_header

let of_primitive_arg : Lambda.primitive -> string = function
| Pbytes_of_string -> pbytes_of_string_arg
Expand Down Expand Up @@ -558,3 +561,4 @@ let of_primitive_arg : Lambda.primitive -> string = function
| Pbox_int _ -> pbox_int_arg
| Parray_of_iarray -> parray_of_iarray_arg
| Parray_to_iarray -> parray_to_iarray_arg
| Pget_header _ -> pget_header_arg
1 change: 1 addition & 0 deletions middle_end/printclambda_primitives.ml
Original file line number Diff line number Diff line change
Expand Up @@ -259,3 +259,4 @@ let primitive ppf (prim:Clambda_primitives.primitive) =
| Pbox_int (bi, m) ->
fprintf ppf "box_%s.%s" (boxed_integer_name bi) (alloc_kind m)
| Punbox_int bi -> fprintf ppf "unbox_%s" (boxed_integer_name bi)
| Pget_header m -> fprintf ppf "get_header.%s" (alloc_kind m)
2 changes: 2 additions & 0 deletions middle_end/semantics_of_primitives.ml
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ let for_primitive (prim : Clambda_primitives.primitive) =
| Psequor ->
(* Removed by [Closure_conversion] in the flambda pipeline. *)
No_effects, No_coeffects
| Pget_header _ -> No_effects, No_coeffects

type return_type =
| Float
Expand Down Expand Up @@ -282,3 +283,4 @@ let may_locally_allocate (prim:Clambda_primitives.primitive) : bool =
| Psequor ->
false
| Pprobe_is_enabled _ -> false
| Pget_header m -> is_local_alloc m
8 changes: 5 additions & 3 deletions ocaml/asmcomp/cmmgen.ml
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,7 @@ let rec transl env e =
| Pasrbint _ | Pbintcomp (_, _) | Pstring_load _ | Pbytes_load _
| Pbytes_set _ | Pbigstring_load _ | Pbigstring_set _
| Punbox_float | Pbox_float _ | Punbox_int _ | Pbox_int _
| Pbbswap _), _)
| Pbbswap _ | Pget_header _), _)
->
fatal_error "Cmmgen.transl:prim"
end
Expand Down Expand Up @@ -960,6 +960,8 @@ and transl_prim_1 env p arg dbg =
| Pbswap16 ->
tag_int (bswap16 (ignore_high_bit_int (untag_int
(transl env arg) dbg)) dbg) dbg
| Pget_header m ->
box_int dbg Pnativeint m (get_header (transl env arg) dbg)
| (Pfield_computed | Psequand | Psequor
| Paddint | Psubint | Pmulint | Pandint
| Porint | Pxorint | Plslint | Plsrint | Pasrint
Expand Down Expand Up @@ -1155,7 +1157,7 @@ and transl_prim_2 env p arg1 arg2 dbg =
| Pnegbint _ | Pbigarrayref (_, _, _, _) | Pbigarrayset (_, _, _, _)
| Pbigarraydim _ | Pbytes_set _ | Pbigstring_set _ | Pbbswap _
| Pprobe_is_enabled _
| Punbox_float | Pbox_float _ | Punbox_int _ | Pbox_int _
| Punbox_float | Pbox_float _ | Punbox_int _ | Pbox_int _ | Pget_header _
->
fatal_errorf "Cmmgen.transl_prim_2: %a"
Printclambda_primitives.primitive p
Expand Down Expand Up @@ -1216,7 +1218,7 @@ and transl_prim_3 env p arg1 arg2 arg3 dbg =
| Pbigarrayref (_, _, _, _) | Pbigarrayset (_, _, _, _) | Pbigarraydim _
| Pstring_load _ | Pbytes_load _ | Pbigstring_load _ | Pbbswap _
| Pprobe_is_enabled _
| Punbox_float | Pbox_float _ | Punbox_int _ | Pbox_int _
| Punbox_float | Pbox_float _ | Punbox_int _ | Pbox_int _ | Pget_header _
->
fatal_errorf "Cmmgen.transl_prim_3: %a"
Printclambda_primitives.primitive p
Expand Down
2 changes: 2 additions & 0 deletions ocaml/bytecomp/bytegen.ml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ let preserve_tailcall_for_prim = function
true
| Pbytes_to_string | Pbytes_of_string
| Parray_to_iarray | Parray_of_iarray
| Pget_header _
| Pignore
| Pgetglobal _ | Psetglobal _ | Pgetpredef _
| Pmakeblock _ | Pmakefloatblock _
Expand Down Expand Up @@ -531,6 +532,7 @@ let comp_primitive p args =
| Pbytes_of_string -> Kccall("caml_bytes_of_string", 1)
| Parray_to_iarray -> Kccall("caml_iarray_of_array", 1)
| Parray_of_iarray -> Kccall("caml_array_of_iarray", 1)
| Pget_header _ -> Kccall("caml_get_header", 1)
| Pobj_dup -> Kccall("caml_obj_dup", 1)
(* The cases below are handled in [comp_expr] before the [comp_primitive] call
(in the order in which they appear below),
Expand Down
4 changes: 3 additions & 1 deletion ocaml/lambda/lambda.ml
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ type primitive =
(* Jane Street extensions *)
| Parray_to_iarray
| Parray_of_iarray
| Pget_header of alloc_mode

and integer_comparison =
Ceq | Cne | Clt | Cgt | Cle | Cge
Expand Down Expand Up @@ -1462,7 +1463,7 @@ let primitive_may_allocate : primitive -> alloc_mode option = function
Some alloc_heap
| Pstring_load_16 _ | Pbytes_load_16 _ -> None
| Pstring_load_32 (_, m) | Pbytes_load_32 (_, m)
| Pstring_load_64 (_, m) | Pbytes_load_64 (_, m) -> Some m
| Pstring_load_64 (_, m) | Pbytes_load_64 (_, m) | Pget_header m -> Some m
| Pbytes_set_16 _ | Pbytes_set_32 _ | Pbytes_set_64 _ -> None
| Pbigstring_load_16 _ -> None
| Pbigstring_load_32 (_,m) | Pbigstring_load_64 (_,m) -> Some m
Expand Down Expand Up @@ -1576,6 +1577,7 @@ let primitive_result_layout (p : primitive) =
(* CR ncourant: use an unboxed int64 here when it exists *)
layout_any_value
| (Parray_to_iarray | Parray_of_iarray) -> layout_any_value
| Pget_header _ -> layout_boxedint Pnativeint

let compute_expr_layout free_vars_kind lam =
let rec compute_expr_layout kinds = function
Expand Down