jon.recoil.org

Module Lambda

module Scalar = Scalar
type constant = Typedtree.constant
type mutable_flag =
  1. | Immutable
  2. | Immutable_unique
  3. | Mutable
type compile_time_constant =
  1. | Big_endian
  2. | Word_size
  3. | Int_size
  4. | Max_wosize
  5. | Ostype_unix
  6. | Ostype_win32
  7. | Ostype_cygwin
  8. | Backend_type
  9. | Runtime5
  10. | Arch_amd64
  11. | Arch_arm64
type immediate_or_pointer =
  1. | Immediate
  2. | Pointer
type locality_mode = private
  1. | Alloc_heap
  2. | Alloc_local
type modify_mode = private
  1. | Modify_heap
  2. | Modify_maybe_stack
val alloc_heap : Lambda.locality_mode
val alloc_local : Lambda.locality_mode
val modify_heap : Lambda.modify_mode
val modify_maybe_stack : Lambda.modify_mode
type initialization_or_assignment =
  1. | Assignment of Lambda.modify_mode
  2. | Heap_initialization
  3. | Root_initialization
type field_read_semantics =
  1. | Reads_agree
  2. | Reads_vary
type has_initializer =
  1. | With_initializer
  2. | Uninitialized
type region_close =
  1. | Rc_normal
  2. | Rc_nontail
  3. | Rc_close_at_apply

Notes about applytail (as emitted by Printlambda) a.k.a. Rc_close_at_apply:

applytail / Rc_close_at_apply means that a call occurs in tail position of the nearest enclosing region, and should be compiled by closing that region (and only that region) just before control is transferred to the call.

In the raw lambda generated by Translcore, this can occur only in tail position of a function, so these do happen to be tail calls. But after inlining (by Simplif or otherwise), this may no longer be the case.

In particular, this code pattern:

(function (region (.... (region ... (applytail f)))))

means that the applytail is in tail position of the inner region and closes that one. It just so happens to be at the end of the outer function as well, but it does not mean that it's a tail call of that function. (It's not a tail call because the outer region needs to end there.)

type any_locality_mode = Scalar.any_locality_mode =
  1. | Any_locality_mode
module Phys_equal : sig ... end
type lazy_block_tag =
  1. | Lazy_tag
  2. | Forward_tag
