jon.recoil.org

Module Flambda2_terms.Flambda_primitive

"Primitive" operations: those that perform computation but never affect control flow.

Primitives that accept float, int32, int64 or nativeint values always take (or return) the unboxed versions.

No primitive raises an exception. (Bounds checking is handled separately.)

module Lazy_block_tag : sig ... end
module Block_kind : sig ... end
module Array_kind : sig ... end
module Array_kind_for_length : sig ... end
module Init_or_assign : sig ... end
module Array_load_kind : sig ... end
module Array_set_kind : sig ... end
module Duplicate_block_kind : sig ... end
module Duplicate_array_kind : sig ... end
module Block_access_field_kind : sig ... end
module Mixed_block_access_field_kind : sig ... end
module Block_access_kind : sig ... end
type string_or_bytes =
  1. | String
  2. | Bytes
type 'signed_or_unsigned comparison =
  1. | Eq
  2. | Neq
  3. | Lt of 'signed_or_unsigned
  4. | Gt of 'signed_or_unsigned
  5. | Le of 'signed_or_unsigned
  6. | Ge of 'signed_or_unsigned
type equality_comparison =
  1. | Eq
  2. | Neq
module Bigarray_kind : sig ... end
module Bigarray_layout : sig ... end
type string_accessor_width =
  1. | Eight
  2. | Sixteen
  3. | Thirty_two
  4. | Single
  5. | Sixty_four
  6. | One_twenty_eight of {
    1. aligned : bool;
    }
  7. | Two_fifty_six of {
    1. aligned : bool;
    }
  8. | Five_twelve of {
    1. aligned : bool;
    }
val byte_width_of_string_accessor_width : Flambda2_terms.Flambda_primitive.string_accessor_width -> int
type float_bitwidth =
  1. | Float32
  2. | Float64
type string_like_value =
  1. | String
  2. | Bytes
  3. | Bigstring
type bytes_like_value =
  1. | Bytes
  2. | Bigstring
type num_dimensions = int
type signed_or_unsigned =
  1. | Signed
  2. | Unsigned
type nullary_primitive =
  1. | Invalid of Flambda2_kinds.Flambda_kind.t
    (*

    Used when rebuilding a primitive that turns out to be invalid. This is easier to use than turning a whole let-binding into Invalid (which might end up deleting code on the way up, resulting in a typing env out-of-sync with the generated code).

    *)
  2. | Optimised_out of Flambda2_kinds.Flambda_kind.t
    (*

    Used for phantom bindings for which there is not enough information remaining to build a meaningful value. Can only be used in a phantom let-binding.

    *)
  3. | Probe_is_enabled of {
    1. name : string;
    2. enabled_at_init : bool option;
    }
    (*

    Returns a boolean saying whether the given tracing probe is enabled. Semaphore initialization code may be emitted as a consequence of seeing this instruction, but the emitter checks that all occurrences of enabled_at_init are consistent for a given probe name.

    *)
  4. | Enter_inlined_apply of {
    1. dbg : Flambda2_term_basics.Inlined_debuginfo.t;
    }
    (*

    Used in classic mode to denote the start of an inlined function body. This is then used in to_cmm to correctly add inlined debuginfo.

    *)
  5. | Dls_get
    (*

    Obtain the domain-local state block.

    *)
  6. | Tls_get
    (*

    Obtain the thread-local state block.

    *)
  7. | Poll
    (*

    Poll for runtime actions. May run pending actions such as signal handlers, finalizers, memprof callbacks, etc, as well as GCs and GC slices, so should not be moved or optimised away.

    *)
  8. | Cpu_relax
    (*

    Arch-specific pause. If poll insertion is disabled, also acts as a polling point.

    *)

Primitives taking exactly zero arguments.

type unary_int_arith_op =
  1. | Swap_byte_endianness

Untagged binary integer arithmetic operations.

Swap_byte_endianness on a Tagged_immediate treats the immediate as encoding a 16-bit quantity (described in the least significant 16 bits of the immediate after untagging) and exchanges the two halves of the 16-bit quantity. The higher-order bits are zeroed.

type unary_float_arith_op =
  1. | Abs
  2. | Neg

Naked float unary arithmetic operations.

module Reinterpret_64_bit_word : sig ... end

Reinterpretation operations for 64-bit words.

