1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
|
(**************************************************************************)
(* *)
(* 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"]
(** Exported information (that is to say, information written into a .cmx
file) about a compilation unit. *)
module A = Simple_value_approx
type value_string_contents =
| Contents of string
| Unknown_or_mutable
type value_string = {
contents : value_string_contents;
size : int;
}
type value_float_array_contents =
| Contents of float option array
| Unknown_or_mutable
type value_float_array = {
contents : value_float_array_contents;
size : int;
}
type descr =
| Value_block of Tag.t * approx array
| Value_mutable_block of Tag.t * int
| Value_int of int
| Value_char of char
| Value_float of float
| Value_float_array of value_float_array
| Value_boxed_int : 'a A.boxed_int * 'a -> descr
| Value_string of value_string
| Value_closure of value_closure
| Value_set_of_closures of value_set_of_closures
| Value_unknown_descr
and value_closure = {
closure_id : Closure_id.t;
set_of_closures : value_set_of_closures;
}
and value_set_of_closures = {
set_of_closures_id : Set_of_closures_id.t;
bound_vars : approx Var_within_closure.Map.t;
free_vars : Flambda.specialised_to Variable.Map.t;
results : approx Closure_id.Map.t;
aliased_symbol : Symbol.t option;
}
(* CR-soon mshinwell: Fix the export information so we can correctly
propagate "unresolved due to..." in the manner of [Simple_value_approx].
Unfortunately this seems to be complicated by the fact that, during
[Import_approx], resolution can fail not only due to missing symbols but
also due to missing export IDs. The argument type of
[Simple_value_approx.t] may need updating to reflect this (make the
symbol optional? It's only for debugging anyway.) *)
and approx =
| Value_unknown
| Value_id of Export_id.t
| Value_symbol of Symbol.t
(** A structure that describes what a single compilation unit exports. *)
type t = private {
sets_of_closures : A.function_declarations Set_of_closures_id.Map.t;
(** Code of exported functions indexed by set of closures IDs. *)
values : descr Export_id.Map.t Compilation_unit.Map.t;
(** Structure of exported values. *)
symbol_id : Export_id.t Symbol.Map.t;
(** Associates symbols and values. *)
offset_fun : int Closure_id.Map.t;
(** Positions of function pointers in their closures. *)
offset_fv : int Var_within_closure.Map.t;
(** Positions of value pointers in their closures. *)
constant_closures : Closure_id.Set.t;
(* CR-soon mshinwell for pchambart: Add comment *)
invariant_params : Variable.Set.t Variable.Map.t Set_of_closures_id.Map.t;
(* Function parameters known to be invariant (see [Invariant_params])
indexed by set of closures ID. *)
recursive : Variable.Set.t Set_of_closures_id.Map.t;
}
type transient = private {
sets_of_closures : A.function_declarations Set_of_closures_id.Map.t;
values : descr Export_id.Map.t Compilation_unit.Map.t;
symbol_id : Export_id.t Symbol.Map.t;
invariant_params : Variable.Set.t Variable.Map.t Set_of_closures_id.Map.t;
recursive : Variable.Set.t Set_of_closures_id.Map.t;
relevant_local_closure_ids : Closure_id.Set.t;
relevant_imported_closure_ids : Closure_id.Set.t;
relevant_local_vars_within_closure : Var_within_closure.Set.t;
relevant_imported_vars_within_closure : Var_within_closure.Set.t;
}
(** Export information for a compilation unit that exports nothing. *)
val empty : t
val opaque_transient
: compilation_unit:Compilation_unit.t
-> root_symbol:Symbol.t
-> transient
(** Create a new export information structure. *)
val create
: sets_of_closures:(A.function_declarations Set_of_closures_id.Map.t)
-> values:descr Export_id.Map.t Compilation_unit.Map.t
-> symbol_id:Export_id.t Symbol.Map.t
-> offset_fun:int Closure_id.Map.t
-> offset_fv:int Var_within_closure.Map.t
-> constant_closures:Closure_id.Set.t
-> invariant_params:Variable.Set.t Variable.Map.t Set_of_closures_id.Map.t
-> recursive:Variable.Set.t Set_of_closures_id.Map.t
-> t
val create_transient
: sets_of_closures:(A.function_declarations Set_of_closures_id.Map.t)
-> values:descr Export_id.Map.t Compilation_unit.Map.t
-> symbol_id:Export_id.t Symbol.Map.t
-> invariant_params:Variable.Set.t Variable.Map.t Set_of_closures_id.Map.t
-> recursive:Variable.Set.t Set_of_closures_id.Map.t
-> relevant_local_closure_ids: Closure_id.Set.t
-> relevant_imported_closure_ids : Closure_id.Set.t
-> relevant_local_vars_within_closure : Var_within_closure.Set.t
-> relevant_imported_vars_within_closure : Var_within_closure.Set.t
-> transient
(* CR-someday pchambart: Should we separate [t] in 2 types: one created by the
current [create] function, returned by [Build_export_info]. And
another built using t and offset_informations returned by
[flambda_to_clambda] ?
mshinwell: I think we should, but after we've done the first release.
*)
(** Record information about the layout of closures and which sets of
closures are constant. These are all worked out during the
[Flambda_to_clambda] pass. *)
val t_of_transient
: transient
-> program: Flambda.program
-> local_offset_fun:int Closure_id.Map.t
-> local_offset_fv:int Var_within_closure.Map.t
-> imported_offset_fun:int Closure_id.Map.t
-> imported_offset_fv:int Var_within_closure.Map.t
-> constant_closures:Closure_id.Set.t
-> t
(** Union of export information. Verifies that there are no identifier
clashes. *)
val merge : t -> t -> t
(** Look up the description of an exported value given its export ID. *)
val find_description
: t
-> Export_id.t
-> descr
(** Partition a mapping from export IDs by compilation unit. *)
val nest_eid_map
: 'a Export_id.Map.t
-> 'a Export_id.Map.t Compilation_unit.Map.t
(**/**)
(* Debug printing functions. *)
val print_approx_components
: Format.formatter
-> symbol_id: Export_id.t Symbol.Map.t
-> values: descr Export_id.Map.t Compilation_unit.Map.t
-> Symbol.t list
-> unit
val print_approx : Format.formatter -> t * Symbol.t list -> unit
val print_functions : Format.formatter -> t -> unit
val print_offsets : Format.formatter -> t -> unit
val print_all : Format.formatter -> t * Symbol.t list -> unit
(** Prints approx and descr as it is, without recursively looking up
[Export_id.t] *)
val print_raw_approx : Format.formatter -> approx -> unit
val print_raw_descr : Format.formatter -> descr -> unit
|