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 : locality_mode
val alloc_local : locality_mode
val modify_heap : modify_mode
val modify_maybe_stack : modify_mode
type staticity =
  1. | Static
  2. | Dynamic
type initialization_or_assignment =
  1. | Assignment of 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 * staticity
  5. | Pgetpredef of Ident.t
  6. | Pmakeblock of int * mutable_flag * block_shape * locality_mode
  7. | Pmakefloatblock of mutable_flag * locality_mode
  8. | Pmakeufloatblock of mutable_flag * locality_mode
  9. | Pmakelazyblock of lazy_block_tag
  10. | Pfield of int * immediate_or_pointer * field_read_semantics
  11. | Pfield_computed of field_read_semantics
  12. | Psetfield of int * immediate_or_pointer * initialization_or_assignment
  13. | Psetfield_computed of immediate_or_pointer * initialization_or_assignment
  14. | Pfloatfield of int * field_read_semantics * locality_mode
  15. | Pufloatfield of int * field_read_semantics
  16. | Pmixedfield of int list * mixed_block_shape_with_locality_mode * 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.

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

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

    *)
  20. | Pduprecord of Types.record_representation * int
  21. | Pmake_unboxed_product of layout list
  22. | Punboxed_product_field of int * layout list
  23. | Parray_element_size_in_bytes of array_kind
  24. | Pmake_idx_field of int
  25. | Pmake_idx_mixed_field of 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

    *)
  26. | Pmake_idx_array of array_kind * array_index_kind * unit mixed_block_element * int list
  27. | Pidx_deepen of unit mixed_block_element * int list
  28. | Pwith_stack
  29. | Pwith_stack_bind
  30. | Pperform
  31. | Presume
  32. | Preperform
  33. | Pccall of external_call_description
  34. | Praise of raise_kind
  35. | Psequand
  36. | Psequor
  37. | Pnot
  38. | Pphys_equal of 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 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 array_kind * mutable_flag * locality_mode
  50. | Pmakearray_dynamic of array_kind * locality_mode * has_initializer
    (*

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

    *)
  51. | Pduparray of array_kind * 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 : mutable_flag;
    2. dst_array_set_kind : 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 array_kind
  54. | Parrayrefu of array_ref_kind * array_index_kind * mutable_flag
  55. | Parraysetu of array_set_kind * array_index_kind
  56. | Parrayrefs of array_ref_kind * array_index_kind * mutable_flag
  57. | Parraysets of array_set_kind * array_index_kind
  58. | Pisint of {
    1. variant_only : bool;
    }
  59. | Pisnull
  60. | Pisout
  61. | Pbigarrayref of bool * int * bigarray_kind * bigarray_layout
  62. | Pbigarrayset of bool * int * bigarray_kind * bigarray_layout
  63. | Pbigarraydim of int
  64. | Pstring_load_i8 of {
    1. unsafe : bool;
    2. index_kind : array_index_kind;
    3. tagged : bool;
    }
  65. | Pstring_load_i16 of {
    1. unsafe : bool;
    2. index_kind : array_index_kind;
    3. tagged : bool;
    }
  66. | Pstring_load_16 of {
    1. unsafe : bool;
    2. index_kind : array_index_kind;
    }
  67. | Pstring_load_32 of {
    1. unsafe : bool;
    2. index_kind : array_index_kind;
    3. mode : locality_mode;
    4. boxed : bool;
    }
  68. | Pstring_load_f32 of {
    1. unsafe : bool;
    2. index_kind : array_index_kind;
    3. mode : locality_mode;
    4. boxed : bool;
    }
  69. | Pstring_load_64 of {
    1. unsafe : bool;
    2. index_kind : array_index_kind;
    3. mode : locality_mode;
    4. boxed : bool;
    }
  70. | Pstring_load_vec of {
    1. size : boxed_vector;
    2. unsafe : bool;
    3. index_kind : array_index_kind;
    4. mode : locality_mode;
    5. boxed : bool;
    }
  71. | Pbytes_load_i8 of {
    1. unsafe : bool;
    2. index_kind : array_index_kind;
    3. tagged : bool;
    }
  72. | Pbytes_load_i16 of {
    1. unsafe : bool;
    2. index_kind : array_index_kind;
    3. tagged : bool;
    }
  73. | Pbytes_load_16 of {
    1. unsafe : bool;
    2. index_kind : array_index_kind;
    }
  74. | Pbytes_load_32 of {
    1. unsafe : bool;
    2. index_kind : array_index_kind;
    3. mode : locality_mode;
    4. boxed : bool;
    }
  75. | Pbytes_load_f32 of {
    1. unsafe : bool;
    2. index_kind : array_index_kind;
    3. mode : locality_mode;
    4. boxed : bool;
    }
  76. | Pbytes_load_64 of {
    1. unsafe : bool;
    2. index_kind : array_index_kind;
    3. mode : locality_mode;
    4. boxed : bool;
    }
  77. | Pbytes_load_vec of {
    1. size : boxed_vector;
    2. unsafe : bool;
    3. index_kind : array_index_kind;
    4. mode : locality_mode;
    5. boxed : bool;
    }
  78. | Pbytes_set_8 of {
    1. unsafe : bool;
    2. index_kind : array_index_kind;
    3. tagged : bool;
    }
  79. | Pbytes_set_16 of {
    1. unsafe : bool;
    2. index_kind : array_index_kind;
    3. tagged : bool;
    }
  80. | Pbytes_set_32 of {
    1. unsafe : bool;
    2. index_kind : array_index_kind;
    3. boxed : bool;
    }
  81. | Pbytes_set_f32 of {
    1. unsafe : bool;
    2. index_kind : array_index_kind;
    3. boxed : bool;
    }
  82. | Pbytes_set_64 of {
    1. unsafe : bool;
    2. index_kind : array_index_kind;
    3. boxed : bool;
    }
  83. | Pbytes_set_vec of {
    1. size : boxed_vector;
    2. unsafe : bool;
    3. index_kind : array_index_kind;
    4. boxed : bool;
    }
  84. | Pbigstring_load_i8 of {
    1. unsafe : bool;
    2. index_kind : array_index_kind;
    3. tagged : bool;
    }
  85. | Pbigstring_load_i16 of {
    1. unsafe : bool;
    2. index_kind : array_index_kind;
    3. tagged : bool;
    }
  86. | Pbigstring_load_16 of {
    1. unsafe : bool;
    2. index_kind : array_index_kind;
    }
  87. | Pbigstring_load_32 of {
    1. unsafe : bool;
    2. index_kind : array_index_kind;
    3. mode : locality_mode;
    4. boxed : bool;
    }
  88. | Pbigstring_load_f32 of {
    1. unsafe : bool;
    2. index_kind : array_index_kind;
    3. mode : locality_mode;
    4. boxed : bool;
    }
  89. | Pbigstring_load_64 of {
    1. unsafe : bool;
    2. index_kind : array_index_kind;
    3. mode : locality_mode;
    4. boxed : bool;
    }
  90. | Pbigstring_load_vec of {
    1. size : boxed_vector;
    2. checks : (len:int * align:int) option;
    3. index_kind : array_index_kind;
    4. mode : locality_mode;
    5. aligned : bool;
    6. boxed : bool;
    }
  91. | Pbigstring_set_8 of {
    1. unsafe : bool;
    2. index_kind : array_index_kind;
    3. tagged : bool;
    }
  92. | Pbigstring_set_16 of {
    1. unsafe : bool;
    2. index_kind : array_index_kind;
    3. tagged : bool;
    }
  93. | Pbigstring_set_32 of {
    1. unsafe : bool;
    2. index_kind : array_index_kind;
    3. boxed : bool;
    }
  94. | Pbigstring_set_f32 of {
    1. unsafe : bool;
    2. index_kind : array_index_kind;
    3. boxed : bool;
    }
  95. | Pbigstring_set_64 of {
    1. unsafe : bool;
    2. index_kind : array_index_kind;
    3. boxed : bool;
    }
  96. | Pbigstring_set_vec of {
    1. size : boxed_vector;
    2. checks : (len:int * align:int) option;
    3. index_kind : array_index_kind;
    4. aligned : bool;
    5. boxed : bool;
    }
  97. | Pfloatarray_load_vec of {
    1. size : boxed_vector;
    2. unsafe : bool;
    3. index_kind : array_index_kind;
    4. mode : locality_mode;
    5. boxed : bool;
    }
  98. | Pfloat_array_load_vec of {
    1. size : boxed_vector;
    2. unsafe : bool;
    3. index_kind : array_index_kind;
    4. mode : locality_mode;
    5. boxed : bool;
    }
  99. | Pint_array_load_vec of {
    1. size : boxed_vector;
    2. unsafe : bool;
    3. index_kind : array_index_kind;
    4. mode : locality_mode;
    5. boxed : bool;
    }
  100. | Punboxed_float_array_load_vec of {
    1. size : boxed_vector;
    2. unsafe : bool;
    3. index_kind : array_index_kind;
    4. mode : locality_mode;
    5. boxed : bool;
    }
  101. | Punboxed_float32_array_load_vec of {
    1. size : boxed_vector;
    2. unsafe : bool;
    3. index_kind : array_index_kind;
    4. mode : locality_mode;
    5. boxed : bool;
    }
  102. | Puntagged_int8_array_load_vec of {
    1. size : boxed_vector;
    2. unsafe : bool;
    3. index_kind : array_index_kind;
    4. mode : locality_mode;
    5. boxed : bool;
    }
  103. | Puntagged_int16_array_load_vec of {
    1. size : boxed_vector;
    2. unsafe : bool;
    3. index_kind : array_index_kind;
    4. mode : locality_mode;
    5. boxed : bool;
    }
  104. | Punboxed_int32_array_load_vec of {
    1. size : boxed_vector;
    2. unsafe : bool;
    3. index_kind : array_index_kind;
    4. mode : locality_mode;
    5. boxed : bool;
    }
  105. | Punboxed_int64_array_load_vec of {
    1. size : boxed_vector;
    2. unsafe : bool;
    3. index_kind : array_index_kind;
    4. mode : locality_mode;
    5. boxed : bool;
    }
  106. | Punboxed_nativeint_array_load_vec of {
    1. size : boxed_vector;
    2. unsafe : bool;
    3. index_kind : array_index_kind;
    4. mode : locality_mode;
    5. boxed : bool;
    }
  107. | Pfloatarray_set_vec of {
    1. size : boxed_vector;
    2. unsafe : bool;
    3. index_kind : array_index_kind;
    4. boxed : bool;
    }
  108. | Pfloat_array_set_vec of {
    1. size : boxed_vector;
    2. unsafe : bool;
    3. index_kind : array_index_kind;
    4. boxed : bool;
    }
  109. | Pint_array_set_vec of {
    1. size : boxed_vector;
    2. unsafe : bool;
    3. index_kind : array_index_kind;
    4. boxed : bool;
    }
  110. | Punboxed_float_array_set_vec of {
    1. size : boxed_vector;
    2. unsafe : bool;
    3. index_kind : array_index_kind;
    4. boxed : bool;
    }
  111. | Punboxed_float32_array_set_vec of {
    1. size : boxed_vector;
    2. unsafe : bool;
    3. index_kind : array_index_kind;
    4. boxed : bool;
    }
  112. | Puntagged_int8_array_set_vec of {
    1. size : boxed_vector;
    2. unsafe : bool;
    3. index_kind : array_index_kind;
    4. boxed : bool;
    }
  113. | Puntagged_int16_array_set_vec of {
    1. size : boxed_vector;
    2. unsafe : bool;
    3. index_kind : array_index_kind;
    4. boxed : bool;
    }
  114. | Punboxed_int32_array_set_vec of {
    1. size : boxed_vector;
    2. unsafe : bool;
    3. index_kind : array_index_kind;
    4. boxed : bool;
    }
  115. | Punboxed_int64_array_set_vec of {
    1. size : boxed_vector;
    2. unsafe : bool;
    3. index_kind : array_index_kind;
    4. boxed : bool;
    }
  116. | Punboxed_nativeint_array_set_vec of {
    1. size : boxed_vector;
    2. unsafe : bool;
    3. index_kind : array_index_kind;
    4. boxed : bool;
    }
  117. | Pctconst of compile_time_constant
  118. | Pint_as_pointer of locality_mode
  119. | Patomic_load_field of {
    1. immediate_or_pointer : immediate_or_pointer;
    }
  120. | Patomic_set_field of {
    1. immediate_or_pointer : immediate_or_pointer;
    }
  121. | Patomic_exchange_field of {
    1. immediate_or_pointer : immediate_or_pointer;
    }
  122. | Patomic_compare_exchange_field of {
    1. immediate_or_pointer : immediate_or_pointer;
    }
  123. | Patomic_compare_set_field of {
    1. immediate_or_pointer : immediate_or_pointer;
    }
  124. | Patomic_fetch_add_field
  125. | Patomic_add_field
  126. | Patomic_sub_field
  127. | Patomic_land_field
  128. | Patomic_lor_field
  129. | Patomic_lxor_field
  130. | Popaque of layout
  131. | Pprobe_is_enabled of {
    1. name : string;
    2. enabled_at_init : bool option;
    }
  132. | Pobj_dup
  133. | Pobj_magic of layout
  134. | Punbox_unit
  135. | Punbox_vector of boxed_vector
  136. | Pbox_vector of boxed_vector * locality_mode
  137. | Pjoin_vec256
  138. | Psplit_vec256
  139. | Preinterpret_boxed_vector_as_tuple of boxed_vector
  140. | Preinterpret_tuple_as_boxed_vector of boxed_vector
  141. | Preinterpret_unboxed_int64_as_tagged_int63
  142. | 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.

    *)
  143. | Parray_to_iarray
  144. | Parray_of_iarray
  145. | Pget_header of locality_mode
  146. | Ppeek of peek_or_poke
  147. | Ppoke of peek_or_poke
  148. | Pdls_get
  149. | Ptls_get
  150. | Pdomain_index
  151. | Ppoll
  152. | Pcpu_relax
  153. | Pget_idx of layout * Asttypes.mutable_flag
  154. | Pset_idx of layout * modify_mode
  155. | Pget_ptr of layout * Asttypes.mutable_flag
  156. | Pset_ptr of layout * modify_mode