type unary_primitive =
  1. | Block_load of {
    1. kind : Flambda2_terms.Flambda_primitive.Block_access_kind.t;
    2. mut : Flambda2_terms.Mutability.t;
    3. field : Flambda2_numbers.Target_ocaml_int.t;
    }
  2. | Duplicate_block of {
    1. kind : Flambda2_terms.Flambda_primitive.Duplicate_block_kind.t;
    }
    (*

    Duplicate_block may not be used to change the tag or the mutability of a block.

    *)
  3. | Duplicate_array of {
    1. kind : Flambda2_terms.Flambda_primitive.Duplicate_array_kind.t;
    2. source_mutability : Flambda2_terms.Mutability.t;
    3. destination_mutability : Flambda2_terms.Mutability.t;
    }
  4. | Is_int of {
    1. variant_only : bool;
    }
  5. | Is_null
  6. | Get_tag
  7. | Array_length of Flambda2_terms.Flambda_primitive.Array_kind_for_length.t
    (*

    The unarized length of an array. So for an example an array of kind Unboxed_product [tagged_immediate; tagged_immediate] always has a length that is a multiple of two.

    *)
  8. | Bigarray_length of {
    1. dimension : int;
    }
    (*

    This primitive is restricted by type-checking to bigarrays that have at least the correct number of dimensions. More specifically, they come from `%caml_ba_dim_x` primitives (for x=1,2,3), and only exposed in the Bigarray.ArrayX modules (incidentally, `dimension` should then be one of 1,2,3).

    *)
  9. | String_length of Flambda2_terms.Flambda_primitive.string_or_bytes
  10. | Int_as_pointer of Flambda2_term_basics.Alloc_mode.For_allocations.t
  11. | Opaque_identity of {
    1. middle_end_only : bool;
    2. kind : Flambda2_kinds.Flambda_kind.t;
    }
  12. | Int_arith of Flambda2_kinds.Flambda_kind.Standard_int.t * Flambda2_terms.Flambda_primitive.unary_int_arith_op
  13. | Float_arith of Flambda2_terms.Flambda_primitive.float_bitwidth * Flambda2_terms.Flambda_primitive.unary_float_arith_op
  14. | Num_conv of {
    1. src : Flambda2_kinds.Flambda_kind.Standard_int_or_float.t;
    2. dst : Flambda2_kinds.Flambda_kind.Standard_int_or_float.t;
    }
  15. | Boolean_not
  16. | Reinterpret_64_bit_word of Flambda2_terms.Flambda_primitive.Reinterpret_64_bit_word.t
  17. | Unbox_number of Flambda2_kinds.Flambda_kind.Boxable_number.t
  18. | Box_number of Flambda2_kinds.Flambda_kind.Boxable_number.t * Flambda2_term_basics.Alloc_mode.For_allocations.t
  19. | Untag_immediate
  20. | Tag_immediate
  21. | Project_function_slot of {
    1. move_from : Flambda2_identifiers.Function_slot.t;
    2. move_to : Flambda2_identifiers.Function_slot.t;
    }
    (*

    Project a function slot from a set of closures, which is actually achieved by providing a known function slot move_from and the desired function slot move_to, which must be within the same set of closures.

    *)
  22. | Project_value_slot of {
    1. project_from : Flambda2_identifiers.Function_slot.t;
    2. value_slot : Flambda2_identifiers.Value_slot.t;
    }
    (*

    Project a value slot from a set of closures -- in other words, read an entry from the closure environment (the captured variables).

    *)
  23. | Is_boxed_float
    (*

    Only valid when the float array optimisation is enabled.

    *)
  24. | Is_flat_float_array
    (*

    Only valid when the float array optimisation is enabled.

    *)
  25. | End_region of {
    1. ghost : bool;
    }
    (*

    Ending delimiter of local allocation region, accepting a region name.

    *)
  26. | End_try_region of {
    1. ghost : bool;
    }
    (*

    Corresponding delimiter for Begin_try_region.

    *)
  27. | Obj_dup
    (*

    Corresponds to Obj.dup; see the documentation in obj.mli.

    *)
  28. | Get_header
    (*

    Get the header of a block. This primitive is invalid if provided with an immediate value. It should also not be used to read tags above No_scan_tag. Note: The GC color bits in the header are not reliable except for checking if the value is locally allocated Invariant: never read the tag of a possibly-lazy value from ocamlopt-generated code. Tag reads that are allowed to be lazy tags (by the type system) should always go through caml_obj_tag, which is opaque to the compiler.

    *)
  29. | Peek of Flambda2_kinds.Flambda_kind.Standard_int_or_float.t
  30. | Make_lazy of Flambda2_terms.Flambda_primitive.Lazy_block_tag.t