type primitive =
  1. | Pbytes_to_string
  2. | Pbytes_of_string
  3. | Pignore
  4. | Pgetglobal of Compilation_unit.t
  5. | Pgetpredef of Ident.t
  6. | Pmakeblock of int * Lambda.mutable_flag * Lambda.block_shape * Lambda.locality_mode
  7. | Pmakefloatblock of Lambda.mutable_flag * Lambda.locality_mode
  8. | Pmakeufloatblock of Lambda.mutable_flag * Lambda.locality_mode
  9. | Pmakemixedblock of int * Lambda.mutable_flag * Lambda.mixed_block_shape * Lambda.locality_mode
  10. | Pmakelazyblock of Lambda.lazy_block_tag
  11. | Pfield of int * Lambda.immediate_or_pointer * Lambda.field_read_semantics
  12. | Pfield_computed of Lambda.field_read_semantics
  13. | Psetfield of int * Lambda.immediate_or_pointer * Lambda.initialization_or_assignment
  14. | Psetfield_computed of Lambda.immediate_or_pointer * Lambda.initialization_or_assignment
  15. | Pfloatfield of int * Lambda.field_read_semantics * Lambda.locality_mode
  16. | Pufloatfield of int * Lambda.field_read_semantics
  17. | Pmixedfield of int list * Lambda.mixed_block_shape_with_locality_mode * Lambda.field_read_semantics
    (*

    The index to Pmixedfield corresponds to an element of the shape, not necessarily the index of the field at runtime, as reordering may take place on entry to Flambda 2.

    *)
  18. | Psetfloatfield of int * Lambda.initialization_or_assignment
  19. | Psetufloatfield of int * Lambda.initialization_or_assignment
  20. | Psetmixedfield of int list * Lambda.mixed_block_shape * Lambda.initialization_or_assignment
    (*

    The same comment about the index as for Pmixedfield applies to Psetmixedfield.

    *)
  21. | Pduprecord of Types.record_representation * int
  22. | Pmake_unboxed_product of Lambda.layout list
  23. | Punboxed_product_field of int * Lambda.layout list
  24. | Parray_element_size_in_bytes of Lambda.array_kind
  25. | Pmake_idx_field of int
  26. | Pmake_idx_mixed_field of Lambda.mixed_block_shape * int * int list
    (*

    The lone int is the index into the mixed_block_shape, the int list is the path into that mixed_block_element

    *)
  27. | Pmake_idx_array of Lambda.array_kind * Lambda.array_index_kind * unit Lambda.mixed_block_element * int list
  28. | Pidx_deepen of unit Lambda.mixed_block_element * int list
  29. | Prunstack
  30. | Pperform
  31. | Presume
  32. | Preperform
  33. | Pccall of Lambda.external_call_description
  34. | Praise of Lambda.raise_kind
  35. | Psequand
  36. | Psequor
  37. | Pnot
  38. | Pphys_equal of Lambda.Phys_equal.t
    (*

    Unlike in the language specification, the compiler defines physical equality as referential equality on all values, including immediates and immutable blocks.

    *)
  39. | Pscalar of Lambda.locality_mode Scalar.Operation.t
  40. | Poffsetref of int
  41. | Pstringlength
  42. | Pstringrefu
  43. | Pstringrefs
  44. | Pbyteslength
  45. | Pbytesrefu
  46. | Pbytessetu
  47. | Pbytesrefs
  48. | Pbytessets
  49. | Pmakearray of Lambda.array_kind * Lambda.mutable_flag * Lambda.locality_mode
  50. | Pmakearray_dynamic of Lambda.array_kind * Lambda.locality_mode * Lambda.has_initializer
    (*

    For Pmakearray_dynamic, if the array kind specifies an unboxed product, the float array optimization will never apply.

    *)
  51. | Pduparray of Lambda.array_kind * Lambda.mutable_flag
    (*

    For Pduparray, the argument must be an immutable array. The arguments of Pduparray give the kind and mutability of the array being *produced* by the duplication.

    *)
  52. | Parrayblit of {
    1. src_mutability : Lambda.mutable_flag;
    2. dst_array_set_kind : Lambda.array_set_kind;
    }
    (*

    For Parrayblit, we record the array_set_kind of the destination array. We check that the source array has the same shape, but do not need to know anything about its locality. We do however request the mutability of the source array.

    *)
  53. | Parraylength of Lambda.array_kind
  54. | Parrayrefu of Lambda.array_ref_kind * Lambda.array_index_kind * Lambda.mutable_flag
  55. | Parraysetu of Lambda.array_set_kind * Lambda.array_index_kind
  56. | Parrayrefs of Lambda.array_ref_kind * Lambda.array_index_kind * Lambda.mutable_flag
  57. | Parraysets of Lambda.array_set_kind * Lambda.array_index_kind
  58. | Pisint of {
    1. variant_only : bool;
    }
  59. | Pisnull
  60. | Pisout
  61. | Pbigarrayref of bool * int * Lambda.bigarray_kind * Lambda.bigarray_layout
  62. | Pbigarrayset of bool * int * Lambda.bigarray_kind * Lambda.bigarray_layout
  63. | Pbigarraydim of int
  64. | Pstring_load_16 of {
    1. unsafe : bool;
    2. index_kind : Lambda.array_index_kind;
    }
  65. | Pstring_load_32 of {
    1. unsafe : bool;
    2. index_kind : Lambda.array_index_kind;
    3. mode : Lambda.locality_mode;
    4. boxed : bool;
    }
  66. | Pstring_load_f32 of {
    1. unsafe : bool;
    2. index_kind : Lambda.array_index_kind;
    3. mode : Lambda.locality_mode;
    4. boxed : bool;
    }
  67. | Pstring_load_64 of {
    1. unsafe : bool;
    2. index_kind : Lambda.array_index_kind;
    3. mode : Lambda.locality_mode;
    4. boxed : bool;
    }
  68. | Pstring_load_vec of {
    1. size : Lambda.boxed_vector;
    2. unsafe : bool;
    3. index_kind : Lambda.array_index_kind;
    4. mode : Lambda.locality_mode;
    5. boxed : bool;
    }
  69. | Pbytes_load_16 of {
    1. unsafe : bool;
    2. index_kind : Lambda.array_index_kind;
    }
  70. | Pbytes_load_32 of {
    1. unsafe : bool;
    2. index_kind : Lambda.array_index_kind;
    3. mode : Lambda.locality_mode;
    4. boxed : bool;
    }
  71. | Pbytes_load_f32 of {
    1. unsafe : bool;
    2. index_kind : Lambda.array_index_kind;
    3. mode : Lambda.locality_mode;
    4. boxed : bool;
    }
  72. | Pbytes_load_64 of {
    1. unsafe : bool;
    2. index_kind : Lambda.array_index_kind;
    3. mode : Lambda.locality_mode;
    4. boxed : bool;
    }
  73. | Pbytes_load_vec of {
    1. size : Lambda.boxed_vector;
    2. unsafe : bool;
    3. index_kind : Lambda.array_index_kind;
    4. mode : Lambda.locality_mode;
    5. boxed : bool;
    }
  74. | Pbytes_set_16 of {
    1. unsafe : bool;
    2. index_kind : Lambda.array_index_kind;
    }
  75. | Pbytes_set_32 of {
    1. unsafe : bool;
    2. index_kind : Lambda.array_index_kind;
    3. boxed : bool;
    }
  76. | Pbytes_set_f32 of {
    1. unsafe : bool;
    2. index_kind : Lambda.array_index_kind;
    3. boxed : bool;
    }
  77. | Pbytes_set_64 of {
    1. unsafe : bool;
    2. index_kind : Lambda.array_index_kind;
    3. boxed : bool;
    }
  78. | Pbytes_set_vec of {
    1. size : Lambda.boxed_vector;
    2. unsafe : bool;
    3. index_kind : Lambda.array_index_kind;
    4. boxed : bool;
    }
  79. | Pbigstring_load_16 of {
    1. unsafe : bool;
    2. index_kind : Lambda.array_index_kind;
    }
  80. | Pbigstring_load_32 of {
    1. unsafe : bool;
    2. index_kind : Lambda.array_index_kind;
    3. mode : Lambda.locality_mode;
    4. boxed : bool;
    }
  81. | Pbigstring_load_f32 of {
    1. unsafe : bool;
    2. index_kind : Lambda.array_index_kind;
    3. mode : Lambda.locality_mode;
    4. boxed : bool;
    }
  82. | Pbigstring_load_64 of {
    1. unsafe : bool;
    2. index_kind : Lambda.array_index_kind;
    3. mode : Lambda.locality_mode;
    4. boxed : bool;
    }
  83. | Pbigstring_load_vec of {
    1. size : Lambda.boxed_vector;
    2. aligned : bool;
    3. unsafe : bool;
    4. index_kind : Lambda.array_index_kind;
    5. mode : Lambda.locality_mode;
    6. boxed : bool;
    }
  84. | Pbigstring_set_16 of {
    1. unsafe : bool;
    2. index_kind : Lambda.array_index_kind;
    }
  85. | Pbigstring_set_32 of {
    1. unsafe : bool;
    2. index_kind : Lambda.array_index_kind;
    3. boxed : bool;
    }
  86. | Pbigstring_set_f32 of {
    1. unsafe : bool;
    2. index_kind : Lambda.array_index_kind;
    3. boxed : bool;
    }
  87. | Pbigstring_set_64 of {
    1. unsafe : bool;
    2. index_kind : Lambda.array_index_kind;
    3. boxed : bool;
    }
  88. | Pbigstring_set_vec of {
    1. size : Lambda.boxed_vector;
    2. aligned : bool;
    3. unsafe : bool;
    4. index_kind : Lambda.array_index_kind;
    5. boxed : bool;
    }
  89. | Pfloatarray_load_vec of {
    1. size : Lambda.boxed_vector;
    2. unsafe : bool;
    3. index_kind : Lambda.array_index_kind;
    4. mode : Lambda.locality_mode;
    5. boxed : bool;
    }
  90. | Pfloat_array_load_vec of {
    1. size : Lambda.boxed_vector;
    2. unsafe : bool;
    3. index_kind : Lambda.array_index_kind;
    4. mode : Lambda.locality_mode;
    5. boxed : bool;
    }
  91. | Pint_array_load_vec of {
    1. size : Lambda.boxed_vector;
    2. unsafe : bool;
    3. index_kind : Lambda.array_index_kind;
    4. mode : Lambda.locality_mode;
    5. boxed : bool;
    }
  92. | Punboxed_float_array_load_vec of {
    1. size : Lambda.boxed_vector;
    2. unsafe : bool;
    3. index_kind : Lambda.array_index_kind;
    4. mode : Lambda.locality_mode;
    5. boxed : bool;
    }
  93. | Punboxed_float32_array_load_vec of {
    1. size : Lambda.boxed_vector;
    2. unsafe : bool;
    3. index_kind : Lambda.array_index_kind;
    4. mode : Lambda.locality_mode;
    5. boxed : bool;
    }
  94. | Punboxed_int32_array_load_vec of {
    1. size : Lambda.boxed_vector;
    2. unsafe : bool;
    3. index_kind : Lambda.array_index_kind;
    4. mode : Lambda.locality_mode;
    5. boxed : bool;
    }
  95. | Punboxed_int64_array_load_vec of {
    1. size : Lambda.boxed_vector;
    2. unsafe : bool;
    3. index_kind : Lambda.array_index_kind;
    4. mode : Lambda.locality_mode;
    5. boxed : bool;
    }
  96. | Punboxed_nativeint_array_load_vec of {
    1. size : Lambda.boxed_vector;
    2. unsafe : bool;
    3. index_kind : Lambda.array_index_kind;
    4. mode : Lambda.locality_mode;
    5. boxed : bool;
    }
  97. | Pfloatarray_set_vec of {
    1. size : Lambda.boxed_vector;
    2. unsafe : bool;
    3. index_kind : Lambda.array_index_kind;
    4. boxed : bool;
    }
  98. | Pfloat_array_set_vec of {
    1. size : Lambda.boxed_vector;
    2. unsafe : bool;
    3. index_kind : Lambda.array_index_kind;
    4. boxed : bool;
    }
  99. | Pint_array_set_vec of {
    1. size : Lambda.boxed_vector;
    2. unsafe : bool;
    3. index_kind : Lambda.array_index_kind;
    4. boxed : bool;
    }
  100. | Punboxed_float_array_set_vec of {
    1. size : Lambda.boxed_vector;
    2. unsafe : bool;
    3. index_kind : Lambda.array_index_kind;
    4. boxed : bool;
    }
  101. | Punboxed_float32_array_set_vec of {
    1. size : Lambda.boxed_vector;
    2. unsafe : bool;
    3. index_kind : Lambda.array_index_kind;
    4. boxed : bool;
    }
  102. | Punboxed_int32_array_set_vec of {
    1. size : Lambda.boxed_vector;
    2. unsafe : bool;
    3. index_kind : Lambda.array_index_kind;
    4. boxed : bool;
    }
  103. | Punboxed_int64_array_set_vec of {
    1. size : Lambda.boxed_vector;
    2. unsafe : bool;
    3. index_kind : Lambda.array_index_kind;
    4. boxed : bool;
    }
  104. | Punboxed_nativeint_array_set_vec of {
    1. size : Lambda.boxed_vector;
    2. unsafe : bool;
    3. index_kind : Lambda.array_index_kind;
    4. boxed : bool;
    }
  105. | Pctconst of Lambda.compile_time_constant
  106. | Pint_as_pointer of Lambda.locality_mode
  107. | Patomic_load_field of {
    1. immediate_or_pointer : Lambda.immediate_or_pointer;
    }
  108. | Patomic_set_field of {
    1. immediate_or_pointer : Lambda.immediate_or_pointer;
    }
  109. | Patomic_exchange_field of {
    1. immediate_or_pointer : Lambda.immediate_or_pointer;
    }
  110. | Patomic_compare_exchange_field of {
    1. immediate_or_pointer : Lambda.immediate_or_pointer;
    }
  111. | Patomic_compare_set_field of {
    1. immediate_or_pointer : Lambda.immediate_or_pointer;
    }
  112. | Patomic_fetch_add_field
  113. | Patomic_add_field
  114. | Patomic_sub_field
  115. | Patomic_land_field
  116. | Patomic_lor_field
  117. | Patomic_lxor_field
  118. | Popaque of Lambda.layout
  119. | Pprobe_is_enabled of {
    1. name : string;
    2. enabled_at_init : bool option;
    }
  120. | Pobj_dup
  121. | Pobj_magic of Lambda.layout
  122. | Punbox_unit
  123. | Punbox_vector of Lambda.boxed_vector
  124. | Pbox_vector of Lambda.boxed_vector * Lambda.locality_mode
  125. | Preinterpret_unboxed_int64_as_tagged_int63
  126. | Preinterpret_tagged_int63_as_unboxed_int64
    (*

    At present Preinterpret_unboxed_int64_as_tagged_int63 and Preinterpret_tagged_int63_as_unboxed_int64 will cause a fatal error if the target system is 32-bit bytecode.

    The Preinterpret_tagged_int63_as_unboxed_int64 primitive is the identity on machine words. The Preinterpret_unboxed_int64_as_tagged_int63 compiles to logical OR with 1 on machine words, to ensure that the tag bit is always set in the result, just in case it was not in the incoming unboxed int64.

    *)
  127. | Parray_to_iarray
  128. | Parray_of_iarray
  129. | Pget_header of Lambda.locality_mode
  130. | Ppeek of Lambda.peek_or_poke
  131. | Ppoke of Lambda.peek_or_poke
  132. | Pdls_get
  133. | Ptls_get
  134. | Ppoll
  135. | Pcpu_relax
  136. | Pget_idx of Lambda.layout * Asttypes.mutable_flag
  137. | Pset_idx of Lambda.layout * Lambda.modify_mode
  138. | Pget_ptr of Lambda.layout * Asttypes.mutable_flag
  139. | Pset_ptr of Lambda.layout * Lambda.modify_mode
