Skip to content

Commit

Permalink
support %get_header
Browse files Browse the repository at this point in the history
  • Loading branch information
riaqn committed Jul 1, 2023
1 parent 4584a80 commit 84c71e2
Show file tree
Hide file tree
Showing 26 changed files with 145 additions and 13 deletions.
8 changes: 5 additions & 3 deletions backend/cmmgen.ml
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,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 @@ -996,6 +996,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 @@ -1191,7 +1193,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 @@ -1252,7 +1254,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 @@ -126,6 +126,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 @@ -129,6 +129,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
1 change: 1 addition & 0 deletions middle_end/flambda2/from_lambda/closure_conversion.ml
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,7 @@ let close_primitive acc env ~let_bound_var named (prim : Lambda.primitive) ~args
| 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
Expand Down
3 changes: 2 additions & 1 deletion middle_end/flambda2/from_lambda/lambda_to_flambda.ml
Original file line number Diff line number Diff line change
Expand Up @@ -982,7 +982,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

let primitive_result_kind (prim : Lambda.primitive) :
Expand Down Expand Up @@ -1072,6 +1072,7 @@ let primitive_result_kind (prim : Lambda.primitive) :
| Pint32 -> Flambda_kind.With_subkind.naked_int32
| Pint64 -> Flambda_kind.With_subkind.naked_int64
| Pnativeint -> Flambda_kind.With_subkind.naked_nativeint)
| Pget_header _ -> Flambda_kind.With_subkind.boxed_nativeint

type cps_continuation =
| Tail of Continuation.t
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,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 @@ -1157,6 +1161,7 @@ let convert_lprim ~big_endian (prim : L.primitive) (args : Simple.t 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 @@ -1178,7 +1183,7 @@ let convert_lprim ~big_endian (prim : L.primitive) (args : Simple.t 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 @@ -534,7 +534,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
6 changes: 6 additions & 0 deletions middle_end/flambda2/simplify/simplify_unary_primitive.ml
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,11 @@ 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 @@ -635,5 +640,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 @@ -337,6 +337,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 @@ -679,14 +679,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
| Array_length -> true
| Bigarray_length _ -> false
| String_length _ -> true
Expand Down Expand Up @@ -739,6 +740,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 @@ -816,7 +818,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 @@ -870,6 +872,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 @@ -894,6 +897,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 @@ -920,6 +924,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_immediate

let effects_and_coeffects_of_unary_primitive p : Effects_and_coeffects.t =
match p with
Expand Down Expand Up @@ -1009,6 +1014,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

let unary_classify_for_printing p =
match p with
Expand All @@ -1023,6 +1029,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 @@ -1043,7 +1050,7 @@ let free_names_unary_primitive p =
| 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 @@ -1058,7 +1065,7 @@ let apply_renaming_unary_primitive p renaming =
| 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 @@ -1070,7 +1077,7 @@ let ids_for_export_unary_primitive p =
| 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
1 change: 1 addition & 0 deletions middle_end/flambda2/terms/flambda_primitive.mli
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ 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; undefined behaviour if it's int *)

(** 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 @@ -631,6 +631,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 @@ -176,6 +176,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 @@ -285,6 +286,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 @@ -439,6 +441,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 @@ -553,3 +556,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 @@ -235,3 +235,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
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 @@ -526,6 +527,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 @@ -1384,7 +1385,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 @@ -1490,6 +1491,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
2 changes: 2 additions & 0 deletions ocaml/lambda/lambda.mli
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,8 @@ type primitive =
one; O(1) *)
| Parray_of_iarray (* Unsafely reinterpret an immutable array as a mutable
one; O(1) *)
| Pget_header of alloc_mode (* returns the header of a block; undefined
behavior if it is int*)

and integer_comparison =
Ceq | Cne | Clt | Cgt | Cle | Cge
Expand Down
2 changes: 2 additions & 0 deletions ocaml/lambda/printlambda.ml
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,7 @@ let primitive ppf = function

| Parray_to_iarray -> fprintf ppf "array_to_iarray"
| Parray_of_iarray -> fprintf ppf "array_of_iarray"
| Pget_header m -> fprintf ppf "get_header%s" (alloc_kind m)

let name_of_primitive = function
| Pbytes_of_string -> "Pbytes_of_string"
Expand Down Expand Up @@ -569,6 +570,7 @@ let name_of_primitive = function
| Pbox_int _ -> "Pbox_int"
| Parray_of_iarray -> "Parray_of_iarray"
| Parray_to_iarray -> "Parray_to_iarray"
| Pget_header _ -> "Pget_header"

let check_attribute ppf check =
let check_property = function
Expand Down
1 change: 1 addition & 0 deletions ocaml/lambda/tmc.ml
Original file line number Diff line number Diff line change
Expand Up @@ -917,6 +917,7 @@ let rec choice ctx t =
| Pbytes_set_16 _ | Pbytes_set_32 _ | Pbytes_set_64 _
| Pbigstring_load_16 _ | Pbigstring_load_32 _ | Pbigstring_load_64 _
| Pbigstring_set_16 _ | Pbigstring_set_32 _ | Pbigstring_set_64 _
| Pget_header _
| Pctconst _
| Pbswap16
| Pbbswap _
Expand Down

0 comments on commit 84c71e2

Please sign in to comment.