Primitives taking exactly one argument.

type 'signed_or_unsigned comparison_behaviour =
  1. | Yielding_bool of 'signed_or_unsigned Flambda2_terms.Flambda_primitive.comparison
  2. | Yielding_int_like_compare_functions of 'signed_or_unsigned

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" functions that yield tagged immediates -1, 0 or 1.

type binary_int_arith_op =
  1. | Add
  2. | Sub
  3. | Mul
  4. | Div
  5. | Mod
  6. | And
  7. | Or
  8. | Xor

Binary arithmetic operations on integers.

type int_shift_op =
  1. | Lsl
  2. | Lsr
  3. | Asr

Shift operations on integers.

type binary_float_arith_op =
  1. | Add
  2. | Sub
  3. | Mul
  4. | Div

Naked float binary arithmetic operations.

type binary_primitive =
  1. | Block_set of {
    1. kind : Flambda2_terms.Flambda_primitive.Block_access_kind.t;
    2. init : Flambda2_terms.Flambda_primitive.Init_or_assign.t;
    3. field : Flambda2_numbers.Target_ocaml_int.t;
    }
  2. | Array_load of Flambda2_terms.Flambda_primitive.Array_kind.t * Flambda2_terms.Flambda_primitive.Array_load_kind.t * Flambda2_terms.Mutability.t
    (*

    Unarized or SIMD array load.

    The array kind preserves unboxed product information but the load kind and index all correspond to the unarized representation. See also Array_length, above.

    *)
  3. | String_or_bigstring_load of Flambda2_terms.Flambda_primitive.string_like_value * Flambda2_terms.Flambda_primitive.string_accessor_width
  4. | Bigarray_load of Flambda2_terms.Flambda_primitive.num_dimensions * Flambda2_terms.Flambda_primitive.Bigarray_kind.t * Flambda2_terms.Flambda_primitive.Bigarray_layout.t
  5. | Phys_equal of Flambda2_terms.Flambda_primitive.equality_comparison
    (*

    Phys_equal is only for things of kind Value.

    *)
  6. | Int_arith of Flambda2_kinds.Flambda_kind.Standard_int.t * Flambda2_terms.Flambda_primitive.binary_int_arith_op
  7. | Int_shift of Flambda2_kinds.Flambda_kind.Standard_int.t * Flambda2_terms.Flambda_primitive.int_shift_op
  8. | Int_comp of Flambda2_kinds.Flambda_kind.Standard_int.t * Flambda2_terms.Flambda_primitive.signed_or_unsigned Flambda2_terms.Flambda_primitive.comparison_behaviour
  9. | Float_arith of Flambda2_terms.Flambda_primitive.float_bitwidth * Flambda2_terms.Flambda_primitive.binary_float_arith_op
  10. | Float_comp of Flambda2_terms.Flambda_primitive.float_bitwidth * unit Flambda2_terms.Flambda_primitive.comparison_behaviour
  11. | Bigarray_get_alignment of int
  12. | Atomic_load_field of Flambda2_terms.Flambda_primitive.Block_access_field_kind.t
  13. | Poke of Flambda2_kinds.Flambda_kind.Standard_int_or_float.t
  14. | Read_offset of Flambda2_kinds.Flambda_kind.With_subkind.t * Asttypes.mutable_flag

Primitives taking exactly two arguments.

type int_atomic_op =
  1. | Fetch_add
  2. | Add
  3. | Sub
  4. | And
  5. | Or
  6. | Xor

Atomic arithmetic operations on integers.

type quaternary_primitive =
  1. | Atomic_compare_and_set_field of Flambda2_terms.Flambda_primitive.Block_access_field_kind.t
  2. | Atomic_compare_exchange_field of {
    1. atomic_kind : Flambda2_terms.Flambda_primitive.Block_access_field_kind.t;
      (*

      The kind of values which the atomic can hold.

      *)
    2. args_kind : Flambda2_terms.Flambda_primitive.Block_access_field_kind.t;
      (*

      The kind of values which the compare-exchange operation is to be used with on this particular occasion. Note that this might be Immediate even though the atomic is marked as Any_value, for example.

      *)
    }