and extern_repr =
  1. | Same_as_ocaml_repr of Jkind.Sort.Const.t
  2. | Unboxed_float of Lambda.boxed_float
  3. | Unboxed_vector of Lambda.boxed_vector
  4. | Unboxed_or_untagged_integer of Lambda.unboxed_or_untagged_integer

This is the same as Primitive.native_repr but with Repr_poly compiled away.

and external_call_description = Lambda.extern_repr Primitive.description_gen
and array_kind =
  1. | Pgenarray
  2. | Paddrarray
  3. | Pgcignorableaddrarray
  4. | Pintarray
  5. | Pfloatarray
  6. | Punboxedfloatarray of Lambda.unboxed_float
  7. | Punboxedoruntaggedintarray of Lambda.unboxed_or_untagged_integer
  8. | Punboxedvectorarray of Lambda.unboxed_vector
  9. | Pgcscannableproductarray of Lambda.scannable_product_element_kind list
  10. | Pgcignorableproductarray of Lambda.ignorable_product_element_kind list
and array_ref_kind =
  1. | Pgenarray_ref of Lambda.locality_mode
  2. | Paddrarray_ref
  3. | Pgcignorableaddrarray_ref
  4. | Pintarray_ref
  5. | Pfloatarray_ref of Lambda.locality_mode
  6. | Punboxedfloatarray_ref of Lambda.unboxed_float
  7. | Punboxedoruntaggedintarray_ref of Lambda.unboxed_or_untagged_integer
  8. | Punboxedvectorarray_ref of Lambda.unboxed_vector
  9. | Pgcscannableproductarray_ref of Lambda.scannable_product_element_kind list
  10. | Pgcignorableproductarray_ref of Lambda.ignorable_product_element_kind list

