Module Flambda2_to_cmm.To_cmm_env
Translation environment
type free_vars = Backend_var.Set.tFree names for cmm expressions
module Symbol_inits : sig ... endDelayed symbol initializations
type expr_with_info = {cmm : Cmm.expression;effs : Flambda2_terms.Effects_and_coeffects.t;free_vars : Flambda2_to_cmm.To_cmm_env.free_vars;
}A cmm expression along with extra information
type translation_result = {env : Flambda2_to_cmm.To_cmm_env.t;res : Flambda2_to_cmm.To_cmm_result.t;expr : Flambda2_to_cmm.To_cmm_env.expr_with_info;
}val print : Stdlib.Format.formatter -> Flambda2_to_cmm.To_cmm_env.t -> unitPrinting function
type extra_info = | Untag of Cmm.expression(*The variable is bound to the result of untagging the given Cmm expression. This allows to obtain the Cmm expression as it was before untagging.
*)
Extra information about bound variables, used for optimisation.
type prim_res =
Flambda2_to_cmm.To_cmm_env.extra_info option
* Flambda2_to_cmm.To_cmm_result.t
* Cmm.expressionRecord of all primitive translation functions, to avoid a cyclic dependency.
type ('env, 'prim, 'arity) prim_helper =
'env ->
Flambda2_to_cmm.To_cmm_result.t ->
Debuginfo.t ->
'prim ->
'aritytype 'env trans_prim = {nullary : ('env, Flambda2_terms.Flambda_primitive.nullary_primitive, Flambda2_to_cmm.To_cmm_env.prim_res) Flambda2_to_cmm.To_cmm_env.prim_helper;unary : ('env, Flambda2_terms.Flambda_primitive.unary_primitive, Cmm.expression -> Flambda2_to_cmm.To_cmm_env.prim_res) Flambda2_to_cmm.To_cmm_env.prim_helper;binary : ('env, Flambda2_terms.Flambda_primitive.binary_primitive, Cmm.expression -> Cmm.expression -> Flambda2_to_cmm.To_cmm_env.prim_res) Flambda2_to_cmm.To_cmm_env.prim_helper;ternary : ('env, Flambda2_terms.Flambda_primitive.ternary_primitive, Cmm.expression -> Cmm.expression -> Cmm.expression -> Flambda2_to_cmm.To_cmm_env.prim_res) Flambda2_to_cmm.To_cmm_env.prim_helper;quaternary : ('env, Flambda2_terms.Flambda_primitive.quaternary_primitive, Cmm.expression -> Cmm.expression -> Cmm.expression -> Cmm.expression -> Flambda2_to_cmm.To_cmm_env.prim_res) Flambda2_to_cmm.To_cmm_env.prim_helper;variadic : ('env, Flambda2_terms.Flambda_primitive.variadic_primitive, Cmm.expression list -> Flambda2_to_cmm.To_cmm_env.prim_res) Flambda2_to_cmm.To_cmm_env.prim_helper;
}val create :
Flambda2_simplify_shared.Exported_offsets.t ->
Flambda2_cmx.Exported_code.t ->
trans_prim:Flambda2_to_cmm.To_cmm_env.t Flambda2_to_cmm.To_cmm_env.trans_prim ->
return_continuation:Flambda2_identifiers.Continuation.t ->
return_continuation_arity:Cmm.machtype list ->
exn_continuation:Flambda2_identifiers.Continuation.t ->
Flambda2_to_cmm.To_cmm_env.tCreate an environment for translating a toplevel expression.
val enter_function_body :
Flambda2_to_cmm.To_cmm_env.t ->
return_continuation:Flambda2_identifiers.Continuation.t ->
return_continuation_arity:Cmm.machtype list ->
exn_continuation:Flambda2_identifiers.Continuation.t ->
Flambda2_to_cmm.To_cmm_env.tGiven an existing environment providing the "global" information (such as the exported code structure), create an environment for translating the body of a function.
Debuginfo
val add_inlined_debuginfo :
Flambda2_to_cmm.To_cmm_env.t ->
Debuginfo.t ->
Debuginfo.tAdd the inlined debuginfo from the env to the debuginfo provided, in order to get the correct debuginfo to attach.
val enter_inlined_apply :
Flambda2_to_cmm.To_cmm_env.t ->
Flambda2_term_basics.Inlined_debuginfo.t ->
Flambda2_to_cmm.To_cmm_env.tAdjust the inlined debuginfo in the env to represent the fact that we entered the inlined body of a function.
val set_inlined_debuginfo :
Flambda2_to_cmm.To_cmm_env.t ->
Flambda2_term_basics.Inlined_debuginfo.t ->
Flambda2_to_cmm.To_cmm_env.tSet the inlined debuginfo.
val currently_in_inlined_body : Flambda2_to_cmm.To_cmm_env.t -> boolContinuations
val exn_continuation :
Flambda2_to_cmm.To_cmm_env.t ->
Flambda2_identifiers.Continuation.tReturns the exception continuation of the environment.
Code and closures
val get_code_metadata :
Flambda2_to_cmm.To_cmm_env.t ->
Flambda2_identifiers.Code_id.t ->
Flambda2_terms.Code_metadata.tRetrieve the code metadata for a given code ID. This function will produce fatal error if the code ID was not in the Exported_code.t passed to create.
val exported_offsets :
Flambda2_to_cmm.To_cmm_env.t ->
Flambda2_simplify_shared.Exported_offsets.tRetrieve the closure offset information as passed to create. This can be used for things such as the compilation of function and value slot projections.
Variable bindings
val create_bound_parameter :
Flambda2_to_cmm.To_cmm_env.t ->
(Flambda2_identifiers.Variable.t * Flambda2_identifiers.Flambda_debug_uid.t) ->
Flambda2_to_cmm.To_cmm_env.t * Backend_var.With_provenance.tCreate (and bind) a Cmm variable for the given Flambda variable, returning the new environment and the created variable. Will produce a fatal error if the given variable is already bound.
val create_bound_parameters :
Flambda2_to_cmm.To_cmm_env.t ->
(Flambda2_identifiers.Variable.t * Flambda2_identifiers.Flambda_debug_uid.t)
list ->
Flambda2_to_cmm.To_cmm_env.t * Backend_var.With_provenance.t listSame as create_variable but for a list of variables.
Delayed let-bindings
Let-bindings are delayed in a certain way to allow for potential reordering and inlining of the defining expressions of bound variables that are used exactly once. This behaviour (which are a more powerful version of the Un_anf pass from Flambda 1) does not change semantics. However they allow the Cmm code to adopt the forms expected by the Cmm optimisation functions (in Cmm_helpers, for example the arithmetic optimisations) and the instruction selection pass (for example where matches may be done on function applications and their arguments). Without this, many pattern matches on the Cmm terms would fail, leading to poor code generation.
The delaying process works by partitioning let-bindings into two categories according to the effects and coeffects of their defining expressions:
- bindings whose defining expressions are _pure_, that is to say have neither effects nor coeffects;
- bindings that have effects and/or coeffects.
Bindings in the first category, by virtue of the absence of effects and coeffects, will be allowed to commute with any other bindings.
The second category of bindings is organised into an ordered list of _stages_. A stage is a set of bindings that can all commute with each other. Bindings inside stages cannot commute across stages; and stages cannot commute.
One stage consists of either:
- an ordered list of bindings all of which have only coeffects; or
- a single effectful binding.
When a binding is considered for addition to the most recent stage, it may either be appended to that stage, or else the stage is "archived" and a new stage started containing the new binding.
The defining expression of a binding used exactly once may be inlined only if the binding occurs in the current stage or is pure. Inlining of a binding causes it to be removed from its stage (empty stages are then removed from the head of the list of stages).
Other bindings are delayed until they are explicitly flushed. Exactly which bindings get flushed at different points, for example prior to function calls or branching control flow, depends on decisions outside of this module (e.g. in To_cmm_expr).
Additionally, bindings that must be inlined must be treated with special care. Most notably, most of the time, we are in the case of a binding "let x = prim(args)" where the primitive 'prim' is marked as `Delay`, which we translate as Must_inline. In such cases, we want to inline the primitive itself, but not necessarily its arguments. To correctly handle such cases, we have a notion of "complex" bound argument that, in addition to a cmm expression, also contains the arguments and a way to re-build the expression.
type _ inline = | Do_not_inline : Flambda2_to_cmm.To_cmm_env.simple Flambda2_to_cmm.To_cmm_env.inline| May_inline_once : Flambda2_to_cmm.To_cmm_env.simple Flambda2_to_cmm.To_cmm_env.inline| Must_inline_once : Flambda2_to_cmm.To_cmm_env.complex Flambda2_to_cmm.To_cmm_env.inline| Must_inline_and_duplicate : Flambda2_to_cmm.To_cmm_env.complex Flambda2_to_cmm.To_cmm_env.inline(*Akin to systematic substitutions, it should not be used for (co)effectful expressions
*)
Inlining decision of bound expressions
val simple :
Cmm.expression ->
Flambda2_to_cmm.To_cmm_env.free_vars ->
Flambda2_to_cmm.To_cmm_env.simple Flambda2_to_cmm.To_cmm_env.bound_exprA simple cmm bound expression
val splittable_primitive :
Debuginfo.t ->
Flambda2_terms.Flambda_primitive.Without_args.t ->
Flambda2_to_cmm.To_cmm_env.expr_with_info list ->
Flambda2_to_cmm.To_cmm_env.complex Flambda2_to_cmm.To_cmm_env.bound_exprA bound expr that can be split if needed. This is used for primitives that must be inlined, but whose arguments may not be inlinable or duplicable, so that we can split the expression to be inlined from its arguments if/when needed. The effects that are passed must correspond respectively to each individual argument and to the primitive itself.
val bind_variable_to_primitive :
?extra:Flambda2_to_cmm.To_cmm_env.extra_info ->
Flambda2_to_cmm.To_cmm_env.t ->
Flambda2_to_cmm.To_cmm_result.t ->
Flambda2_bound_identifiers.Bound_var.t ->
inline:'a Flambda2_to_cmm.To_cmm_env.inline ->
defining_expr:'a Flambda2_to_cmm.To_cmm_env.bound_expr ->
effects_and_coeffects_of_defining_expr:Flambda2_terms.Effects_and_coeffects.t ->
Flambda2_to_cmm.To_cmm_env.t * Flambda2_to_cmm.To_cmm_result.tBind a variable, with support for splitting duplicatable primitives with non-duplicatable arguments.
val bind_variable :
?extra:Flambda2_to_cmm.To_cmm_env.extra_info ->
Flambda2_to_cmm.To_cmm_env.t ->
Flambda2_to_cmm.To_cmm_result.t ->
Flambda2_bound_identifiers.Bound_var.t ->
defining_expr:Cmm.expression ->
free_vars_of_defining_expr:Flambda2_to_cmm.To_cmm_env.free_vars ->
num_normal_occurrences_of_bound_vars:
Flambda2_nominal.Num_occurrences.t Flambda2_identifiers.Variable.Map.t ->
effects_and_coeffects_of_defining_expr:Flambda2_terms.Effects_and_coeffects.t ->
Flambda2_to_cmm.To_cmm_env.t * Flambda2_to_cmm.To_cmm_result.tBind a variable to the given Cmm expression, to allow for delaying the let-binding.
val add_alias :
Flambda2_to_cmm.To_cmm_env.t ->
Flambda2_to_cmm.To_cmm_result.t ->
var:Flambda2_bound_identifiers.Bound_var.t ->
alias_of:Flambda2_identifiers.Variable.t ->
num_normal_occurrences_of_bound_vars:
Flambda2_nominal.Num_occurrences.t Flambda2_identifiers.Variable.Map.t ->
Flambda2_to_cmm.To_cmm_env.t * Flambda2_to_cmm.To_cmm_result.tval add_symbol_init :
Flambda2_to_cmm.To_cmm_env.t ->
Backend_var.t ->
Cmm.expression ->
Flambda2_to_cmm.To_cmm_env.tval inline_variable :
?consider_inlining_effectful_expressions:bool ->
Flambda2_to_cmm.To_cmm_env.t ->
Flambda2_to_cmm.To_cmm_result.t ->
Flambda2_identifiers.Variable.t ->
Flambda2_to_cmm.To_cmm_env.translation_resultTry and inline an Flambda variable using the delayed let-bindings.
val flush_delayed_lets :
mode:Flambda2_to_cmm.To_cmm_env.flush_mode ->
Flambda2_to_cmm.To_cmm_env.t ->
Flambda2_to_cmm.To_cmm_result.t ->
(Cmm.expression ->
Flambda2_to_cmm.To_cmm_env.free_vars ->
Flambda2_to_cmm.To_cmm_env.Symbol_inits.t ->
Cmm.expression
* Flambda2_to_cmm.To_cmm_env.free_vars
* Flambda2_to_cmm.To_cmm_env.Symbol_inits.t)
* Flambda2_to_cmm.To_cmm_env.t
* Flambda2_to_cmm.To_cmm_result.tWrap the given Cmm expression with all the delayed let bindings accumulated in the environment.
val place_symbol_inits :
params:(Backend_var.With_provenance.t * _) list ->
Cmm.expression ->
Flambda2_to_cmm.To_cmm_env.free_vars ->
Flambda2_to_cmm.To_cmm_env.Symbol_inits.t ->
Cmm.expression
* Flambda2_to_cmm.To_cmm_env.free_vars
* Flambda2_to_cmm.To_cmm_env.Symbol_inits.tval extra_info :
Flambda2_to_cmm.To_cmm_env.t ->
Flambda2_term_basics.Simple.t ->
Flambda2_to_cmm.To_cmm_env.extra_info optionFetch the extra info for a Flambda variable (if any), specified as a Simple.
Continuation bindings
Param types: some parameters might be skipped: for instance parameters of kind Rec_info are meant to be removed during to_cmm translation.
type cont = private | Return of {param_types : Cmm.machtype list;
}| Jump of {cont : Lambda.static_label;param_types : Cmm.machtype Flambda2_to_cmm.To_cmm_env.param_type list;
}| Inline of {handler_params : Flambda2_bound_identifiers.Bound_parameters.t;handler_params_occurrences : Flambda2_nominal.Num_occurrences.t Flambda2_identifiers.Variable.Map.t;handler_body : Flambda2_terms.Flambda.Expr.t;handler_body_inlined_debuginfo : Flambda2_term_basics.Inlined_debuginfo.t;
}
Translation information for continuations. A continuation may either be translated as a static jump to a Cmm continuation (represented as a Cmm label), or inlined at any unique use site.
val add_jump_cont :
Flambda2_to_cmm.To_cmm_env.t ->
Flambda2_identifiers.Continuation.t ->
param_types:Cmm.machtype Flambda2_to_cmm.To_cmm_env.param_type list ->
Lambda.static_label * Flambda2_to_cmm.To_cmm_env.tRecord that the given continuation should be compiled to a jump, creating a fresh Cmm continuation identifier for it.
val add_inline_cont :
Flambda2_to_cmm.To_cmm_env.t ->
Flambda2_identifiers.Continuation.t ->
handler_params:Flambda2_bound_identifiers.Bound_parameters.t ->
handler_params_occurrences:
Flambda2_nominal.Num_occurrences.t Flambda2_identifiers.Variable.Map.t ->
handler_body:Flambda2_terms.Flambda.Expr.t ->
Flambda2_to_cmm.To_cmm_env.tRecord that the given continuation should be inlined.
val add_exn_handler :
Flambda2_to_cmm.To_cmm_env.t ->
Flambda2_identifiers.Continuation.t ->
[ `Unarized ] Flambda2_kinds.Flambda_arity.t ->
Flambda2_to_cmm.To_cmm_env.tRegister the given continuation as an exception handler.
val is_exn_handler :
Flambda2_to_cmm.To_cmm_env.t ->
Flambda2_identifiers.Continuation.t ->
boolReturn whether the given continuation has been registered as an exception handler.
val get_continuation :
Flambda2_to_cmm.To_cmm_env.t ->
Flambda2_identifiers.Continuation.t ->
Flambda2_to_cmm.To_cmm_env.contReturn the binding for a given continuation, describing whether it is to be compiled as a jump or inlined, etc. Produces a fatal error if given an unbound continuation.
val get_cmm_continuation :
Flambda2_to_cmm.To_cmm_env.t ->
Flambda2_identifiers.Continuation.t ->
Lambda.static_labelReturns the Cmm continuation identifier bound to a continuation. Produces a fatal error if given an unbound continuation, or a continuation that was registered (using add_inline_cont) to be inlined.
val print_param_type :
(Stdlib.Format.formatter -> 'a -> unit) ->
Stdlib.Format.formatter ->
'a Flambda2_to_cmm.To_cmm_env.param_type ->
unitprint function