and extern_repr =
  1. | Same_as_ocaml_repr of Jkind.Sort.Const.t
  2. | Unboxed_float of boxed_float
  3. | Unboxed_vector of boxed_vector
  4. | Unboxed_or_untagged_integer of unboxed_or_untagged_integer

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

and external_call_description = extern_repr Primitive.description_gen
and array_kind =
  1. | Pgenarray
  2. | Paddrarray
  3. | Pgcignorableaddrarray
  4. | Pintarray
  5. | Pfloatarray
  6. | Punboxedfloatarray of unboxed_float
  7. | Punboxedoruntaggedintarray of unboxed_or_untagged_integer
  8. | Punboxedvectorarray of unboxed_vector
  9. | Pgcscannableproductarray of scannable_product_element_kind list
  10. | Pgcignorableproductarray of ignorable_product_element_kind list
and array_ref_kind =
  1. | Pgenarray_ref of locality_mode
  2. | Paddrarray_ref
  3. | Pgcignorableaddrarray_ref
  4. | Pintarray_ref
  5. | Pfloatarray_ref of locality_mode
  6. | Punboxedfloatarray_ref of unboxed_float
  7. | Punboxedoruntaggedintarray_ref of unboxed_or_untagged_integer
  8. | Punboxedvectorarray_ref of unboxed_vector
  9. | Pgcscannableproductarray_ref of scannable_product_element_kind list
  10. | Pgcignorableproductarray_ref of 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 modify_mode
  2. | Paddrarray_set of modify_mode
  3. | Pgcignorableaddrarray_set
  4. | Pintarray_set
  5. | Pfloatarray_set
  6. | Punboxedfloatarray_set of unboxed_float
  7. | Punboxedoruntaggedintarray_set of unboxed_or_untagged_integer
  8. | Punboxedvectorarray_set of unboxed_vector
  9. | Pgcscannableproductarray_set of modify_mode * scannable_product_element_kind list
  10. | Pgcignorableproductarray_set of 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 unboxed_float
  3. | Punboxedvector_ignorable of unboxed_vector
  4. | Punboxedoruntaggedint_ignorable of unboxed_or_untagged_integer
  5. | Pproduct_ignorable of ignorable_product_element_kind list