When accessing a flat float array, we need to know the mode which we should box the resulting float at.

and array_set_kind =
  1. | Pgenarray_set of Lambda.modify_mode
  2. | Paddrarray_set of Lambda.modify_mode
  3. | Pgcignorableaddrarray_set
  4. | Pintarray_set
  5. | Pfloatarray_set
  6. | Punboxedfloatarray_set of Lambda.unboxed_float
  7. | Punboxedoruntaggedintarray_set of Lambda.unboxed_or_untagged_integer
  8. | Punboxedvectorarray_set of Lambda.unboxed_vector
  9. | Pgcscannableproductarray_set of Lambda.modify_mode * Lambda.scannable_product_element_kind list
  10. | Pgcignorableproductarray_set of Lambda.ignorable_product_element_kind list

When updating an array that might contain pointers, we need to know what mode they're at; otherwise, access is uniform.

and ignorable_product_element_kind =
  1. | Pint_ignorable
  2. | Punboxedfloat_ignorable of Lambda.unboxed_float
  3. | Punboxedoruntaggedint_ignorable of Lambda.unboxed_or_untagged_integer
  4. | Pproduct_ignorable of Lambda.ignorable_product_element_kind list
and scannable_product_element_kind =
  1. | Pint_scannable
  2. | Paddr_scannable
  3. | Pproduct_scannable of Lambda.scannable_product_element_kind list
and array_index_kind =
  1. | Ptagged_int_index
  2. | Punboxed_or_untagged_integer_index of Lambda.unboxed_or_untagged_integer
and nullable =
  1. | Nullable
  2. | Non_nullable

Nullable value kinds allow the special Null value in addition to the values of its underlying type. Non_nullable only allows values of the underlying type.

and value_kind = {
  1. raw_kind : Lambda.value_kind_non_null;
  2. nullable : Lambda.nullable;
}
and value_kind_non_null =
  1. | Pgenval
  2. | Pintval
  3. | Pboxedfloatval of Lambda.boxed_float
  4. | Pboxedintval of Lambda.boxed_integer
  5. | Pvariant of {
    1. consts : int list;
    2. non_consts : (int * Lambda.constructor_shape) list;
      (*

      non_consts must be non-empty. For constant variants Pintval must be used. This causes a small loss of precision but it is not expected to be significant.

      *)
    }
  6. | Parrayval of Lambda.array_kind
  7. | Pboxedvectorval of Lambda.boxed_vector
and layout =
  1. | Ptop
  2. | Pvalue of Lambda.value_kind
  3. | Punboxed_float of Lambda.unboxed_float
  4. | Punboxed_or_untagged_integer of Lambda.unboxed_or_untagged_integer
  5. | Punboxed_vector of Lambda.unboxed_vector
  6. | Punboxed_product of Lambda.layout list
  7. | Pbottom
  8. | Psplicevar of Ident.t
and block_shape = Lambda.value_kind list option
and 'a mixed_block_element =
  1. | Value of Lambda.value_kind
  2. | Float_boxed of 'a
  3. | Float64
  4. | Float32
  5. | Bits8
  6. | Bits16
  7. | Bits32
  8. | Bits64
  9. | Vec128
  10. | Vec256
  11. | Vec512
  12. | Word
  13. | Untagged_immediate
  14. | Product of 'a Lambda.mixed_block_element array
  15. | Splice_variable of Ident.t
