jon.recoil.org

Module Flambda2_to_cmm.To_cmm_env

Translation environment

type t

Environment for Flambda to Cmm translation

type free_vars = Backend_var.Set.t

Free names for cmm expressions

module Symbol_inits : sig ... end

Delayed symbol initializations

A cmm expression along with extra information

Printing function

type extra_info =
  1. | 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.

Record 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 -> 'arity

Create 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.t

Given 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.t

Add the inlined debuginfo from the env to the debuginfo provided, in order to get the correct debuginfo to attach.

Adjust the inlined debuginfo in the env to represent the fact that we entered the inlined body of a function.

val currently_in_inlined_body : Flambda2_to_cmm.To_cmm_env.t -> bool

Continuations

Returns the exception continuation of the environment.

Code and closures

Retrieve 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.

Retrieve 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

Create (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.

Same 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 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:

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 simple =
  1. | Simple

Some uniques and different types

type complex =
  1. | Complex
type _ inline =
  1. | Do_not_inline : Flambda2_to_cmm.To_cmm_env.simple Flambda2_to_cmm.To_cmm_env.inline
  2. | May_inline_once : Flambda2_to_cmm.To_cmm_env.simple Flambda2_to_cmm.To_cmm_env.inline
  3. | Must_inline_once : Flambda2_to_cmm.To_cmm_env.complex Flambda2_to_cmm.To_cmm_env.inline
  4. | 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

type _ bound_expr

The type of expression that can be bound.

A 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.

Bind a variable, with support for splitting duplicatable primitives with non-duplicatable arguments.

Bind a variable to the given Cmm expression, to allow for delaying the let-binding.

Try and inline an Flambda variable using the delayed let-bindings.

type flush_mode =
  1. | Entering_loop
  2. | Branching_point
  3. | Flush_everything

Fetch the extra info for a Flambda variable (if any), specified as a Simple.

Continuation bindings

type 'a param_type =
  1. | Param of 'a
  2. | Skip_param

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
  1. | Return of {
    1. param_types : Cmm.machtype list;
    }
  2. | Jump of {
    1. cont : Lambda.static_label;
    2. param_types : Cmm.machtype Flambda2_to_cmm.To_cmm_env.param_type list;
    }
  3. | Inline of {
    1. handler_params : Flambda2_bound_identifiers.Bound_parameters.t;
    2. handler_params_occurrences : Flambda2_nominal.Num_occurrences.t Flambda2_identifiers.Variable.Map.t;
    3. handler_body : Flambda2_terms.Flambda.Expr.t;
    4. 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.

Record that the given continuation should be compiled to a jump, creating a fresh Cmm continuation identifier for it.

Register the given continuation as an exception handler.

Return whether the given continuation has been registered as an exception handler.

Return 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.

Returns 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 -> unit

print function