and scannable_product_element_kind =
  1. | Pint_scannable
  2. | Paddr_scannable
  3. | Pproduct_scannable of scannable_product_element_kind list
and array_index_kind =
  1. | Ptagged_int_index
  2. | Punboxed_or_untagged_integer_index of 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 : value_kind_non_null;
  2. nullable : nullable;
}
and value_kind_non_null =
  1. | Pgenval
  2. | Pintval
  3. | Pboxedfloatval of boxed_float
  4. | Pboxedintval of boxed_integer
  5. | Pvariant of {
    1. consts : int list;
    2. non_consts : (int * 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 array_kind
  7. | Pboxedvectorval of boxed_vector
and layout =
  1. | Ptop
  2. | Pvalue of value_kind
  3. | Punboxed_float of unboxed_float
  4. | Punboxed_or_untagged_integer of unboxed_or_untagged_integer
  5. | Punboxed_vector of unboxed_vector
  6. | Punboxed_product of layout list
  7. | Pbottom
  8. | Psplicevar of Ident.t
and block_shape =
  1. | All_value
    (*

    The block shape is a uniform block of generic_values, the length can be determined from the application site.

    *)
  2. | Shape of mixed_block_shape
    (*

    A specific block shape, this may be a uniform block or a mixed block.

    *)
and 'a mixed_block_element =
  1. | Value of 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 mixed_block_element array
  15. | Splice_variable of Ident.t
and mixed_block_shape = unit mixed_block_element array
and mixed_block_shape_with_locality_mode = locality_mode mixed_block_element array
and constructor_shape =
  1. | Constructor_uniform of value_kind list
  2. | Constructor_mixed of 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_raise_kind : raise_kind -> raise_kind -> bool
val equal_value_kind : value_kind -> value_kind -> bool
val equal_layout : layout -> layout -> bool
val print_boxed_vector : Format.formatter -> boxed_vector -> unit
val equal_ignorable_product_element_kind : ignorable_product_element_kind -> ignorable_product_element_kind -> bool
val must_be_value : layout -> value_kind
val generic_value : value_kind
val layout_of_extern_repr : extern_repr -> layout
val element_layout_of_array_kind : array_kind -> layout
val extern_repr_involves_unboxed_products : extern_repr -> bool
type structured_constant =
  1. | Const_base of constant
  2. | Const_block of int * structured_constant list
  3. | Const_mixed_block of int * mixed_block_shape * 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 : inline_attribute -> inline_attribute -> bool
val equal_inlined_attribute : inlined_attribute -> inlined_attribute -> bool
type probe_desc = {
  1. name : string;
  2. enabled_at_init : bool;
}
type probe = probe_desc option
type specialise_attribute =
  1. | Always_specialise
  2. | Never_specialise
  3. | Default_specialise
val equal_specialise_attribute : specialise_attribute -> 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 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 : unique_barrier -> let_kind -> let_kind
type meth_kind =
  1. | Self
  2. | Public
  3. | Cached
val equal_meth_kind : meth_kind -> meth_kind -> bool
type shared_code = (int * int) list
type static_label = Static_label.t
type function_attribute = {
  1. inline : inline_attribute;
  2. specialise : specialise_attribute;
  3. local : local_attribute;
  4. zero_alloc : zero_alloc_attribute;
  5. poll : poll_attribute;
  6. loop : loop_attribute;
  7. regalloc : regalloc_attribute;
  8. regalloc_param : 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 : 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 : debug_uid;
  3. layout : layout;
  4. attributes : parameter_attribute;
  5. mode : 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 structured_constant
  4. | Lapply of lambda_apply
  5. | Lfunction of lfunction
  6. | Llet of let_kind * layout * Ident.t * debug_uid * lambda * lambda
  7. | Lmutlet of layout * Ident.t * debug_uid * lambda * lambda
  8. | Lletrec of rec_binding list * lambda
  9. | Lprim of primitive * lambda list * scoped_location
  10. | Lswitch of lambda * lambda_switch * scoped_location * layout
  11. | Lstringswitch of lambda * (string * lambda) list * lambda option * scoped_location * layout
  12. | Lstaticraise of static_label * lambda list
  13. | Lstaticcatch of lambda * static_label * (Ident.t * debug_uid * layout) list * lambda * pop_region * layout
  14. | Ltrywith of lambda * Ident.t * debug_uid * lambda * layout
  15. | Lifthenelse of lambda * lambda * lambda * layout
  16. | Lsequence of lambda * lambda
  17. | Lwhile of lambda_while
  18. | Lfor of lambda_for
  19. | Lassign of Ident.t * lambda
  20. | Lsend of meth_kind * lambda * lambda * lambda list * region_close * locality_mode * scoped_location * layout
  21. | Levent of lambda * lambda_event
  22. | Lifused of Ident.t * lambda
  23. | Lregion of lambda * layout
  24. | Lexclave of lambda
  25. | Lsplice of scoped_location * slambda

The lambda type is shared across multiple phases of compilation, where some constructors are invalid at different stages.

Compilation looks like:

typedtree
---transl--> tlambda
--fracture-> slambda
----eval---> rawlambda
---simplif-> lambda

where tlambda, slambda, rawlambda, and lambda are all represented using this type.

Most constructors are valid at all stages, the constructors that aren't document this. The only other difference is that layout can contain variables before eval (tlambda and slambda) and not after eval (rawlambda and lambda).

and slambda =
  1. | SLlayout of layout
  2. | SLglobal of Compilation_unit.t
  3. | SLvar of Slambdaident.t
  4. | SLmissing
  5. | SLrecord of slambda list
  6. | SLfield of slambda * int
  7. | SLhalves of slambda_halves
  8. | SLproj_comptime of slambda
    (*

    Project out the compiletime half of a slambda_halves

    *)
  9. | SLtemplate of slambda_function
  10. | SLinstantiate of slambda_apply
  11. | SLlet of slambda_let
and slambda_halves = {
  1. sval_comptime : slambda;
  2. sval_runtime : lambda;
}
and slambda_function = {
  1. sfun_params : Slambdaident.t array;
  2. sfun_body : slambda;
}
and slambda_apply = {
  1. sapp_func : slambda;
  2. sapp_arguments : slambda array;
}
and slambda_let = {
  1. slet_name : Slambdaident.t;
  2. slet_value : slambda;
  3. slet_body : slambda;
}
and rec_binding = {
  1. id : Ident.t;
  2. debug_uid : debug_uid;
  3. def : lfunction;
}
and lfunction = private {
  1. kind : function_kind;
  2. params : lparam list;
  3. return : layout;
  4. body : lambda;
  5. attr : function_attribute;
  6. loc : scoped_location;
  7. mode : locality_mode;
  8. ret_mode : 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;
  2. wh_body : lambda;
}
and lambda_for = {
  1. for_id : Ident.t;
  2. for_debug_uid : debug_uid;
  3. for_loc : scoped_location;
  4. for_from : lambda;
  5. for_to : lambda;
  6. for_dir : Asttypes.direction_flag;
  7. for_body : lambda;
}
and lambda_apply = {
  1. ap_func : lambda;
  2. ap_args : lambda list;
  3. ap_result_layout : layout;
  4. ap_region_close : region_close;
  5. ap_mode : locality_mode;
  6. ap_loc : scoped_location;
  7. ap_tailcall : tailcall_attribute;
  8. ap_inlined : inlined_attribute;
  9. ap_specialised : specialise_attribute;
  10. ap_probe : probe;
}
and lambda_switch = {
  1. sw_numconsts : int;
  2. sw_consts : (int * lambda) list;
  3. sw_numblocks : int;
  4. sw_blocks : (int * lambda) list;
  5. sw_failaction : lambda option;
}
and lambda_event = {
  1. lev_loc : scoped_location;
  2. lev_kind : lambda_event_kind;
  3. lev_repr : int 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
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 mixed_block_shape * mixed_block_shape_with_locality_mode
val module_representation_field_count : module_representation -> int
val layout_of_module_field : module_representation -> int -> layout
type main_module_block_format =
  1. | Mb_struct of {
    1. mb_repr : module_representation;
    }
  2. | Mb_instantiating_functor of {
    1. mb_runtime_params : runtime_param list;
    2. mb_returned_repr : module_representation;
    }
val main_module_representation : main_module_block_format -> module_representation
type program = {
  1. compilation_unit : Compilation_unit.t;
  2. main_module_block_format : main_module_block_format;
  3. arg_block_idx : int option;
  4. required_globals : Compilation_unit.Set.t;
  5. code : lambda;
}
type arg_descr = {
  1. arg_param : Global_module.Parameter_name.t;
  2. arg_block_idx : int;
  3. main_repr : module_representation;
}
val make_key : lambda -> lambda option
val const_unit : structured_constant
val const_int : int -> structured_constant
val const_unboxed_int64 : int64 -> structured_constant
val tagged_immediate : int -> lambda
val lambda_unit : lambda
val of_bool : bool -> lambda
val split_vectors : bool
val layout_unit : layout
val layout_unboxed_unit : layout
val layout_int : layout
val layout_array : array_kind -> layout
val layout_block : layout
val layout_list : layout
val layout_exception : layout
val layout_function : layout
val layout_object : layout
val layout_class : layout
val layout_module : layout
val layout_functor : layout
val layout_string : layout
val layout_boxed_float : boxed_float -> layout
val layout_unboxed_float : unboxed_float -> layout
val layout_boxed_int : boxed_integer -> layout
val layout_boxed_vector : boxed_vector -> layout
val layout_tupled_vector : boxed_vector -> layout
val layout_unboxed_vector : unboxed_vector -> layout
val layout_unboxed_tupled_vector : unboxed_vector -> layout
val layout_tuple_element : layout
val layout_variant_arg : layout
val layout_tmc_field : layout
val layout_optional_arg : layout
val layout_value_field : layout
val layout_predef_value : layout
val layout_lazy : layout
val layout_lazy_contents : layout
val layout_any_value : layout
val layout_letrec : layout
val layout_probe_arg : layout
val layout_unboxed_product : layout list -> layout
val layout_top : layout
val layout_bottom : layout
val mixed_block_element_for_module : unit mixed_block_element
val mixed_block_element_with_locality_mode_for_module : locality_mode mixed_block_element
val dummy_constant : lambda

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

val name_lambda : let_kind -> lambda -> layout -> (Ident.t -> lambda) -> lambda
val name_lambda_list : (lambda * layout) list -> (lambda list -> lambda) -> lambda
val lfunction : kind:function_kind -> params:lparam list -> return:layout -> body:lambda -> attr:function_attribute -> loc:scoped_location -> mode:locality_mode -> ret_mode:locality_mode -> lambda
val lfunction' : kind:function_kind -> params:lparam list -> return:layout -> body:lambda -> attr:function_attribute -> loc:scoped_location -> mode:locality_mode -> ret_mode:locality_mode -> lfunction
val iter_head_constructor : (lambda -> unit) -> 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.

Callers should note that you will need to handle stage specific constructors (Lsplice, etc) depending on what stage you are calling this from.

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

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

Callers should note that you will need to handle stage specific constructors (Lsplice, etc) depending on what stage you are calling this from.

val transl_prim : string -> string -> lambda

Translate a value from a persistent module. For instance:

  transl_internal_value "CamlinternalLazy" "force"
val free_variables : lambda -> Ident.Set.t
val transl_module_path : scoped_location -> Env.t -> Path.t -> lambda
val transl_value_path : scoped_location -> Env.t -> Path.t -> lambda
val transl_extension_path : scoped_location -> Env.t -> Path.t -> lambda
val transl_class_path : scoped_location -> Env.t -> Path.t -> lambda
val transl_address : scoped_location -> Persistent_env.address -> lambda
val value_kind_of_pointerness : immediate_or_pointer -> value_kind_non_null
val pointerness_of_separability : Jkind_axis.Separability.t -> immediate_or_pointer
val transl_mixed_product_shape : Types.mixed_product_shape -> mixed_block_shape
val block_shape_of_value_kinds : value_kind list option -> block_shape
val is_uniform_block_shape : block_shape -> bool
val mixed_block_of_block_shape : block_shape -> mixed_block_shape option
val transl_mixed_product_shape_for_read : get_value_kind:(int -> value_kind) -> get_mode:(int -> 'a) -> Types.mixed_product_shape -> 'a mixed_block_element array
val transl_module_representation : Types.module_representation -> module_representation
val make_sequence : ('a -> lambda) -> 'a list -> lambda
val subst : (Ident.t -> (Subst.Lazy.value_description * Mode.Value.l) -> Env.t -> Env.t) -> ?freshen_bound_variables:bool -> lambda Ident.Map.t -> 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.

val rename : Ident.t Ident.Map.t -> lambda -> lambda

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

val duplicate_function : lfunction -> lfunction

Duplicate a term, freshening all locally-bound identifiers.

val map : (lambda -> lambda) -> lambda -> lambda

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

val map_lfunction : (lambda -> lambda) -> lfunction -> lfunction

Apply the given transformation on the function's body

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

Rewrite each immediate sub-term with the function.

val bind_with_layout : let_kind -> (Ident.t * debug_uid * layout) -> lambda -> lambda -> lambda
val default_function_attribute : function_attribute
val default_stub_attribute : function_attribute
val default_param_attribute : parameter_attribute
val find_exact_application : function_kind -> arity:int -> lambda list -> 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 join_locality_mode : locality_mode -> locality_mode -> locality_mode
val sub_locality_mode : locality_mode -> locality_mode -> bool
val eq_locality_mode : locality_mode -> locality_mode -> bool
val is_local_mode : locality_mode -> bool
val is_heap_mode : locality_mode -> bool
val primitive_may_allocate : primitive -> 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 : external_call_description -> locality_mode option

Like primitive_may_allocate, for external calls.

val next_raise_count : unit -> static_label
val staticfail : lambda
val is_guarded : lambda -> bool
val patch_guarded : lambda -> lambda -> lambda
val raise_kind : raise_kind -> string
val merge_inline_attributes : inline_attribute -> inline_attribute -> inline_attribute option
val reset : unit -> unit
val mod_field : ?read_semantics:field_read_semantics -> int -> module_representation -> primitive

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 : structured_constant -> layout
val mixed_block_element_of_layout : layout -> 'a mixed_block_element
val project_from_mixed_block_shape : 'a mixed_block_element array -> path:int list -> 'a mixed_block_element

Returns the element at the given path in a mixed block shape. The path is a list of field indices for navigating into nested products.

val pointerness_of_scannable_with_externality : Jkind_axis.Externality.t -> immediate_or_pointer

Immediate if a type of scannable jkind is GC-ignorable based on its provided externality, and Pointer otherwise.

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

Whether there exists a non-value before a value

val primitive_result_layout : primitive -> layout
val array_ref_kind_result_layout : array_ref_kind -> layout
val array_ref_kind : locality_mode -> array_kind -> array_ref_kind

The mode will be discarded if unnecessary for the given array_kind

val array_set_kind : modify_mode -> array_kind -> array_set_kind

The mode will be discarded if unnecessary for the given array_kind

val array_ref_kind_of_array_set_kind : array_set_kind -> locality_mode -> 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 -> bool
val simple_prim_on_values : name:string -> arity:int -> alloc:bool -> external_call_description
val try_to_find_location : lambda -> scoped_location
val try_to_find_debuginfo : lambda -> Debuginfo.t
val primitive_can_raise : primitive -> bool
val count_initializers_array_kind : array_kind -> int
val ignorable_product_element_kind_involves_int : ignorable_product_element_kind -> bool
val array_element_size_in_bytes : array_kind -> int

This function currently assumes a 64-bit target.

Construction helpers

val array_index_to_layout : array_index_kind -> layout
val array_index_to_scalar : array_index_kind -> locality_mode Scalar.Integral.t
val const_scalar : locality_mode Scalar.Integral.t -> int -> lambda
val int : _ Scalar.Integral.t

A tagged immediate.

val phys_equal : lambda -> lambda -> loc:scoped_location -> lambda

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

type 'a unop := 'a -> lambda -> loc:scoped_location -> lambda
type 'a binop := 'a -> lambda -> lambda -> loc:scoped_location -> 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.

type error =
  1. | Slambda_unsupported of string
val error : ?loc:Location.t -> error -> 'a
val fatal_error_unevaluated_splice_var : Ident.t -> 'a
val fatal_error_invalid_constructor : lambda -> 'a