and mixed_block_shape = unit Lambda.mixed_block_element array
and mixed_block_shape_with_locality_mode = Lambda.locality_mode Lambda.mixed_block_element array
and constructor_shape =
  1. | Constructor_uniform of Lambda.value_kind list
  2. | Constructor_mixed of Lambda.mixed_block_shape
and unboxed_float = Primitive.unboxed_float =
  1. | Unboxed_float64
  2. | Unboxed_float32
and unboxed_or_untagged_integer = Primitive.unboxed_or_untagged_integer =
  1. | Unboxed_int64
  2. | Unboxed_nativeint
  3. | Unboxed_int32
  4. | Untagged_int16
  5. | Untagged_int8
  6. | Untagged_int
and unboxed_vector = Primitive.unboxed_vector =
  1. | Unboxed_vec128
  2. | Unboxed_vec256
  3. | Unboxed_vec512
and boxed_float = Primitive.boxed_float =
  1. | Boxed_float64
  2. | Boxed_float32
and boxed_integer = Primitive.boxed_integer =
  1. | Boxed_int64
  2. | Boxed_nativeint
  3. | Boxed_int32
and boxed_vector = Primitive.boxed_vector =
  1. | Boxed_vec128
  2. | Boxed_vec256
  3. | Boxed_vec512
and peek_or_poke =
  1. | Ppp_tagged_immediate
  2. | Ppp_untagged_immediate
  3. | Ppp_unboxed_float32
  4. | Ppp_unboxed_float
  5. | Ppp_untagged_int8
  6. | Ppp_untagged_int16
  7. | Ppp_unboxed_int32
  8. | Ppp_unboxed_int64
  9. | Ppp_unboxed_nativeint
and bigarray_kind =
  1. | Pbigarray_unknown
  2. | Pbigarray_float16
  3. | Pbigarray_float32
  4. | Pbigarray_float32_t
  5. | Pbigarray_float64
  6. | Pbigarray_sint8
  7. | Pbigarray_uint8
  8. | Pbigarray_sint16
  9. | Pbigarray_uint16
  10. | Pbigarray_int32
  11. | Pbigarray_int64
  12. | Pbigarray_caml_int
  13. | Pbigarray_native_int
  14. | Pbigarray_complex32
  15. | Pbigarray_complex64
and bigarray_layout =
  1. | Pbigarray_unknown_layout
  2. | Pbigarray_c_layout
  3. | Pbigarray_fortran_layout
and raise_kind =
  1. | Raise_regular
  2. | Raise_reraise
  3. | Raise_notrace
val equal_value_kind : Lambda.value_kind -> Lambda.value_kind -> bool
val equal_layout : Lambda.layout -> Lambda.layout -> bool
val print_boxed_vector : Stdlib.Format.formatter -> Lambda.boxed_vector -> unit
val equal_ignorable_product_element_kind : Lambda.ignorable_product_element_kind -> Lambda.ignorable_product_element_kind -> bool
val must_be_value : Lambda.layout -> Lambda.value_kind
val generic_value : Lambda.value_kind
val layout_of_extern_repr : Lambda.extern_repr -> Lambda.layout
val extern_repr_involves_unboxed_products : Lambda.extern_repr -> bool
type structured_constant =
  1. | Const_base of Lambda.constant
  2. | Const_block of int * Lambda.structured_constant list
  3. | Const_mixed_block of int * Lambda.mixed_block_shape * Lambda.structured_constant list
  4. | Const_float_array of string list
  5. | Const_immstring of string
  6. | Const_float_block of string list
  7. | Const_null
type tailcall_attribute =
  1. | Tailcall_expectation of bool
  2. | Default_tailcall
type inline_attribute =
  1. | Always_inline
  2. | Never_inline
  3. | Available_inline
  4. | Unroll of int
  5. | Default_inline
type inlined_attribute =
  1. | Always_inlined
  2. | Never_inlined
  3. | Hint_inlined
  4. | Unroll of int
  5. | Default_inlined
val equal_inline_attribute : Lambda.inline_attribute -> Lambda.inline_attribute -> bool
val equal_inlined_attribute : Lambda.inlined_attribute -> Lambda.inlined_attribute -> bool
type probe_desc = {
  1. name : string;
  2. enabled_at_init : bool;
}
type probe = Lambda.probe_desc option
type specialise_attribute =
  1. | Always_specialise
  2. | Never_specialise
  3. | Default_specialise
val equal_specialise_attribute : Lambda.specialise_attribute -> Lambda.specialise_attribute -> bool
type local_attribute =
  1. | Always_local
  2. | Never_local
  3. | Default_local
type poll_attribute =
  1. | Error_poll
  2. | Default_poll
type zero_alloc_attribute =
  1. | Default_zero_alloc
  2. | Check of {
    1. strict : bool;
    2. loc : Location.t;
    3. custom_error_msg : string option;
    }
  3. | Assume of {
    1. strict : bool;
    2. never_returns_normally : bool;
    3. never_raises : bool;
    4. loc : Location.t;
    }
type loop_attribute =
  1. | Always_loop
  2. | Never_loop
  3. | Default_loop
type regalloc_attribute =
  1. | Default_regalloc
  2. | Regalloc of Clflags.Register_allocator.t
type regalloc_param_attribute =
  1. | Default_regalloc_params
  2. | Regalloc_params of string list
type curried_function_kind = {
  1. nlocal : int;
}

A well-formed function parameter list is of the form G @ L @ [ Final_arg ], where the values of G and L are of the form More_args { partial_mode }, where partial_mode has locality Global in G and locality Local in L.