Primitives taking exactly four arguments.

type variadic_primitive =
  1. | Begin_region of {
    1. ghost : bool;
    }
    (*

    Starting delimiter of local allocation region, returning a region name. For regions for the "try" part of a "try...with", use Begin_try_region (below) instead.

    *)
  2. | Begin_try_region of {
    1. ghost : bool;
    }
    (*

    Starting delimiter of local allocation region, when used for a "try" body.

    *)
  3. | Make_block of Flambda2_terms.Flambda_primitive.Block_kind.t * Flambda2_terms.Mutability.t * Flambda2_term_basics.Alloc_mode.For_allocations.t
  4. | Make_array of Flambda2_terms.Flambda_primitive.Array_kind.t * Flambda2_terms.Mutability.t * Flambda2_term_basics.Alloc_mode.For_allocations.t

Primitives taking zero or more arguments.

type primitive_application = Flambda2_terms.Flambda_primitive.t
include Flambda2_nominal.Contains_names.S with type t := Flambda2_terms.Flambda_primitive.t

Compute the free names of a term. Such computation covers all kinds of bindable names (variables, continuations, ...)

Apply a renaming throughout a term.

include Flambda2_nominal.Contains_ids.S with type t := Flambda2_terms.Flambda_primitive.t

Gather all table identifiers to export them.

module Without_args : sig ... end

Simpler version (e.g. for Inlining_cost), where only the actual primitive matters, not the arguments.

A description of the kind of values which a unary primitive expects as its arguments.

type arg_kinds =
  1. | Variadic_mixed of Flambda2_kinds.Flambda_kind.Mixed_block_shape.t
  2. | Variadic_all_of_kind of Flambda2_kinds.Flambda_kind.t
  3. | Variadic_zero_or_one of Flambda2_kinds.Flambda_kind.t
  4. | Variadic_unboxed_product of Flambda2_kinds.Flambda_kind.t list
type result_kind =
  1. | Singleton of Flambda2_kinds.Flambda_kind.t
    (*

    The primitive returns a single value of the given kind.

    *)
  2. | Unit
    (*

    The primitive returns the constant unit value.

    *)

A description of the kinds of values (or in the case of Unit, the actual value) which a primitive returns.

Describe the kind of the result of the given primitive.

Like the result_kinds, but returns the appropriate Flambda_kind.

Describe the effects and coeffects that the application of the given primitive may have.

val no_effects_or_coeffects : Flambda2_terms.Flambda_primitive.t -> bool

Returns true iff the given primitive has neither effects nor coeffects.

val at_most_generative_effects : Flambda2_terms.Flambda_primitive.t -> bool
val only_generative_effects : Flambda2_terms.Flambda_primitive.t -> bool

Returns true iff the given primitive has generative effects, and no other effects.

module Eligible_for_cse : sig ... end
include Flambda2_algorithms.Container_types.S with type t := Flambda2_terms.Flambda_primitive.t
include Flambda2_algorithms.Container_types_intf.Thing with type t := Flambda2_terms.Flambda_primitive.T.t
include Stdlib.Hashtbl.HashedType with type t := Flambda2_terms.Flambda_primitive.T.t

A hashing function on keys. It must be such that if two keys are equal according to equal, then they have identical hash values as computed by hash. Examples: suitable (equal, hash) pairs for arbitrary key types include

  • ((=), hash) for comparing objects by structure (provided objects do not contain floats)
  • ((fun x y -> compare x y = 0), hash) for comparing objects by structure and handling Stdlib.nan correctly
  • ((==), hash) for comparing objects by physical equality (e.g. for mutable or cyclic objects).
include Stdlib.Map.OrderedType with type t := Flambda2_terms.Flambda_primitive.T.t

A total ordering function over the keys. This is a two-argument function f such that f e1 e2 is zero if the keys e1 and e2 are equal, f e1 e2 is strictly negative if e1 is smaller than e2, and f e1 e2 is strictly positive if e1 is greater than e2. Example: a suitable ordering function is the generic structural comparison function Stdlib.compare.

val is_begin_or_end_region : Flambda2_terms.Flambda_primitive.t -> bool
val is_begin_region : Flambda2_terms.Flambda_primitive.t -> bool