Skip to content

Commit c761394

Browse files
vouillonhhugo
authored andcommitted
Add / update comments
1 parent dc50018 commit c761394

File tree

1 file changed

+38
-17
lines changed

1 file changed

+38
-17
lines changed

compiler/lib/inline.ml

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,10 @@ let blocks_in_loop p pc =
164164

165165
type 'a cache = 'a option ref
166166

167+
(* Information about a function candidate for inlining. Some
168+
information / statistics about this function are computed lazily
169+
and stored there. *)
170+
167171
type info =
168172
{ f : Var.t
169173
; params : Var.t list
@@ -180,16 +184,18 @@ type info =
180184
}
181185

182186
type context =
183-
{ profile : Profile.t
187+
{ profile : Profile.t (** Aggressive inlining? *)
184188
; p : program
185-
; live_vars : int array
186-
; inline_count : int ref
187-
; env : info Var.Map.t
188-
; in_loop : bool
189-
; has_closures : bool ref
190-
; current_function : Var.t option
189+
; live_vars : int array (** Occurence count of all variables *)
190+
; inline_count : int ref (** Inlining statistics *)
191+
; env : info Var.Map.t (** Functions that are candidate for inlining *)
192+
; in_loop : bool (** Whether the current block is in a loop *)
193+
; has_closures : bool ref (** Whether the current function contains closures *)
194+
; current_function : Var.t option (** Name of the current function *)
191195
; enclosing_function : Var.t option
196+
(** Name of the function enclosing the current function *)
192197
}
198+
(** Current context into which we consider inlining some functions. *)
193199

194200
let cache ~info:{ cont = pc, _; _ } ref f =
195201
match !ref with
@@ -199,6 +205,7 @@ let cache ~info:{ cont = pc, _; _ } ref f =
199205
ref := Some v;
200206
v
201207

208+
(** Does the function contain a loop? *)
202209
let contains_loop ~context info =
203210
cache ~info info.loops (fun pc ->
204211
let rec traverse pc ((visited, loop) as accu) : _ * bool =
@@ -244,8 +251,10 @@ let rec block_size ~recurse ~context { branch; body; _ } =
244251

245252
and size ~recurse ~context = sum ~context (block_size ~recurse ~context)
246253

254+
(** Size of the function body *)
247255
let body_size ~context info = cache ~info info.body_size (size ~recurse:false ~context)
248256

257+
(** Size of the function, including the size of the closures it contains *)
249258
let full_size ~context info = cache ~info info.full_size (size ~recurse:true ~context)
250259

251260
let closure_count_uncached ~context =
@@ -258,9 +267,12 @@ let closure_count_uncached ~context =
258267
~init:0
259268
body)
260269

270+
(** Number of closures contained in the function *)
261271
let closure_count ~context info =
262272
cache ~info info.closure_count (closure_count_uncached ~context)
263273

274+
(** Number of instructions in the function which look like
275+
initialization code. *)
264276
let count_init_code ~context info =
265277
cache
266278
~info
@@ -276,6 +288,7 @@ let count_init_code ~context info =
276288
~init:0
277289
body)
278290

291+
(** Whether the function returns a block. *)
279292
let returns_a_block ~context info =
280293
cache ~info info.returns_a_block (fun pc ->
281294
let blocks = context.p.blocks in
@@ -295,6 +308,8 @@ let returns_a_block ~context info =
295308
blocks
296309
true)
297310

311+
(** List of parameters that corresponds to functions called once in
312+
the function body. *)
298313
let interesting_parameters ~context info =
299314
let params = info.params in
300315
cache ~info info.interesting_params (fun pc ->
@@ -334,7 +349,10 @@ let functor_like ~context info =
334349
&& (not (contains_loop ~context info))
335350
&& returns_a_block ~context info
336351
&& count_init_code ~context info * 2 > body_size ~context info
337-
&& full_size ~context info - body_size ~context info <= 20 * closure_count ~context info
352+
(* A large portion of the body is initialization code *)
353+
&&
354+
(* The closures defined in this function are small on average *)
355+
full_size ~context info - body_size ~context info <= 20 * closure_count ~context info
338356

339357
let trivial_function ~context info =
340358
body_size ~context info <= 1 && closure_count ~context info = 0
@@ -373,13 +391,16 @@ let rec small_function ~context info args =
373391
with Exit -> true
374392

375393
and should_inline ~context info args =
376-
(* A closure contains a pointer to (recursively) the contexts of its
377-
enclosing functions. The context of a function contains the
378-
variables bound in this function which are referred to from one
379-
of the enclosed function. To limit the risk of memory leaks, we
380-
don't inline functions containing closure if this makes these
381-
closures capture additional contexts shared with other
382-
closures. *)
394+
(* Typically, in JavaScript implementations, a closure contains a
395+
pointer to (recursively) the contexts of its enclosing functions.
396+
The context of a function contains the variables bound in this
397+
function which are referred to from one of the enclosed function.
398+
To limit the risk of memory leaks, we try to avoid inlining functions
399+
containing closures if this makes these closures capture
400+
additional contexts shared with other closures.
401+
We still inline into toplevel functions ([Option.is_none
402+
context.enclosing_function]) since this results in significant
403+
performance improvements. *)
383404
(match Config.target (), Config.effects () with
384405
| `JavaScript, (`Disabled | `Cps) ->
385406
closure_count ~context info = 0
@@ -394,8 +415,8 @@ and should_inline ~context info args =
394415
&&
395416
match Config.target () with
396417
| `Wasm when context.in_loop ->
397-
(* Avoid inlining in loop since, if the loop is not hot, the
398-
code might never get optimized *)
418+
(* Avoid inlining in a loop since, if the loop is not hot,
419+
the code might never get optimized *)
399420
body_size ~context info < 30 && not (contains_loop ~context info)
400421
| `JavaScript
401422
when Option.is_none context.current_function && contains_loop ~context info ->

0 commit comments

Comments
 (0)