nlocal is defined as follows:

  • if

    |L| > 0

    , then

    nlocal = |L| + 1

    .

  • if

    |L| = 0

    , * if the function returns at mode local, the final arg has mode local, or the function itself is allocated locally, then

    nlocal = 1

    . * otherwise,

    nlocal = 0

    .

type function_kind =
  1. | Curried of Lambda.curried_function_kind
  2. | Tupled
type let_kind =
  1. | Strict
  2. | Alias
  3. | StrictOpt
type unique_barrier =
  1. | May_be_pushed_down
  2. | Must_stay_here
val add_barrier_to_let_kind : Lambda.unique_barrier -> Lambda.let_kind -> Lambda.let_kind
type meth_kind =
  1. | Self
  2. | Public
  3. | Cached
val equal_meth_kind : Lambda.meth_kind -> Lambda.meth_kind -> bool
type shared_code = (int * int) list
type static_label = Static_label.t
type function_attribute = {
  1. inline : Lambda.inline_attribute;
  2. specialise : Lambda.specialise_attribute;
  3. local : Lambda.local_attribute;
  4. zero_alloc : Lambda.zero_alloc_attribute;
  5. poll : Lambda.poll_attribute;
  6. loop : Lambda.loop_attribute;
  7. regalloc : Lambda.regalloc_attribute;
  8. regalloc_param : Lambda.regalloc_param_attribute;
  9. cold : bool;
  10. is_a_functor : bool;
  11. is_opaque : bool;
  12. stub : bool;
  13. tmc_candidate : bool;
  14. may_fuse_arity : bool;
  15. unbox_return : bool;
}
type parameter_attribute = {
  1. unbox_param : bool;
}
type debug_uid = Shape.Uid.t

The debug_uid values track typed-tree level identifiers that are then passed down to the lower level IRs and eventually emitted into dwarf output. WARNING: Unlike the name sugggests, these identifiers are not always unique. Instead, in many cases, we use debug_uid_none below, and multiple variables at the level of Lambda or below can use the same debug_uid.

val debug_uid_none : Lambda.debug_uid

debug_uid_none should be used for those identifiers that are not user visible (i.e., that are created internally in the compiler and do not mean anything to users writing OCaml code).

type lparam = {
  1. name : Ident.t;
  2. debug_uid : Lambda.debug_uid;
  3. layout : Lambda.layout;
  4. attributes : Lambda.parameter_attribute;
  5. mode : Lambda.locality_mode;
}
type scoped_location = Debuginfo.Scoped_location.t
type pop_region =
  1. | Popped_region
  2. | Same_region
type lambda =
  1. | Lvar of Ident.t
  2. | Lmutvar of Ident.t
  3. | Lconst of Lambda.structured_constant
  4. | Lapply of Lambda.lambda_apply
  5. | Lfunction of Lambda.lfunction
  6. | Llet of Lambda.let_kind * Lambda.layout * Ident.t * Lambda.debug_uid * Lambda.lambda * Lambda.lambda
  7. | Lmutlet of Lambda.layout * Ident.t * Lambda.debug_uid * Lambda.lambda * Lambda.lambda
  8. | Lletrec of Lambda.rec_binding list * Lambda.lambda
  9. | Lprim of Lambda.primitive * Lambda.lambda list * Lambda.scoped_location
  10. | Lswitch of Lambda.lambda * Lambda.lambda_switch * Lambda.scoped_location * Lambda.layout
  11. | Lstringswitch of Lambda.lambda * (string * Lambda.lambda) list * Lambda.lambda option * Lambda.scoped_location * Lambda.layout
  12. | Lstaticraise of Lambda.static_label * Lambda.lambda list
  13. | Lstaticcatch of Lambda.lambda * Lambda.static_label * (Ident.t * Lambda.debug_uid * Lambda.layout) list * Lambda.lambda * Lambda.pop_region * Lambda.layout
  14. | Ltrywith of Lambda.lambda * Ident.t * Lambda.debug_uid * Lambda.lambda * Lambda.layout
  15. | Lifthenelse of Lambda.lambda * Lambda.lambda * Lambda.lambda * Lambda.layout
  16. | Lsequence of Lambda.lambda * Lambda.lambda
  17. | Lwhile of Lambda.lambda_while
  18. | Lfor of Lambda.lambda_for
  19. | Lassign of Ident.t * Lambda.lambda
  20. | Lsend of Lambda.meth_kind * Lambda.lambda * Lambda.lambda * Lambda.lambda list * Lambda.region_close * Lambda.locality_mode * Lambda.scoped_location * Lambda.layout
  21. | Levent of Lambda.lambda * Lambda.lambda_event
  22. | Lifused of Ident.t * Lambda.lambda
  23. | Lregion of Lambda.lambda * Lambda.layout
  24. | Lexclave of Lambda.lambda
  25. | Lsplice of Lambda.lambda_splice
