Module Lambda
module Scalar = Scalartype constant = Typedtree.constantval alloc_heap : Lambda.locality_modeval alloc_local : Lambda.locality_modeval modify_heap : Lambda.modify_modeval modify_maybe_stack : Lambda.modify_modetype initialization_or_assignment = | Assignment of Lambda.modify_mode| Heap_initialization| Root_initialization
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.)
module Phys_equal : sig ... endtype primitive = | Pbytes_to_string| Pbytes_of_string| Pignore| Pgetglobal of Compilation_unit.t| Pgetpredef of Ident.t| Pmakeblock of int * Lambda.mutable_flag * Lambda.block_shape * Lambda.locality_mode| Pmakefloatblock of Lambda.mutable_flag * Lambda.locality_mode| Pmakeufloatblock of Lambda.mutable_flag * Lambda.locality_mode| Pmakemixedblock of int * Lambda.mutable_flag * Lambda.mixed_block_shape * Lambda.locality_mode| Pmakelazyblock of Lambda.lazy_block_tag| Pfield of int * Lambda.immediate_or_pointer * Lambda.field_read_semantics| Pfield_computed of Lambda.field_read_semantics| Psetfield of int * Lambda.immediate_or_pointer * Lambda.initialization_or_assignment| Psetfield_computed of Lambda.immediate_or_pointer * Lambda.initialization_or_assignment| Pfloatfield of int * Lambda.field_read_semantics * Lambda.locality_mode| Pufloatfield of int * Lambda.field_read_semantics| Pmixedfield of int list * Lambda.mixed_block_shape_with_locality_mode * Lambda.field_read_semantics(*The index to
*)Pmixedfieldcorresponds 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.| Psetfloatfield of int * Lambda.initialization_or_assignment| Psetufloatfield of int * Lambda.initialization_or_assignment| Psetmixedfield of int list * Lambda.mixed_block_shape * Lambda.initialization_or_assignment(*The same comment about the index as for
*)Pmixedfieldapplies toPsetmixedfield.| Pduprecord of Types.record_representation * int| Pmake_unboxed_product of Lambda.layout list| Punboxed_product_field of int * Lambda.layout list| Parray_element_size_in_bytes of Lambda.array_kind| Pmake_idx_field of int| 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
*)| Pmake_idx_array of Lambda.array_kind * Lambda.array_index_kind * unit Lambda.mixed_block_element * int list| Pidx_deepen of unit Lambda.mixed_block_element * int list| Prunstack| Pperform| Presume| Preperform| Pccall of Lambda.external_call_description| Praise of Lambda.raise_kind| Psequand| Psequor| Pnot| 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.
*)| Pscalar of Lambda.locality_mode Scalar.Operation.t| Poffsetref of int| Pstringlength| Pstringrefu| Pstringrefs| Pbyteslength| Pbytesrefu| Pbytessetu| Pbytesrefs| Pbytessets| Pmakearray of Lambda.array_kind * Lambda.mutable_flag * Lambda.locality_mode| 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.| Pduparray of Lambda.array_kind * Lambda.mutable_flag(*For
*)Pduparray, the argument must be an immutable array. The arguments ofPduparraygive the kind and mutability of the array being *produced* by the duplication.| Parrayblit of {src_mutability : Lambda.mutable_flag;dst_array_set_kind : Lambda.array_set_kind;
}(*For
*)Parrayblit, we record thearray_set_kindof 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.| Parraylength of Lambda.array_kind| Parrayrefu of Lambda.array_ref_kind * Lambda.array_index_kind * Lambda.mutable_flag| Parraysetu of Lambda.array_set_kind * Lambda.array_index_kind| Parrayrefs of Lambda.array_ref_kind * Lambda.array_index_kind * Lambda.mutable_flag| Parraysets of Lambda.array_set_kind * Lambda.array_index_kind| Pisint of {}| Pisnull| Pisout| Pbigarrayref of bool * int * Lambda.bigarray_kind * Lambda.bigarray_layout| Pbigarrayset of bool * int * Lambda.bigarray_kind * Lambda.bigarray_layout| Pbigarraydim of int| Pstring_load_16 of {unsafe : bool;index_kind : Lambda.array_index_kind;
}| Pstring_load_32 of {unsafe : bool;index_kind : Lambda.array_index_kind;mode : Lambda.locality_mode;boxed : bool;
}| Pstring_load_f32 of {unsafe : bool;index_kind : Lambda.array_index_kind;mode : Lambda.locality_mode;boxed : bool;
}| Pstring_load_64 of {unsafe : bool;index_kind : Lambda.array_index_kind;mode : Lambda.locality_mode;boxed : bool;
}| Pstring_load_vec of {size : Lambda.boxed_vector;unsafe : bool;index_kind : Lambda.array_index_kind;mode : Lambda.locality_mode;boxed : bool;
}| Pbytes_load_16 of {unsafe : bool;index_kind : Lambda.array_index_kind;
}| Pbytes_load_32 of {unsafe : bool;index_kind : Lambda.array_index_kind;mode : Lambda.locality_mode;boxed : bool;
}| Pbytes_load_f32 of {unsafe : bool;index_kind : Lambda.array_index_kind;mode : Lambda.locality_mode;boxed : bool;
}| Pbytes_load_64 of {unsafe : bool;index_kind : Lambda.array_index_kind;mode : Lambda.locality_mode;boxed : bool;
}| Pbytes_load_vec of {size : Lambda.boxed_vector;unsafe : bool;index_kind : Lambda.array_index_kind;mode : Lambda.locality_mode;boxed : bool;
}| Pbytes_set_16 of {unsafe : bool;index_kind : Lambda.array_index_kind;
}| Pbytes_set_32 of {unsafe : bool;index_kind : Lambda.array_index_kind;boxed : bool;
}| Pbytes_set_f32 of {unsafe : bool;index_kind : Lambda.array_index_kind;boxed : bool;
}| Pbytes_set_64 of {unsafe : bool;index_kind : Lambda.array_index_kind;boxed : bool;
}| Pbytes_set_vec of {size : Lambda.boxed_vector;unsafe : bool;index_kind : Lambda.array_index_kind;boxed : bool;
}| Pbigstring_load_16 of {unsafe : bool;index_kind : Lambda.array_index_kind;
}| Pbigstring_load_32 of {unsafe : bool;index_kind : Lambda.array_index_kind;mode : Lambda.locality_mode;boxed : bool;
}| Pbigstring_load_f32 of {unsafe : bool;index_kind : Lambda.array_index_kind;mode : Lambda.locality_mode;boxed : bool;
}| Pbigstring_load_64 of {unsafe : bool;index_kind : Lambda.array_index_kind;mode : Lambda.locality_mode;boxed : bool;
}| Pbigstring_load_vec of {size : Lambda.boxed_vector;aligned : bool;unsafe : bool;index_kind : Lambda.array_index_kind;mode : Lambda.locality_mode;boxed : bool;
}| Pbigstring_set_16 of {unsafe : bool;index_kind : Lambda.array_index_kind;
}| Pbigstring_set_32 of {unsafe : bool;index_kind : Lambda.array_index_kind;boxed : bool;
}| Pbigstring_set_f32 of {unsafe : bool;index_kind : Lambda.array_index_kind;boxed : bool;
}| Pbigstring_set_64 of {unsafe : bool;index_kind : Lambda.array_index_kind;boxed : bool;
}| Pbigstring_set_vec of {size : Lambda.boxed_vector;aligned : bool;unsafe : bool;index_kind : Lambda.array_index_kind;boxed : bool;
}| Pfloatarray_load_vec of {size : Lambda.boxed_vector;unsafe : bool;index_kind : Lambda.array_index_kind;mode : Lambda.locality_mode;boxed : bool;
}| Pfloat_array_load_vec of {size : Lambda.boxed_vector;unsafe : bool;index_kind : Lambda.array_index_kind;mode : Lambda.locality_mode;boxed : bool;
}| Pint_array_load_vec of {size : Lambda.boxed_vector;unsafe : bool;index_kind : Lambda.array_index_kind;mode : Lambda.locality_mode;boxed : bool;
}| Punboxed_float_array_load_vec of {size : Lambda.boxed_vector;unsafe : bool;index_kind : Lambda.array_index_kind;mode : Lambda.locality_mode;boxed : bool;
}| Punboxed_float32_array_load_vec of {size : Lambda.boxed_vector;unsafe : bool;index_kind : Lambda.array_index_kind;mode : Lambda.locality_mode;boxed : bool;
}| Punboxed_int32_array_load_vec of {size : Lambda.boxed_vector;unsafe : bool;index_kind : Lambda.array_index_kind;mode : Lambda.locality_mode;boxed : bool;
}| Punboxed_int64_array_load_vec of {size : Lambda.boxed_vector;unsafe : bool;index_kind : Lambda.array_index_kind;mode : Lambda.locality_mode;boxed : bool;
}| Punboxed_nativeint_array_load_vec of {size : Lambda.boxed_vector;unsafe : bool;index_kind : Lambda.array_index_kind;mode : Lambda.locality_mode;boxed : bool;
}| Pfloatarray_set_vec of {size : Lambda.boxed_vector;unsafe : bool;index_kind : Lambda.array_index_kind;boxed : bool;
}| Pfloat_array_set_vec of {size : Lambda.boxed_vector;unsafe : bool;index_kind : Lambda.array_index_kind;boxed : bool;
}| Pint_array_set_vec of {size : Lambda.boxed_vector;unsafe : bool;index_kind : Lambda.array_index_kind;boxed : bool;
}| Punboxed_float_array_set_vec of {size : Lambda.boxed_vector;unsafe : bool;index_kind : Lambda.array_index_kind;boxed : bool;
}| Punboxed_float32_array_set_vec of {size : Lambda.boxed_vector;unsafe : bool;index_kind : Lambda.array_index_kind;boxed : bool;
}| Punboxed_int32_array_set_vec of {size : Lambda.boxed_vector;unsafe : bool;index_kind : Lambda.array_index_kind;boxed : bool;
}| Punboxed_int64_array_set_vec of {size : Lambda.boxed_vector;unsafe : bool;index_kind : Lambda.array_index_kind;boxed : bool;
}| Punboxed_nativeint_array_set_vec of {size : Lambda.boxed_vector;unsafe : bool;index_kind : Lambda.array_index_kind;boxed : bool;
}| Pctconst of Lambda.compile_time_constant| Pint_as_pointer of Lambda.locality_mode| Patomic_load_field of {immediate_or_pointer : Lambda.immediate_or_pointer;
}| Patomic_set_field of {immediate_or_pointer : Lambda.immediate_or_pointer;
}| Patomic_exchange_field of {immediate_or_pointer : Lambda.immediate_or_pointer;
}| Patomic_compare_exchange_field of {immediate_or_pointer : Lambda.immediate_or_pointer;
}| Patomic_compare_set_field of {immediate_or_pointer : Lambda.immediate_or_pointer;
}| Patomic_fetch_add_field| Patomic_add_field| Patomic_sub_field| Patomic_land_field| Patomic_lor_field| Patomic_lxor_field| Popaque of Lambda.layout| Pprobe_is_enabled of {}| Pobj_dup| Pobj_magic of Lambda.layout| Punbox_unit| Punbox_vector of Lambda.boxed_vector| Pbox_vector of Lambda.boxed_vector * Lambda.locality_mode| Preinterpret_unboxed_int64_as_tagged_int63| Preinterpret_tagged_int63_as_unboxed_int64(*At present
Preinterpret_unboxed_int64_as_tagged_int63andPreinterpret_tagged_int63_as_unboxed_int64will cause a fatal error if the target system is 32-bit bytecode.The
*)Preinterpret_tagged_int63_as_unboxed_int64primitive is the identity on machine words. ThePreinterpret_unboxed_int64_as_tagged_int63compiles 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.| Parray_to_iarray| Parray_of_iarray| Pget_header of Lambda.locality_mode| Ppeek of Lambda.peek_or_poke| Ppoke of Lambda.peek_or_poke| Pdls_get| Ptls_get| Ppoll| Pcpu_relax| Pget_idx of Lambda.layout * Asttypes.mutable_flag| Pset_idx of Lambda.layout * Lambda.modify_mode| Pget_ptr of Lambda.layout * Asttypes.mutable_flag| Pset_ptr of Lambda.layout * Lambda.modify_mode
and extern_repr = | Same_as_ocaml_repr of Jkind.Sort.Const.t| Unboxed_float of Lambda.boxed_float| Unboxed_vector of Lambda.boxed_vector| 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_genand array_kind = | Pgenarray| Paddrarray| Pgcignorableaddrarray| Pintarray| Pfloatarray| Punboxedfloatarray of Lambda.unboxed_float| Punboxedoruntaggedintarray of Lambda.unboxed_or_untagged_integer| Punboxedvectorarray of Lambda.unboxed_vector| Pgcscannableproductarray of Lambda.scannable_product_element_kind list| Pgcignorableproductarray of Lambda.ignorable_product_element_kind list
and array_ref_kind = | Pgenarray_ref of Lambda.locality_mode| Paddrarray_ref| Pgcignorableaddrarray_ref| Pintarray_ref| Pfloatarray_ref of Lambda.locality_mode| Punboxedfloatarray_ref of Lambda.unboxed_float| Punboxedoruntaggedintarray_ref of Lambda.unboxed_or_untagged_integer| Punboxedvectorarray_ref of Lambda.unboxed_vector| Pgcscannableproductarray_ref of Lambda.scannable_product_element_kind list| 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 = | Pgenarray_set of Lambda.modify_mode| Paddrarray_set of Lambda.modify_mode| Pgcignorableaddrarray_set| Pintarray_set| Pfloatarray_set| Punboxedfloatarray_set of Lambda.unboxed_float| Punboxedoruntaggedintarray_set of Lambda.unboxed_or_untagged_integer| Punboxedvectorarray_set of Lambda.unboxed_vector| Pgcscannableproductarray_set of Lambda.modify_mode * Lambda.scannable_product_element_kind list| 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 = | Pint_ignorable| Punboxedfloat_ignorable of Lambda.unboxed_float| Punboxedoruntaggedint_ignorable of Lambda.unboxed_or_untagged_integer| Pproduct_ignorable of Lambda.ignorable_product_element_kind list
and scannable_product_element_kind = | Pint_scannable| Paddr_scannable| Pproduct_scannable of Lambda.scannable_product_element_kind list
and array_index_kind = | Ptagged_int_index| Punboxed_or_untagged_integer_index of Lambda.unboxed_or_untagged_integer
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_non_null = | Pgenval| Pintval| Pboxedfloatval of Lambda.boxed_float| Pboxedintval of Lambda.boxed_integer| Pvariant of {consts : int list;non_consts : (int * Lambda.constructor_shape) list;(*
*)non_constsmust be non-empty. For constant variantsPintvalmust be used. This causes a small loss of precision but it is not expected to be significant.
}| Parrayval of Lambda.array_kind| Pboxedvectorval of Lambda.boxed_vector
and layout = | Ptop| Pvalue of Lambda.value_kind| Punboxed_float of Lambda.unboxed_float| Punboxed_or_untagged_integer of Lambda.unboxed_or_untagged_integer| Punboxed_vector of Lambda.unboxed_vector| Punboxed_product of Lambda.layout list| Pbottom| Psplicevar of Ident.t
and block_shape = Lambda.value_kind list optionand 'a mixed_block_element = | Value of Lambda.value_kind| Float_boxed of 'a| Float64| Float32| Bits8| Bits16| Bits32| Bits64| Vec128| Vec256| Vec512| Word| Untagged_immediate| Product of 'a Lambda.mixed_block_element array| Splice_variable of Ident.t
and mixed_block_shape = unit Lambda.mixed_block_element arrayand mixed_block_shape_with_locality_mode =
Lambda.locality_mode Lambda.mixed_block_element arrayand constructor_shape = | Constructor_uniform of Lambda.value_kind list| Constructor_mixed of Lambda.mixed_block_shape
and unboxed_or_untagged_integer = Primitive.unboxed_or_untagged_integer = val equal_value_kind : Lambda.value_kind -> Lambda.value_kind -> boolval equal_layout : Lambda.layout -> Lambda.layout -> boolval print_boxed_vector : Stdlib.Format.formatter -> Lambda.boxed_vector -> unitval equal_ignorable_product_element_kind :
Lambda.ignorable_product_element_kind ->
Lambda.ignorable_product_element_kind ->
boolval must_be_value : Lambda.layout -> Lambda.value_kindval generic_value : Lambda.value_kindval layout_of_extern_repr : Lambda.extern_repr -> Lambda.layoutval extern_repr_involves_unboxed_products : Lambda.extern_repr -> booltype structured_constant = | Const_base of Lambda.constant| Const_block of int * Lambda.structured_constant list| Const_mixed_block of int * Lambda.mixed_block_shape * Lambda.structured_constant list| Const_float_array of string list| Const_immstring of string| Const_float_block of string list| Const_null
val equal_inline_attribute :
Lambda.inline_attribute ->
Lambda.inline_attribute ->
boolval equal_inlined_attribute :
Lambda.inlined_attribute ->
Lambda.inlined_attribute ->
booltype probe = Lambda.probe_desc optionval equal_specialise_attribute :
Lambda.specialise_attribute ->
Lambda.specialise_attribute ->
booltype zero_alloc_attribute = | Default_zero_alloc| Check of {strict : bool;loc : Location.t;custom_error_msg : string option;
}| Assume of {strict : bool;never_returns_normally : bool;never_raises : bool;loc : Location.t;
}
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
.
val add_barrier_to_read :
Lambda.unique_barrier ->
Lambda.field_read_semantics ->
Lambda.field_read_semanticsval add_barrier_to_let_kind :
Lambda.unique_barrier ->
Lambda.let_kind ->
Lambda.let_kindval equal_meth_kind : Lambda.meth_kind -> Lambda.meth_kind -> booltype static_label = Static_label.ttype function_attribute = {inline : Lambda.inline_attribute;specialise : Lambda.specialise_attribute;local : Lambda.local_attribute;zero_alloc : Lambda.zero_alloc_attribute;poll : Lambda.poll_attribute;loop : Lambda.loop_attribute;regalloc : Lambda.regalloc_attribute;regalloc_param : Lambda.regalloc_param_attribute;cold : bool;is_a_functor : bool;is_opaque : bool;stub : bool;tmc_candidate : bool;may_fuse_arity : bool;unbox_return : bool;
}type debug_uid = Shape.Uid.tThe 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_uiddebug_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 = {name : Ident.t;debug_uid : Lambda.debug_uid;layout : Lambda.layout;attributes : Lambda.parameter_attribute;mode : Lambda.locality_mode;
}type scoped_location = Debuginfo.Scoped_location.ttype lambda = | Lvar of Ident.t| Lmutvar of Ident.t| Lconst of Lambda.structured_constant| Lapply of Lambda.lambda_apply| Lfunction of Lambda.lfunction| Llet of Lambda.let_kind * Lambda.layout * Ident.t * Lambda.debug_uid * Lambda.lambda * Lambda.lambda| Lmutlet of Lambda.layout * Ident.t * Lambda.debug_uid * Lambda.lambda * Lambda.lambda| Lletrec of Lambda.rec_binding list * Lambda.lambda| Lprim of Lambda.primitive * Lambda.lambda list * Lambda.scoped_location| Lswitch of Lambda.lambda * Lambda.lambda_switch * Lambda.scoped_location * Lambda.layout| Lstringswitch of Lambda.lambda * (string * Lambda.lambda) list * Lambda.lambda option * Lambda.scoped_location * Lambda.layout| Lstaticraise of Lambda.static_label * Lambda.lambda list| Lstaticcatch of Lambda.lambda * Lambda.static_label * (Ident.t * Lambda.debug_uid * Lambda.layout) list * Lambda.lambda * Lambda.pop_region * Lambda.layout| Ltrywith of Lambda.lambda * Ident.t * Lambda.debug_uid * Lambda.lambda * Lambda.layout| Lifthenelse of Lambda.lambda * Lambda.lambda * Lambda.lambda * Lambda.layout| Lsequence of Lambda.lambda * Lambda.lambda| Lwhile of Lambda.lambda_while| Lfor of Lambda.lambda_for| Lassign of Ident.t * Lambda.lambda| Lsend of Lambda.meth_kind * Lambda.lambda * Lambda.lambda * Lambda.lambda list * Lambda.region_close * Lambda.locality_mode * Lambda.scoped_location * Lambda.layout| Levent of Lambda.lambda * Lambda.lambda_event| Lifused of Ident.t * Lambda.lambda| Lregion of Lambda.lambda * Lambda.layout| Lexclave of Lambda.lambda| Lsplice of Lambda.lambda_splice
and slambda = Lambda.lambda Slambda0.t0and lfunction = private {kind : Lambda.function_kind;params : Lambda.lparam list;return : Lambda.layout;body : Lambda.lambda;attr : Lambda.function_attribute;loc : Lambda.scoped_location;mode : Lambda.locality_mode;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_for = {for_id : Ident.t;for_debug_uid : Lambda.debug_uid;for_loc : Lambda.scoped_location;for_from : Lambda.lambda;for_to : Lambda.lambda;for_dir : Asttypes.direction_flag;for_body : Lambda.lambda;
}and lambda_apply = {ap_func : Lambda.lambda;ap_args : Lambda.lambda list;ap_result_layout : Lambda.layout;ap_region_close : Lambda.region_close;ap_mode : Lambda.locality_mode;ap_loc : Lambda.scoped_location;ap_tailcall : Lambda.tailcall_attribute;ap_inlined : Lambda.inlined_attribute;ap_specialised : Lambda.specialise_attribute;ap_probe : Lambda.probe;
}and lambda_switch = {sw_numconsts : int;sw_consts : (int * Lambda.lambda) list;sw_numblocks : int;sw_blocks : (int * Lambda.lambda) list;sw_failaction : Lambda.lambda option;
}and lambda_event = {lev_loc : Lambda.scoped_location;lev_kind : Lambda.lambda_event_kind;lev_repr : int Stdlib.ref option;lev_env : Env.t;
}type runtime_param = | Rp_argument_block of Global_module.t| Rp_main_module_block of Global_module.t| Rp_unit
type module_representation = | Module_value_only of {}| Module_mixed of Lambda.mixed_block_shape * Lambda.mixed_block_shape_with_locality_mode
val module_representation_field_count : Lambda.module_representation -> intval layout_of_module_field :
Lambda.module_representation ->
int ->
Lambda.layouttype main_module_block_format = | Mb_struct of {mb_repr : Lambda.module_representation;
}| Mb_instantiating_functor of {mb_runtime_params : Lambda.runtime_param list;mb_returned_repr : Lambda.module_representation;
}
val main_module_representation :
Lambda.main_module_block_format ->
Lambda.module_representationtype program = {compilation_unit : Compilation_unit.t;main_module_block_format : Lambda.main_module_block_format;arg_block_idx : int option;required_globals : Compilation_unit.Set.t;code : Lambda.lambda;
}type arg_descr = {arg_param : Global_module.Parameter_name.t;arg_block_idx : int;main_repr : Lambda.module_representation;
}val make_key : Lambda.lambda -> Lambda.lambda optionval const_unit : Lambda.structured_constantval const_int : int -> Lambda.structured_constantval tagged_immediate : int -> Lambda.lambdaval lambda_unit : Lambda.lambdaval of_bool : bool -> Lambda.lambdaval layout_unit : Lambda.layoutval layout_unboxed_unit : Lambda.layoutval layout_int : Lambda.layoutval layout_array : Lambda.array_kind -> Lambda.layoutval layout_block : Lambda.layoutval layout_list : Lambda.layoutval layout_exception : Lambda.layoutval layout_function : Lambda.layoutval layout_object : Lambda.layoutval layout_class : Lambda.layoutval layout_module : Lambda.layoutval layout_functor : Lambda.layoutval layout_string : Lambda.layoutval layout_boxed_float : Lambda.boxed_float -> Lambda.layoutval layout_unboxed_float : Lambda.unboxed_float -> Lambda.layoutval layout_boxed_int : Lambda.boxed_integer -> Lambda.layoutval layout_boxed_vector : Lambda.boxed_vector -> Lambda.layoutval layout_tuple_element : Lambda.layoutval layout_variant_arg : Lambda.layoutval layout_tmc_field : Lambda.layoutval layout_optional_arg : Lambda.layoutval layout_value_field : Lambda.layoutval layout_predef_value : Lambda.layoutval layout_lazy : Lambda.layoutval layout_lazy_contents : Lambda.layoutval layout_any_value : Lambda.layoutval layout_letrec : Lambda.layoutval layout_probe_arg : Lambda.layoutval layout_unboxed_product : Lambda.layout list -> Lambda.layoutval layout_top : Lambda.layoutval layout_bottom : Lambda.layoutval mixed_block_element_for_module : unit Lambda.mixed_block_elementval mixed_block_element_with_locality_mode_for_module :
Lambda.locality_mode Lambda.mixed_block_elementval dummy_constant : Lambda.lambdadummy_constant produces a placeholder value with a recognizable bit pattern (currently 0xBBBB in its tagged form)
val name_lambda :
Lambda.let_kind ->
Lambda.lambda ->
Lambda.layout ->
(Ident.t -> Lambda.lambda) ->
Lambda.lambdaval name_lambda_list :
(Lambda.lambda * Lambda.layout) list ->
(Lambda.lambda list -> Lambda.lambda) ->
Lambda.lambdaval lfunction :
kind:Lambda.function_kind ->
params:Lambda.lparam list ->
return:Lambda.layout ->
body:Lambda.lambda ->
attr:Lambda.function_attribute ->
loc:Lambda.scoped_location ->
mode:Lambda.locality_mode ->
ret_mode:Lambda.locality_mode ->
Lambda.lambdaval lfunction' :
kind:Lambda.function_kind ->
params:Lambda.lparam list ->
return:Lambda.layout ->
body:Lambda.lambda ->
attr:Lambda.function_attribute ->
loc:Lambda.scoped_location ->
mode:Lambda.locality_mode ->
ret_mode:Lambda.locality_mode ->
Lambda.lfunctionval iter_head_constructor : (Lambda.lambda -> unit) -> Lambda.lambda -> unititer_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 ->
unitSame 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.lambdaTranslate a value from a persistent module. For instance:
transl_internal_value "CamlinternalLazy" "force"val free_variables : Lambda.lambda -> Ident.Set.tval transl_module_path :
Lambda.scoped_location ->
Env.t ->
Path.t ->
Lambda.lambdaval transl_value_path :
Lambda.scoped_location ->
Env.t ->
Path.t ->
Lambda.lambdaval transl_extension_path :
Lambda.scoped_location ->
Env.t ->
Path.t ->
Lambda.lambdaval transl_class_path :
Lambda.scoped_location ->
Env.t ->
Path.t ->
Lambda.lambdaval transl_address :
Lambda.scoped_location ->
Persistent_env.address ->
Lambda.lambdaval transl_mixed_product_shape :
Types.mixed_product_shape ->
Lambda.mixed_block_shapeval 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 arrayval transl_module_representation :
Types.module_representation ->
Lambda.module_representationval block_of_module_representation :
loc:Warnings.loc ->
Lambda.module_representation ->
Lambda.primitiveval make_sequence : ('a -> Lambda.lambda) -> 'a list -> Lambda.lambdaval 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.lambdasubst 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 -> Lambda.lambdaA version of subst specialized for the case where we're just renaming idents.
val duplicate_function : Lambda.lfunction -> Lambda.lfunctionDuplicate a term, freshening all locally-bound identifiers.
val map : (Lambda.lambda -> Lambda.lambda) -> Lambda.lambda -> Lambda.lambdaBottom-up rewriting, applying the function on each node from the leaves to the root.
val map_lfunction :
(Lambda.lambda -> Lambda.lambda) ->
Lambda.lfunction ->
Lambda.lfunctionApply 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.lambdaRewrite each immediate sub-term with the function.
val bind_with_layout :
Lambda.let_kind ->
(Ident.t * Lambda.debug_uid * Lambda.layout) ->
Lambda.lambda ->
Lambda.lambda ->
Lambda.lambdaval default_function_attribute : Lambda.function_attributeval default_stub_attribute : Lambda.function_attributeval default_param_attribute : Lambda.parameter_attributeval find_exact_application :
Lambda.function_kind ->
arity:int ->
Lambda.lambda list ->
Lambda.lambda list optionMaximal 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 :
Lambda.locality_mode ->
Lambda.locality_mode ->
Lambda.locality_modeval sub_locality_mode : Lambda.locality_mode -> Lambda.locality_mode -> boolval eq_locality_mode : Lambda.locality_mode -> Lambda.locality_mode -> boolval is_local_mode : Lambda.locality_mode -> boolval is_heap_mode : Lambda.locality_mode -> boolval primitive_may_allocate : Lambda.primitive -> Lambda.locality_mode optionWhether 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 optionLike primitive_may_allocate, for external calls.
val next_raise_count : unit -> Lambda.static_labelval staticfail : Lambda.lambdaval is_guarded : Lambda.lambda -> boolval patch_guarded : Lambda.lambda -> Lambda.lambda -> Lambda.lambdaval raise_kind : Lambda.raise_kind -> stringval merge_inline_attributes :
Lambda.inline_attribute ->
Lambda.inline_attribute ->
Lambda.inline_attribute optionval mod_field :
?read_semantics:Lambda.field_read_semantics ->
int ->
Lambda.module_representation ->
Lambda.primitiveHelpers 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.layoutval mixed_block_element_of_layout :
Lambda.layout ->
unit Lambda.mixed_block_elementval value_kind_of_value_with_externality :
Jkind_axis.Externality.t ->
Lambda.value_kind_non_nullPintval 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.layoutval mixed_block_element_leaves :
'a Lambda.mixed_block_element ->
'a Lambda.mixed_block_element listval will_be_reordered : _ Lambda.mixed_block_element -> boolWhether there exists a non-value before a value
val primitive_result_layout : Lambda.primitive -> Lambda.layoutval array_ref_kind_result_layout : Lambda.array_ref_kind -> Lambda.layoutval array_ref_kind :
Lambda.locality_mode ->
Lambda.array_kind ->
Lambda.array_ref_kindThe mode will be discarded if unnecessary for the given array_kind
val array_set_kind :
Lambda.modify_mode ->
Lambda.array_kind ->
Lambda.array_set_kindThe 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_kindAny 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 -> boolval simple_prim_on_values :
name:string ->
arity:int ->
alloc:bool ->
Lambda.external_call_descriptionval try_to_find_location : Lambda.lambda -> Lambda.scoped_locationval try_to_find_debuginfo : Lambda.lambda -> Debuginfo.tval primitive_can_raise : Lambda.primitive -> boolval count_initializers_array_kind : Lambda.array_kind -> intval ignorable_product_element_kind_involves_int :
Lambda.ignorable_product_element_kind ->
boolval array_element_size_in_bytes : Lambda.array_kind -> intThis function currently assumes a 64-bit target.
Construction helpers
val int : _ Scalar.Integral.tA tagged immediate.
val phys_equal :
Lambda.lambda ->
Lambda.lambda ->
loc:Lambda.scoped_location ->
Lambda.lambdaSee 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.lambdaval succ : Lambda.locality_mode Scalar.Integral.t Lambda.unopval pred : Lambda.locality_mode Scalar.Integral.t Lambda.unoptype 'a binop :=
'a ->
Lambda.lambda ->
Lambda.lambda ->
loc:Lambda.scoped_location ->
Lambda.lambdaval and_ : Lambda.locality_mode Scalar.Integral.t Lambda.binopThis 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.
val static_cast :
src:Lambda.any_locality_mode Scalar.t ->
dst:Lambda.locality_mode Scalar.t ->
Lambda.lambda ->
loc:Lambda.scoped_location ->
Lambda.lambda