Module Flambda2_from_lambda.Lambda_to_flambda_env
module Region_stack_element : sig ... endval create :
current_unit:Compilation_unit.t ->
machine_width:Target_system.Machine_width.t ->
return_continuation:Flambda2_identifiers.Continuation.t ->
exn_continuation:Flambda2_identifiers.Continuation.t ->
my_region:
Flambda2_from_lambda.Lambda_to_flambda_env.Region_stack_element.t option ->
Flambda2_from_lambda.Lambda_to_flambda_env.tval current_unit :
Flambda2_from_lambda.Lambda_to_flambda_env.t ->
Compilation_unit.tval machine_width :
Flambda2_from_lambda.Lambda_to_flambda_env.t ->
Target_system.Machine_width.tval ident_stamp_upon_starting :
Flambda2_from_lambda.Lambda_to_flambda_env.t ->
intval is_mutable :
Flambda2_from_lambda.Lambda_to_flambda_env.t ->
Ident.t ->
boolval register_mutable_variable :
Flambda2_from_lambda.Lambda_to_flambda_env.t ->
Ident.t ->
before_unarization:
[ `Complex ] Flambda2_kinds.Flambda_arity.Component_for_creation.t ->
Flambda2_from_lambda.Lambda_to_flambda_env.t
* (Ident.t
* Flambda2_identifiers.Flambda_debug_uid.t
* Flambda2_kinds.Flambda_kind.With_subkind.full_kind)
listval update_mutable_variable :
Flambda2_from_lambda.Lambda_to_flambda_env.t ->
Ident.t ->
Flambda2_from_lambda.Lambda_to_flambda_env.tval register_unboxed_product :
Flambda2_from_lambda.Lambda_to_flambda_env.t ->
unboxed_product:Ident.t ->
before_unarization:
[ `Complex ] Flambda2_kinds.Flambda_arity.Component_for_creation.t ->
fields:(Ident.t * Flambda2_identifiers.Flambda_debug_uid.t) list ->
Flambda2_from_lambda.Lambda_to_flambda_env.tval register_unboxed_product_with_kinds :
Flambda2_from_lambda.Lambda_to_flambda_env.t ->
unboxed_product:Ident.t ->
before_unarization:
[ `Complex ] Flambda2_kinds.Flambda_arity.Component_for_creation.t ->
fields:
(Ident.t
* Flambda2_identifiers.Flambda_debug_uid.t
* Flambda2_kinds.Flambda_kind.With_subkind.t)
list ->
Flambda2_from_lambda.Lambda_to_flambda_env.tval get_unboxed_product_fields :
Flambda2_from_lambda.Lambda_to_flambda_env.t ->
Ident.t ->
([ `Complex ] Flambda2_kinds.Flambda_arity.Component_for_creation.t
* (Ident.t * Flambda2_identifiers.Flambda_debug_uid.t) list)
optiontype add_continuation_result = private {body_env : Flambda2_from_lambda.Lambda_to_flambda_env.t;handler_env : Flambda2_from_lambda.Lambda_to_flambda_env.t;extra_params : (Ident.t * Flambda2_identifiers.Flambda_debug_uid.t * Flambda2_kinds.Flambda_kind.With_subkind.t) list;
}val add_continuation :
Flambda2_from_lambda.Lambda_to_flambda_env.t ->
Flambda2_identifiers.Continuation.t ->
push_to_try_stack:bool ->
pop_region:bool ->
Asttypes.rec_flag ->
Flambda2_from_lambda.Lambda_to_flambda_env.add_continuation_resultval add_static_exn_continuation :
Flambda2_from_lambda.Lambda_to_flambda_env.t ->
Static_label.t ->
pop_region:bool ->
Flambda2_identifiers.Continuation.t ->
Flambda2_from_lambda.Lambda_to_flambda_env.add_continuation_resultval get_static_exn_continuation :
Flambda2_from_lambda.Lambda_to_flambda_env.t ->
Static_label.t ->
Flambda2_identifiers.Continuation.tval mark_as_recursive_static_catch :
Flambda2_from_lambda.Lambda_to_flambda_env.t ->
Static_label.t ->
Flambda2_from_lambda.Lambda_to_flambda_env.tval is_static_exn_recursive :
Flambda2_from_lambda.Lambda_to_flambda_env.t ->
Static_label.t ->
boolval get_try_stack :
Flambda2_from_lambda.Lambda_to_flambda_env.t ->
Flambda2_identifiers.Continuation.t listval get_try_stack_at_handler :
Flambda2_from_lambda.Lambda_to_flambda_env.t ->
Flambda2_identifiers.Continuation.t ->
Flambda2_identifiers.Continuation.t listval extra_args_for_continuation :
Flambda2_from_lambda.Lambda_to_flambda_env.t ->
Flambda2_identifiers.Continuation.t ->
Ident.t listval extra_args_for_continuation_with_kinds :
Flambda2_from_lambda.Lambda_to_flambda_env.t ->
Flambda2_identifiers.Continuation.t ->
(Ident.t
* Flambda2_identifiers.Flambda_debug_uid.t
* Flambda2_kinds.Flambda_kind.With_subkind.t)
listval get_mutable_variable_with_kinds :
Flambda2_from_lambda.Lambda_to_flambda_env.t ->
Ident.t ->
(Ident.t
* Flambda2_identifiers.Flambda_debug_uid.t
* Flambda2_kinds.Flambda_kind.With_subkind.t)
list
* [ `Complex ] Flambda2_kinds.Flambda_arity.Component_for_creation.tAbout local allocation regions:
In this pass, we have to transform Lregion expressions in Lambda to primitives that mark the opening and closing of stack regions. We need to ensure regions are always closed so as to not leak out of their scope. They must also never be closed twice.
Several nested regions can be closed with one primitive as End_region id which will close id and every other region opened in its scope. As such, the transformation doesn't need to generate strict pairings of Begin_region and End_region in every case. We may jump out of the scope of several regions at once, in particular with exception raises from Lstaticraise.
Another case requiring attention is function calls in tail position for which we may need to add an End_region before the jump.
This implementation works as follows.
For normal control flow, following the block structure of Lambda expressions, we insert a new continuation (called the "region closure continuation") upon encountering Begin_region; then at every leaf we cause the control flow to jump via that continuation. The region closure continuation closes the relevant region before jumping to what would have been the "real" continuation of the leaf expressions in question. The insertion of the continuation avoids duplication of the End_region constructs. (We only need one Begin_region per region, but potentially as many End_regions as there are leaves in the subsequent term.)
For exceptional control flow, the region closure continuation is not used; instead, a region is opened before the beginning of a Trywith, so that we can use this region to close every subsequent regions opened in its scope at the beginning of the handler.
Likewise, when regions must be closed explicitly prior to tail calls to avoid leaking memory on the local allocation stack, the closure continuation is also not used in favour of explicit insertion of End_region operations.
Region closure continuations are created alongside corresponding Begin_regions when translating Lregion expressions. The decision as to calling a closure continuation or adding explicit End_regions is done in restore_continuation_context and wrap_return_continuation. Exceptional control flow cases are handled by the compile_staticfail and Ltrywith cases of the main transformation functions.
Each Lregion actually turns into two Flambda regions: one used for stack allocation and one used for primitives that are constrained by locality (e.g. Int_as_pointer at local mode). The latter kinds of regions are known as ghost regions.
val entering_region :
Flambda2_from_lambda.Lambda_to_flambda_env.t ->
Flambda2_from_lambda.Lambda_to_flambda_env.Region_stack_element.t ->
continuation_closing_region:Flambda2_identifiers.Continuation.t ->
continuation_after_closing_region:Flambda2_identifiers.Continuation.t ->
Flambda2_from_lambda.Lambda_to_flambda_env.tval leaving_region :
Flambda2_from_lambda.Lambda_to_flambda_env.t ->
Flambda2_from_lambda.Lambda_to_flambda_env.tval my_region :
Flambda2_from_lambda.Lambda_to_flambda_env.t ->
Flambda2_from_lambda.Lambda_to_flambda_env.Region_stack_element.t optionThe region stack element corresponding to the my_region parameter of the current function, if relevant. The toplevel expression doesn't have such a variable, and functions that cannot allocate in the parent region may not have one either.
val current_region :
Flambda2_from_lambda.Lambda_to_flambda_env.t ->
Flambda2_from_lambda.Lambda_to_flambda_env.Region_stack_element.t optionThe current region stack element, to be used for allocation etc.
val parent_region :
Flambda2_from_lambda.Lambda_to_flambda_env.t ->
Flambda2_from_lambda.Lambda_to_flambda_env.Region_stack_element.t optionThe region stack element immediately outside current_region.
val region_stack :
Flambda2_from_lambda.Lambda_to_flambda_env.t ->
Flambda2_from_lambda.Lambda_to_flambda_env.Region_stack_element.t listThe innermost (newest) region is first in the list.
val region_stack_in_cont_scope :
Flambda2_from_lambda.Lambda_to_flambda_env.t ->
Flambda2_identifiers.Continuation.t ->
Flambda2_from_lambda.Lambda_to_flambda_env.Region_stack_element.t listval pop_region :
Flambda2_from_lambda.Lambda_to_flambda_env.Region_stack_element.t list ->
(Flambda2_from_lambda.Lambda_to_flambda_env.Region_stack_element.t
* Flambda2_from_lambda.Lambda_to_flambda_env.Region_stack_element.t list)
optionHack for staticfail (which should eventually use pop_regions_up_to_context)
val pop_regions_up_to_context :
Flambda2_from_lambda.Lambda_to_flambda_env.t ->
Flambda2_identifiers.Continuation.t ->
Flambda2_from_lambda.Lambda_to_flambda_env.Region_stack_element.t optiontype region_closure_continuation = private {continuation_closing_region : Flambda2_identifiers.Continuation.t;continuation_after_closing_region : Flambda2_identifiers.Continuation.t;
}