and rec_binding = {
  1. id : Ident.t;
  2. debug_uid : Lambda.debug_uid;
  3. def : Lambda.lfunction;
}
and lfunction = private {
  1. kind : Lambda.function_kind;
  2. params : Lambda.lparam list;
  3. return : Lambda.layout;
  4. body : Lambda.lambda;
  5. attr : Lambda.function_attribute;
  6. loc : Lambda.scoped_location;
  7. mode : Lambda.locality_mode;
  8. ret_mode : Lambda.locality_mode;
    (*

    alloc mode of the returned value. Also indicates if the function might allocate in the caller's region.

    *)
}
and lambda_while = {
  1. wh_cond : Lambda.lambda;
  2. wh_body : Lambda.lambda;
}
and lambda_for = {
  1. for_id : Ident.t;
  2. for_debug_uid : Lambda.debug_uid;
  3. for_loc : Lambda.scoped_location;
  4. for_from : Lambda.lambda;
  5. for_to : Lambda.lambda;
  6. for_dir : Asttypes.direction_flag;
  7. for_body : Lambda.lambda;
}
and lambda_apply = {
  1. ap_func : Lambda.lambda;
  2. ap_args : Lambda.lambda list;
  3. ap_result_layout : Lambda.layout;
  4. ap_region_close : Lambda.region_close;
  5. ap_mode : Lambda.locality_mode;
  6. ap_loc : Lambda.scoped_location;
  7. ap_tailcall : Lambda.tailcall_attribute;
  8. ap_inlined : Lambda.inlined_attribute;
  9. ap_specialised : Lambda.specialise_attribute;
  10. ap_probe : Lambda.probe;
}
and lambda_switch = {
  1. sw_numconsts : int;
  2. sw_consts : (int * Lambda.lambda) list;
  3. sw_numblocks : int;
  4. sw_blocks : (int * Lambda.lambda) list;
  5. sw_failaction : Lambda.lambda option;
}
and lambda_event = {
  1. lev_loc : Lambda.scoped_location;
  2. lev_kind : Lambda.lambda_event_kind;
  3. lev_repr : int Stdlib.ref option;
  4. lev_env : Env.t;
}
and lambda_event_kind =
  1. | Lev_before
  2. | Lev_after of Types.type_expr
  3. | Lev_function
  4. | Lev_pseudo
and lambda_splice = {
  1. splice_loc : Lambda.scoped_location;
  2. slambda : Lambda.slambda;
}
type runtime_param =
  1. | Rp_argument_block of Global_module.t
  2. | Rp_main_module_block of Global_module.t
  3. | Rp_unit
type module_representation =
  1. | Module_value_only of {
    1. field_count : int;
    }
  2. | Module_mixed of Lambda.mixed_block_shape * Lambda.mixed_block_shape_with_locality_mode
val module_representation_field_count : Lambda.module_representation -> int
val layout_of_module_field : Lambda.module_representation -> int -> Lambda.layout
type main_module_block_format =
  1. | Mb_struct of {
    1. mb_repr : Lambda.module_representation;
    }
  2. | Mb_instantiating_functor of {
    1. mb_runtime_params : Lambda.runtime_param list;
    2. mb_returned_repr : Lambda.module_representation;
    }
type program = {
  1. compilation_unit : Compilation_unit.t;
  2. main_module_block_format : Lambda.main_module_block_format;
  3. arg_block_idx : int option;
  4. required_globals : Compilation_unit.Set.t;
  5. code : Lambda.lambda;
}
type arg_descr = {
  1. arg_param : Global_module.Parameter_name.t;
  2. arg_block_idx : int;
  3. main_repr : Lambda.module_representation;
}
val make_key : Lambda.lambda -> Lambda.lambda option
val const_int : int -> Lambda.structured_constant
val tagged_immediate : int -> Lambda.lambda
val lambda_unit : Lambda.lambda
val of_bool : bool -> Lambda.lambda
val layout_unit : Lambda.layout
val layout_unboxed_unit : Lambda.layout
val layout_int : Lambda.layout
val layout_array : Lambda.array_kind -> Lambda.layout
val layout_block : Lambda.layout
val layout_list : Lambda.layout
val layout_exception : Lambda.layout
val layout_function : Lambda.layout
val layout_object : Lambda.layout
val layout_class : Lambda.layout
val layout_module : Lambda.layout
val layout_functor : Lambda.layout
val layout_string : Lambda.layout
val layout_boxed_float : Lambda.boxed_float -> Lambda.layout
val layout_unboxed_float : Lambda.unboxed_float -> Lambda.layout
val layout_boxed_int : Lambda.boxed_integer -> Lambda.layout
val layout_boxed_vector : Lambda.boxed_vector -> Lambda.layout
val layout_tuple_element : Lambda.layout
val layout_variant_arg : Lambda.layout
val layout_tmc_field : Lambda.layout
val layout_optional_arg : Lambda.layout
val layout_value_field : Lambda.layout
val layout_predef_value : Lambda.layout
val layout_lazy : Lambda.layout
val layout_lazy_contents : Lambda.layout
val layout_any_value : Lambda.layout
val layout_letrec : Lambda.layout
val layout_probe_arg : Lambda.layout
val layout_unboxed_product : Lambda.layout list -> Lambda.layout
val layout_top : Lambda.layout
val layout_bottom : Lambda.layout
val mixed_block_element_for_module : unit Lambda.mixed_block_element
val mixed_block_element_with_locality_mode_for_module : Lambda.locality_mode Lambda.mixed_block_element
val dummy_constant : Lambda.lambda

dummy_constant produces a placeholder value with a recognizable bit pattern (currently 0xBBBB in its tagged form)

val name_lambda_list : (Lambda.lambda * Lambda.layout) list -> (Lambda.lambda list -> Lambda.lambda) -> Lambda.lambda
val iter_head_constructor : (Lambda.lambda -> unit) -> Lambda.lambda -> unit

iter_head_constructor f lam apply f to only the first level of sub expressions of lam. It does not recursively traverse the expression.

val shallow_iter : tail:(Lambda.lambda -> unit) -> non_tail:(Lambda.lambda -> unit) -> Lambda.lambda -> unit

Same as iter_head_constructor, but use a different callback for sub-terms which are in tail position or not.

val transl_prim : string -> string -> Lambda.lambda

Translate a value from a persistent module. For instance:

  transl_internal_value "CamlinternalLazy" "force"
