-
Notifications
You must be signed in to change notification settings - Fork 85
/
Copy pathclosure_conversion_aux.mli
416 lines (299 loc) · 12.1 KB
/
closure_conversion_aux.mli
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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
(**************************************************************************)
(* *)
(* OCaml *)
(* *)
(* Pierre Chambart, OCamlPro *)
(* Mark Shinwell and Leo White, Jane Street Europe *)
(* *)
(* Copyright 2013--2019 OCamlPro SAS *)
(* Copyright 2014--2019 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. *)
(* *)
(**************************************************************************)
(** Environments and auxiliary structures used during closure conversion. *)
module IR : sig
type simple =
| Var of Ident.t
| Const of Lambda.structured_constant
type exn_continuation =
{ exn_handler : Continuation.t;
extra_args : (simple * Lambda.value_kind) list
}
type trap_action =
| Push of { exn_handler : Continuation.t }
| Pop of { exn_handler : Continuation.t }
type user_visible =
| User_visible
| Not_user_visible
type named =
| Simple of simple
| Get_tag of Ident.t (* Intermediary primitive for block switch *)
| Begin_region of { try_region_parent : Ident.t option }
| End_region of Ident.t
(** [Begin_region] and [End_region] are needed because these primitives
don't exist in Lambda *)
| Prim of
{ prim : Lambda.primitive;
args : simple list;
loc : Lambda.scoped_location;
exn_continuation : exn_continuation option;
region : Ident.t
}
type apply_kind =
| Function
| Method of
{ kind : Lambda.meth_kind;
obj : simple
}
type apply =
{ kind : apply_kind;
func : Ident.t;
args : simple list;
continuation : Continuation.t;
exn_continuation : exn_continuation;
loc : Lambda.scoped_location;
region_close : Lambda.region_close;
inlined : Lambda.inlined_attribute;
probe : Lambda.probe;
mode : Lambda.alloc_mode;
region : Ident.t
}
type switch =
{ numconsts : int;
consts : (int * Continuation.t * trap_action option * simple list) list;
failaction : (Continuation.t * trap_action option * simple list) option
}
val print_named : Format.formatter -> named -> unit
end
module Inlining : sig
type inlinable_result =
| Not_inlinable
| Inlinable of Code.t
val threshold : unit -> int
val definition_inlining_decision :
Inline_attribute.t ->
Cost_metrics.t ->
Function_decl_inlining_decision_type.t
end
(** Used to remember which [Variable.t] values correspond to which [Ident.t]
values during closure conversion, and similarly for static exception
identifiers. *)
module Env : sig
type value_approximation = Code_or_metadata.t Value_approximation.t
type t
val create : big_endian:bool -> t
val clear_local_bindings : t -> t
val add_var : t -> Ident.t -> Variable.t -> Flambda_kind.With_subkind.t -> t
val add_vars :
t -> Ident.t list -> (Variable.t * Flambda_kind.With_subkind.t) list -> t
val add_var_map :
t -> (Variable.t * Flambda_kind.With_subkind.t) Ident.Map.t -> t
val add_var_like :
t ->
Ident.t ->
IR.user_visible ->
Flambda_kind.With_subkind.t ->
t * Variable.t
val add_vars_like :
t ->
(Ident.t * IR.user_visible * Flambda_kind.With_subkind.t) list ->
t * Variable.t list
val find_name : t -> Ident.t -> Name.t
val find_name_exn : t -> Ident.t -> Name.t
val find_var : t -> Ident.t -> Variable.t * Flambda_kind.With_subkind.t
val find_var_exn : t -> Ident.t -> Variable.t * Flambda_kind.With_subkind.t
val find_vars :
t -> Ident.t list -> (Variable.t * Flambda_kind.With_subkind.t) list
val add_global : t -> int -> Symbol.t -> t
val find_global : t -> int -> Symbol.t
val add_simple_to_substitute :
t -> Ident.t -> Simple.t -> Flambda_kind.With_subkind.t -> t
val add_simple_to_substitute_map :
t -> (Simple.t * Flambda_kind.With_subkind.t) Ident.Map.t -> t
val find_simple_to_substitute_exn :
t -> Ident.t -> Simple.t * Flambda_kind.With_subkind.t
val add_var_approximation : t -> Variable.t -> value_approximation -> t
val add_block_approximation :
t -> Variable.t -> value_approximation array -> Alloc_mode.For_types.t -> t
val find_var_approximation : t -> Variable.t -> value_approximation
val current_depth : t -> Variable.t option
val with_depth : t -> Variable.t -> t
val current_unit : t -> Compilation_unit.t
val big_endian : t -> bool
val set_path_to_root : t -> Debuginfo.Scoped_location.t -> t
val path_to_root : t -> Debuginfo.Scoped_location.t
(* The inlining tracker is used to ensure that absolute histories are shared
between functions defined under the same scope. *)
val use_inlining_history_tracker : t -> Inlining_history.Tracker.t -> t
val inlining_history_tracker : t -> Inlining_history.Tracker.t
(* Relative paths are built directly from scoped locations.
This is fine because when we convert a function call we know that it was
never inlined beforehand and thus should inherit a path corresponding to
its true location in the source file. *)
val relative_history_from_scoped :
loc:Debuginfo.Scoped_location.t -> t -> Inlining_history.Relative.t
end
(** Used to pipe some data through closure conversion *)
module Acc : sig
type closure_info = private
{ return_continuation : Continuation.t;
exn_continuation : Exn_continuation.t;
my_closure : Variable.t;
is_purely_tailrec : bool
}
type t
val create : slot_offsets:Slot_offsets.t -> cmx_loader:Flambda_cmx.loader -> t
val declared_symbols : t -> (Symbol.t * Static_const.t) list
val lifted_sets_of_closures :
t ->
((Symbol.t * Env.value_approximation) Function_slot.Lmap.t
* Flambda.Set_of_closures.t)
list
val shareable_constants : t -> Symbol.t Static_const.Map.t
val code : t -> Code.t Code_id.Map.t
val free_names : t -> Name_occurrences.t
val seen_a_function : t -> bool
val with_seen_a_function : t -> bool -> t
val add_declared_symbol : symbol:Symbol.t -> constant:Static_const.t -> t -> t
val add_lifted_set_of_closures :
symbols:(Symbol.t * Env.value_approximation) Function_slot.Lmap.t ->
set_of_closures:Flambda.Set_of_closures.t ->
t ->
t
val add_shareable_constant :
symbol:Symbol.t -> constant:Static_const.t -> t -> t
val add_code : code_id:Code_id.t -> code:Code.t -> t -> t
val add_free_names : Name_occurrences.t -> t -> t
val remove_var_from_free_names : Variable.t -> t -> t
val remove_continuation_from_free_names : Continuation.t -> t -> t
val mark_continuation_as_untrackable : Continuation.t -> t -> t
val continuation_known_arguments :
cont:Continuation.t -> t -> Env.value_approximation list option
val with_free_names : Name_occurrences.t -> t -> t
(* This is intended to evaluate a distinct free_names from the one in acc, one
must be careful to update acc afterward when necessary *)
val eval_branch_free_names :
t -> f:(t -> t * 'a) -> Name_occurrences.t * t * 'a
val cost_metrics : t -> Cost_metrics.t
val increment_metrics : Cost_metrics.t -> t -> t
val with_cost_metrics : Cost_metrics.t -> t -> t
(* Executes [f] in an acc with an empty cost metrics and returns the cost
metrics for the term generated by f separately from the one in the acc. As
for [eval_branch_free_names], the returned free_names differ from the one
in acc *)
val measure_cost_metrics :
t -> f:(t -> t * 'a) -> Cost_metrics.t * Name_occurrences.t * t * 'a
val slot_offsets : t -> Slot_offsets.t
val add_set_of_closures_offsets :
is_phantom:bool -> t -> Set_of_closures.t -> t
val top_closure_info : t -> closure_info option
val push_closure_info :
t ->
return_continuation:Continuation.t ->
exn_continuation:Exn_continuation.t ->
my_closure:Variable.t ->
is_purely_tailrec:bool ->
t
val pop_closure_info : t -> closure_info * t
val add_symbol_approximation : t -> Symbol.t -> Env.value_approximation -> t
val find_symbol_approximation : t -> Symbol.t -> Env.value_approximation
end
(** Used to represent information about a set of function declarations during
closure conversion. (The only case in which such a set may contain more than
one declaration is when processing "let rec".) *)
module Function_decls : sig
module Function_decl : sig
type t
val create :
let_rec_ident:Ident.t option ->
function_slot:Function_slot.t ->
kind:Lambda.function_kind ->
params:(Ident.t * Lambda.value_kind) list ->
return:Lambda.value_kind ->
return_continuation:Continuation.t ->
exn_continuation:IR.exn_continuation ->
my_region:Ident.t ->
body:(Acc.t -> Env.t -> Acc.t * Flambda.Import.Expr.t) ->
attr:Lambda.function_attribute ->
loc:Lambda.scoped_location ->
free_idents_of_body:Ident.Set.t ->
Recursive.t ->
closure_alloc_mode:Lambda.alloc_mode ->
num_trailing_local_params:int ->
contains_no_escaping_local_allocs:bool ->
t
val let_rec_ident : t -> Ident.t
val function_slot : t -> Function_slot.t
val kind : t -> Lambda.function_kind
val params : t -> (Ident.t * Lambda.value_kind) list
val return : t -> Lambda.value_kind
val return_continuation : t -> Continuation.t
val exn_continuation : t -> IR.exn_continuation
val my_region : t -> Ident.t
val body : t -> Acc.t -> Env.t -> Acc.t * Flambda.Import.Expr.t
val inline : t -> Lambda.inline_attribute
val specialise : t -> Lambda.specialise_attribute
val poll_attribute : t -> Lambda.poll_attribute
val loop : t -> Lambda.loop_attribute
val is_a_functor : t -> bool
val check_attribute : t -> Lambda.check_attribute
val stub : t -> bool
val loc : t -> Lambda.scoped_location
val recursive : t -> Recursive.t
val closure_alloc_mode : t -> Lambda.alloc_mode
val num_trailing_local_params : t -> int
val contains_no_escaping_local_allocs : t -> bool
(* Like [all_free_idents], but for just one function. *)
val free_idents : t -> Ident.Set.t
end
type t
val create : Function_decl.t list -> Lambda.alloc_mode -> t
val alloc_mode : t -> Lambda.alloc_mode
val to_list : t -> Function_decl.t list
(* All identifiers free in the given function declarations after the binding
of parameters and function identifiers has been performed. *)
val all_free_idents : t -> Ident.Set.t
end
open! Flambda.Import
module Expr_with_acc : sig
type t = Acc.t * Expr.t
val create_apply_cont : Acc.t -> Apply_cont.t -> t
val create_apply : Acc.t -> Apply.t -> t
val create_switch : Acc.t -> Switch.t -> t
val create_invalid : Acc.t -> Flambda.Invalid.t -> t
end
module Apply_cont_with_acc : sig
val create :
Acc.t ->
?trap_action:Trap_action.t ->
?args_approx:Env.value_approximation list ->
Continuation.t ->
args:Simple.t list ->
dbg:Debuginfo.t ->
Acc.t * Apply_cont.t
val goto : Acc.t -> Continuation.t -> Acc.t * Apply_cont.t
end
module Let_with_acc : sig
val create :
Acc.t -> Bound_pattern.t -> Named.t -> body:Expr.t -> Expr_with_acc.t
end
module Let_cont_with_acc : sig
val build_recursive :
Acc.t ->
handlers:
((Acc.t -> Expr_with_acc.t) * Bound_parameters.t * bool)
Continuation.Map.t ->
body:(Acc.t -> Expr_with_acc.t) ->
Expr_with_acc.t
val build_non_recursive :
Acc.t ->
Continuation.t ->
handler_params:Bound_parameters.t ->
handler:(Acc.t -> Expr_with_acc.t) ->
body:(Acc.t -> Expr_with_acc.t) ->
is_exn_handler:bool ->
Expr_with_acc.t
end