216 lines
8.4 KiB
OCaml
216 lines
8.4 KiB
OCaml
(**************************************************************************)
|
|
(* *)
|
|
(* OCaml *)
|
|
(* *)
|
|
(* Pierre Chambart, OCamlPro *)
|
|
(* Mark Shinwell and Leo White, Jane Street Europe *)
|
|
(* *)
|
|
(* Copyright 2013--2016 OCamlPro SAS *)
|
|
(* Copyright 2014--2016 Jane Street Group LLC *)
|
|
(* *)
|
|
(* All rights reserved. This file is distributed under the terms of *)
|
|
(* the GNU Lesser General Public License version 2.1, with the *)
|
|
(* special exception on linking described in the file ../LICENSE. *)
|
|
(* *)
|
|
(**************************************************************************)
|
|
|
|
[@@@ocaml.warning "+a-4-9-30-40-41-42"]
|
|
|
|
(** Utility functions for the Flambda intermediate language. *)
|
|
|
|
(** Access functions *)
|
|
|
|
(** [find_declaration f decl] raises [Not_found] if [f] is not in [decl]. *)
|
|
val find_declaration :
|
|
Closure_id.t -> Flambda.function_declarations -> Flambda.function_declaration
|
|
|
|
(** [find_declaration_variable f decl] raises [Not_found] if [f] is not in
|
|
[decl]. *)
|
|
val find_declaration_variable :
|
|
Closure_id.t -> Flambda.function_declarations -> Variable.t
|
|
|
|
(** [find_free_variable v clos] raises [Not_found] if [c] is not in [clos]. *)
|
|
val find_free_variable :
|
|
Var_within_closure.t -> Flambda.set_of_closures -> Variable.t
|
|
|
|
(** Utility functions *)
|
|
|
|
val function_arity : Flambda.function_declaration -> int
|
|
|
|
(** Variables "bound by a closure" are those variables free in the
|
|
corresponding function's body that are neither:
|
|
- bound as parameters of that function; nor
|
|
- bound by the [let] binding that introduces the function declaration(s).
|
|
In particular, if [f], [g] and [h] are being introduced by a
|
|
simultaneous, possibly mutually-recursive [let] binding then none of
|
|
[f], [g] or [h] are bound in any of the closures for [f], [g] and [h].
|
|
*)
|
|
val variables_bound_by_the_closure :
|
|
Closure_id.t -> Flambda.function_declarations -> Variable.Set.t
|
|
|
|
(** If [can_be_merged f1 f2] is [true], it is safe to merge switch
|
|
branches containing [f1] and [f2]. *)
|
|
val can_be_merged : Flambda.t -> Flambda.t -> bool
|
|
|
|
val description_of_toplevel_node : Flambda.t -> string
|
|
|
|
(** Sharing key, used for coalescing switch cases. *)
|
|
type sharing_key
|
|
val make_key : Flambda.t -> sharing_key option
|
|
|
|
(* Given an expression, freshen all variables within it, and form a function
|
|
whose body is the resulting expression. The variables specified by
|
|
[params] will become the parameters of the function; the closure will be
|
|
identified by [id]. [params] must only reference variables that are
|
|
free variables of [body]. *)
|
|
(* CR-soon mshinwell: consider improving name and names of arguments
|
|
lwhite: the params restriction seems odd, perhaps give a reason
|
|
in the comment. *)
|
|
val make_closure_declaration
|
|
: id:Variable.t
|
|
-> body:Flambda.t
|
|
-> params:Variable.t list
|
|
-> Flambda.t
|
|
|
|
val toplevel_substitution
|
|
: Variable.t Variable.Map.t
|
|
-> Flambda.expr
|
|
-> Flambda.expr
|
|
|
|
val toplevel_substitution_named
|
|
: Variable.t Variable.Map.t
|
|
-> Flambda.named
|
|
-> Flambda.named
|
|
|
|
(** [bind [var1, expr1; ...; varN, exprN] body] binds using
|
|
[Immutable] [Let] expressions the given [(var, expr)] pairs around the
|
|
body. *)
|
|
val bind
|
|
: bindings:(Variable.t * Flambda.named) list
|
|
-> body:Flambda.t
|
|
-> Flambda.t
|
|
|
|
val name_expr : Flambda.named -> name:string -> Flambda.t
|
|
|
|
val compare_const : Flambda.const -> Flambda.const -> int
|
|
|
|
val initialize_symbols
|
|
: Flambda.program
|
|
-> (Symbol.t * Tag.t * Flambda.t list) list
|
|
|
|
val imported_symbols : Flambda.program -> Symbol.Set.t
|
|
|
|
val needed_import_symbols : Flambda.program -> Symbol.Set.t
|
|
|
|
val introduce_needed_import_symbols : Flambda.program -> Flambda.program
|
|
|
|
val root_symbol : Flambda.program -> Symbol.t
|
|
|
|
(** Returns [true] iff the given term might raise the given static
|
|
exception. *)
|
|
val might_raise_static_exn : Flambda.named -> Static_exception.t -> bool
|
|
|
|
(** Creates a map from closure IDs to function declarations by iterating over
|
|
all sets of closures in the given program. *)
|
|
val make_closure_map
|
|
: Flambda.program
|
|
-> Flambda.function_declarations Closure_id.Map.t
|
|
|
|
(** Like [make_closure_map], but takes a mapping from set of closures IDs to
|
|
function declarations, instead of a [program]. *)
|
|
val make_closure_map'
|
|
: Flambda.function_declarations Set_of_closures_id.Map.t
|
|
-> Flambda.function_declarations Closure_id.Map.t
|
|
|
|
(** The definitions of all constants that have been lifted out to [Let_symbol]
|
|
or [Let_rec_symbol] constructions. *)
|
|
val all_lifted_constants
|
|
: Flambda.program
|
|
-> (Symbol.t * Flambda.constant_defining_value) list
|
|
|
|
(** Like [all_lifted_constant_symbols], but returns a map instead of a list. *)
|
|
val all_lifted_constants_as_map
|
|
: Flambda.program
|
|
-> Flambda.constant_defining_value Symbol.Map.t
|
|
|
|
(** The identifiers of all constant sets of closures that have been lifted out
|
|
to [Let_symbol] or [Let_rec_symbol] constructions. *)
|
|
val all_lifted_constant_sets_of_closures
|
|
: Flambda.program
|
|
-> Set_of_closures_id.Set.t
|
|
|
|
(** All sets of closures in the given program (whether or not bound to a
|
|
symbol.) *)
|
|
val all_sets_of_closures : Flambda.program -> Flambda.set_of_closures list
|
|
|
|
val all_sets_of_closures_map
|
|
: Flambda.program
|
|
-> Flambda.set_of_closures Set_of_closures_id.Map.t
|
|
|
|
val all_function_decls_indexed_by_set_of_closures_id
|
|
: Flambda.program
|
|
-> Flambda.function_declarations Set_of_closures_id.Map.t
|
|
|
|
val all_function_decls_indexed_by_closure_id
|
|
: Flambda.program
|
|
-> Flambda.function_declarations Closure_id.Map.t
|
|
|
|
val make_variable_symbol : Variable.t -> Symbol.t
|
|
val make_variables_symbol : Variable.t list -> Symbol.t
|
|
|
|
(* CR-someday pchambart: A more general version of this function might
|
|
take a [named] instead of a symbol and be called with
|
|
[Read_symbol_field (symbol, 0)]. *)
|
|
val substitute_read_symbol_field_for_variables
|
|
: (Symbol.t * int list) Variable.Map.t
|
|
-> Flambda.t
|
|
-> Flambda.t
|
|
|
|
(** For the compilation of switch statements. *)
|
|
module Switch_storer : sig
|
|
val mk_store : unit -> Flambda.t Switch.t_store
|
|
end
|
|
|
|
(** Within a set of function declarations there is a set of function bodies,
|
|
each of which may (or may not) reference one of the other functions in
|
|
the same set. Initially such intra-set references are by [Var]s (known
|
|
as "fun_var"s) but if the function is lifted by [Lift_constants] then the
|
|
references will be translated to [Symbol]s. This means that optimization
|
|
passes that need to identify whether a given "fun_var" (i.e. a key in the
|
|
[funs] map in a value of type [function_declarations]) is used in one of
|
|
the function bodies need to examine the [free_symbols] as well as the
|
|
[free_variables] members of [function_declarations]. This function makes
|
|
that process easier by computing all used "fun_var"s in the bodies of
|
|
the given set of function declarations, including the cases where the
|
|
references are [Symbol]s. The returned value is a map from "fun_var"s
|
|
to the "fun_var"s (if any) used in the body of the function associated
|
|
with that "fun_var".
|
|
*)
|
|
val fun_vars_referenced_in_decls
|
|
: Flambda.function_declarations
|
|
-> backend:(module Backend_intf.S)
|
|
-> Variable.Set.t Variable.Map.t
|
|
|
|
(** Computes the set of closure_id in the set of closures that are
|
|
required used (transitively) the entry_point *)
|
|
val closures_required_by_entry_point
|
|
: entry_point:Closure_id.t
|
|
-> backend:(module Backend_intf.S)
|
|
-> Flambda.function_declarations
|
|
-> Variable.Set.t
|
|
|
|
val all_functions_parameters : Flambda.function_declarations -> Variable.Set.t
|
|
|
|
val all_free_symbols : Flambda.function_declarations -> Symbol.Set.t
|
|
|
|
val contains_stub : Flambda.function_declarations -> bool
|
|
|
|
(* Ensure that projection information is suitably erased from
|
|
free_vars and specialised_args if we have deleted the variable being
|
|
projected from. *)
|
|
val clean_projections
|
|
: which_variables : Flambda.specialised_to Variable.Map.t
|
|
-> Flambda.specialised_to Variable.Map.t
|
|
|
|
val projection_to_named : Projection.t -> Flambda.named
|