val free_variables : Lambda.lambda -> Ident.Set.t
val transl_module_path : Lambda.scoped_location -> Env.t -> Path.t -> Lambda.lambda
val transl_value_path : Lambda.scoped_location -> Env.t -> Path.t -> Lambda.lambda
val transl_extension_path : Lambda.scoped_location -> Env.t -> Path.t -> Lambda.lambda
val transl_class_path : Lambda.scoped_location -> Env.t -> Path.t -> Lambda.lambda
val transl_mixed_product_shape : Types.mixed_product_shape -> Lambda.mixed_block_shape
val transl_mixed_product_shape_for_read : get_value_kind:(int -> Lambda.value_kind) -> get_mode:(int -> 'a) -> Types.mixed_product_shape -> 'a Lambda.mixed_block_element array
val transl_module_representation : Types.module_representation -> Lambda.module_representation
val block_of_module_representation : loc:Warnings.loc -> Lambda.module_representation -> Lambda.primitive
val make_sequence : ('a -> Lambda.lambda) -> 'a list -> Lambda.lambda
val subst : (Ident.t -> (Subst.Lazy.value_description * Mode.Value.l) -> Env.t -> Env.t) -> ?freshen_bound_variables:bool -> Lambda.lambda Ident.Map.t -> Lambda.lambda -> Lambda.lambda

subst update_env ?freshen_bound_variables s lt applies a substitution s to the lambda-term lt.

Assumes that the image of the substitution is out of reach of the bound variables of the lambda-term (no capture).

update_env is used to refresh the environment contained in debug events.

freshen_bound_variables, which defaults to false, freshens the bound variables within lt.

A version of subst specialized for the case where we're just renaming idents.

val duplicate_function : Lambda.lfunction -> Lambda.lfunction

Duplicate a term, freshening all locally-bound identifiers.

Bottom-up rewriting, applying the function on each node from the leaves to the root.

Apply the given transformation on the function's body

val shallow_map : tail:(Lambda.lambda -> Lambda.lambda) -> non_tail:(Lambda.lambda -> Lambda.lambda) -> Lambda.lambda -> Lambda.lambda

Rewrite each immediate sub-term with the function.

val default_function_attribute : Lambda.function_attribute
val default_stub_attribute : Lambda.function_attribute
val default_param_attribute : Lambda.parameter_attribute
val find_exact_application : Lambda.function_kind -> arity:int -> Lambda.lambda list -> Lambda.lambda list option
val max_arity : unit -> int

Maximal number of parameters for a function, or in other words, maximal length of the params list of a lfunction record. This is unlimited (max_int) for bytecode, but limited (currently to 126) for native code.

val sub_locality_mode : Lambda.locality_mode -> Lambda.locality_mode -> bool
val eq_locality_mode : Lambda.locality_mode -> Lambda.locality_mode -> bool
val is_local_mode : Lambda.locality_mode -> bool
val is_heap_mode : Lambda.locality_mode -> bool
val primitive_may_allocate : Lambda.primitive -> Lambda.locality_mode option

Whether and where a primitive may allocate. Some Alloc_local permits both options: that is, primitives that may allocate on both the GC heap and locally report this value.

This treats projecting an unboxed float from a float record as non-allocating, which is a lie for the bytecode backend (where unboxed floats are boxed). Presently this function is only used for stack allocation, which doesn't happen in bytecode. If that changes, or if we want to use this for another purpose in bytecode, it will need to be revised.

val locality_mode_of_primitive_description : Lambda.external_call_description -> Lambda.locality_mode option

Like primitive_may_allocate, for external calls.

val next_raise_count : unit -> Lambda.static_label
val staticfail : Lambda.lambda
val is_guarded : Lambda.lambda -> bool
val patch_guarded : Lambda.lambda -> Lambda.lambda -> Lambda.lambda
val raise_kind : Lambda.raise_kind -> string
val reset : unit -> unit

Helpers for module block accesses. Module accesses are always immutable, except in translobj where the method cache is stored in a mutable module field.

val structured_constant_layout : Lambda.structured_constant -> Lambda.layout
val mixed_block_element_of_layout : Lambda.layout -> unit Lambda.mixed_block_element
val value_kind_of_value_with_externality : Jkind_axis.Externality.t -> Lambda.value_kind_non_null

Pintval if a type of value jkind is GC-ignorable based on its provided externality, and Pgenval otherwise.

val layout_of_mixed_block_element_for_idx_set : Jkind_axis.Externality.t -> _ Lambda.mixed_block_element -> Lambda.layout
val mixed_block_element_leaves : 'a Lambda.mixed_block_element -> 'a Lambda.mixed_block_element list
val will_be_reordered : _ Lambda.mixed_block_element -> bool

Whether there exists a non-value before a value

val primitive_result_layout : Lambda.primitive -> Lambda.layout
val array_ref_kind_result_layout : Lambda.array_ref_kind -> Lambda.layout

The mode will be discarded if unnecessary for the given array_kind

The mode will be discarded if unnecessary for the given array_kind

val array_ref_kind_of_array_set_kind : Lambda.array_set_kind -> Lambda.locality_mode -> Lambda.array_ref_kind

Any mode information in the given array_set_kind is ignored. Any mode in the return value always comes from the locality_mode parameter.

val may_allocate_in_region : Lambda.lambda -> bool
val simple_prim_on_values : name:string -> arity:int -> alloc:bool -> Lambda.external_call_description
val try_to_find_location : Lambda.lambda -> Lambda.scoped_location
val try_to_find_debuginfo : Lambda.lambda -> Debuginfo.t
val primitive_can_raise : Lambda.primitive -> bool
val count_initializers_array_kind : Lambda.array_kind -> int
val ignorable_product_element_kind_involves_int : Lambda.ignorable_product_element_kind -> bool
val array_element_size_in_bytes : Lambda.array_kind -> int

This function currently assumes a 64-bit target.

Construction helpers

val int : _ Scalar.Integral.t

A tagged immediate.

See the comment on the Pphys_equal primitive. This can be applied to any arguments of kind value.

type 'a unop := 'a -> Lambda.lambda -> loc:Lambda.scoped_location -> Lambda.lambda

This is ONLY for comparing scalar integral values.

It may NOT be applied to arbitrary arguments of kind value, as it can cause flambda2 to infer that the arguments are always both tagged immediates. Use phys_equal to compare values when either of them might not be an immediate.