jon.recoil.org

Module Flambda2_reaper.Traverse_acc

Accumulator used during the downward traversal of the Flambda 2 term to build the global flow graph for the reaper.

module Graph = Global_flow_graph
type continuation_info = {
  1. is_exn_handler : bool;
  2. params : Flambda2_identifiers.Variable.t list;
  3. arity : Flambda2_kinds.Flambda_kind.With_subkind.t list;
}

Information about a continuation, including its parameters, arity, and whether it is an exception handler. This is used to register dependencies on the continuation at call sites.

type code_dep = {
  1. arity : [ `Complex ] Flambda2_kinds.Flambda_arity.t;
  2. params : Flambda2_identifiers.Variable.t list;
  3. my_closure : Flambda2_identifiers.Variable.t;
  4. return : Flambda2_identifiers.Variable.t list;
  5. exn : Flambda2_identifiers.Variable.t;
  6. is_tupled : bool;
  7. known_arity_call_witness : Flambda2_identifiers.Code_id_or_name.t;
  8. unknown_arity_call_witnesses : Flambda2_identifiers.Code_id_or_name.t list;
}

Information about a function's code that is needed for building the dependency graph. Created by prepare_code during traversal and looked up when processing function bodies and call sites at the end of the traversal.

type apply_dep = {
  1. function_containing_apply_expr : Flambda2_identifiers.Code_id.t option;
  2. apply_code_id : Flambda2_identifiers.Code_id.t;
  3. apply_closure : Flambda2_term_basics.Simple.t option;
  4. apply_call_witness : Flambda2_identifiers.Code_id_or_name.t;
}

A record of a direct function application, to be resolved into graph edges once all code has been traversed.

type t

The type of traversal accumulators.

val create : unit -> t

Create a fresh, empty accumulator.

Record the kind of a name.

val bound_parameter_kind : t -> Flambda2_bound_identifiers.Bound_parameter.t -> unit

Record the kind of a bound parameter's variable.

Record the kind of name by inferring it from simple.

Return the map of all recorded kinds.

val fixed_arity_continuation : t -> Flambda2_identifiers.Continuation.t -> unit

Mark a continuation as having fixed arity (mostly function return continuations): the rebuild pass may not change its number of parameters.

val fixed_arity_continuations : t -> Flambda2_identifiers.Continuation.Set.t

Return the set of all fixed-arity continuations.

val continuation_info : t -> Flambda2_identifiers.Continuation.t -> params:Flambda2_identifiers.Variable.t list -> arity:Flambda2_kinds.Flambda_kind.With_subkind.t list -> is_exn_handler:bool -> unit

Record metadata about a continuation (parameters, arity, and whether it is an exception handler).

Return the map of all recorded continuation metadata.

val add_code_dep : t -> Flambda2_identifiers.Code_id.t -> code_dep -> unit

Register a code_dep for a code id, recording the function's parameters, returns, and call witnesses in the accumulator.

val find_code_dep : t -> Flambda2_identifiers.Code_id.t -> code_dep option

Look up the code_dep for a code id. Returns None if the code id has not been registered (e.g. it belongs to another compilation unit).

Return the map of all registered code deps.

Add a (directed) alias edge: from flows into to_, meaning that every usage of to_ is a usage of from; and every source of from is a source of to_.

val add_alias_vars : t -> to_:Flambda2_identifiers.Variable.t -> from:Flambda2_identifiers.Variable.t -> unit

Convenience wrapper around add_alias for variables.

Add a use-dependency edge: if to_ has an usage, then from is any_usage. Besides, this is a source for to_.

Add an accessor edge: the field relation of base flows into to_.

val add_constructor_dep : t -> base:Flambda2_identifiers.Code_id_or_name.t -> Field.t -> from:Flambda2_identifiers.Code_id_or_name.t -> unit

Add a constructor edge: from flows into field relation of base.

Add an argument edge: from flows into parameters of sources of base.

Add a parameter edge: arguments of usages of base flow into to_.

Add a conditional propagation edge: if if_used is any_usage then add an alias from from to to_.

val add_alias_if_any_source_dep : t -> if_any_source:Flambda2_identifiers.Code_id_or_name.t -> to_:Flambda2_identifiers.Code_id_or_name.t -> from:Flambda2_identifiers.Code_id_or_name.t -> unit

Add a conditional alias edge: if if_any_source is marked as any_source then add an alias from from to to_.

val add_any_usage : t -> Flambda2_identifiers.Code_id_or_name.t -> unit

Mark a node as unconditionally used.

val add_any_source : t -> Flambda2_identifiers.Code_id_or_name.t -> unit

Mark a node as having any possible source (i.e. it could contain any value).

val add_zero_alloc_source : t -> Flambda2_identifiers.Code_id_or_name.t -> unit

Mark a node as a "magic" source for zero-alloc checking purposes. This is a hack to mostly preserve zero_alloc correctness before we have zero_alloc regions.

val add_code_id_my_closure : t -> Flambda2_identifiers.Code_id.t -> Flambda2_identifiers.Variable.t -> unit

Record the my_closure variable associated with a code id.

Convert a Simple.t to a dependency graph node. Constants map to the all_constants node; variables map to themselves; symbols from other compilation units are marked any_source.

val add_cond_any_usage : t -> denv:Traverse_env.t -> Flambda2_term_basics.Simple.t -> unit

Mark a Simple.t as used, conditional on the current function (if any) being used. At the top level, marks it unconditionally.

val add_cond_any_source : t -> denv:Traverse_env.t -> Flambda2_identifiers.Code_id_or_name.t -> unit

Mark a node as any_source, conditional on the current function (if any) being used. At the top level, marks it unconditionally.

val add_apply : t -> apply_dep -> unit

Record a direct function application to be resolved later by deps. Only used for applications to code ids in the current compilation unit.

Create the call witness node for a known-arity function definition. The witness carries parameter, return, exception, and code-id edges corresponding to the function's signature.

Create a call widget for a known-arity application. Links the apply's arguments to the witness's parameters, and the witness's returns and exception to the continuation parameters. Returns a node that can be connected to the callee's closure via an accessor dependency.

val create_unknown_arity_call_witnesses : t -> Flambda2_identifiers.Code_id.t -> is_tupled:bool -> arity:[ `Complex ] Flambda2_kinds.Flambda_arity.t -> params:Flambda2_identifiers.Variable.t list -> returns:Flambda2_identifiers.Variable.t list -> exn:Flambda2_identifiers.Variable.t -> Flambda2_identifiers.Code_id_or_name.t list

Create the call witness nodes for an unknown-arity function definition. For tupled functions, a single witness with tuple-field accessors is created. For curried functions, a chain of witnesses is created, one per complex parameter, linked via partial-application nodes.

Create a call widget for an unknown-arity application, analogous to make_known_arity_apply_widget but for calls where the callee's arity is not statically known.

val add_set_of_closures_dep : t -> Flambda2_identifiers.Name.t -> closure_code_id:Flambda2_identifiers.Code_id.t -> only_full_applications:bool -> defined_in_code_id:Flambda2_identifiers.Code_id.t option -> unit

Record a dependency between a closure binding and its code id. This is resolved later by deps to connect closures to their function code in the graph.

val deps : t -> all_constants:Flambda2_identifiers.Name.t -> Graph.graph

Finalize the graph by resolving all deferred apply and set-of-closures dependencies, and return the completed dependency graph.

val sort_code_ids : t -> Flambda2_identifiers.Code_id.t array