Skip to content

Commit 4e9b884

Browse files
committed
WIP
1 parent a15ea78 commit 4e9b884

File tree

1 file changed

+82
-37
lines changed

1 file changed

+82
-37
lines changed

compiler/lib/inline.ml

Lines changed: 82 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,12 @@ type info =
7777
; params : Var.t list
7878
; cont : Code.cont
7979
; enclosing_function : Var.t option
80+
; recursive : bool
8081
; loops : bool cache
8182
; body_size : int cache
8283
; full_size : int cache
8384
; closure_count : int cache
8485
; init_code : int cache
85-
; recursive : bool cache
8686
; return_block : bool cache
8787
; interesting_params : (Var.t * int) list cache
8888
; mutable dead : bool
@@ -176,34 +176,6 @@ let count_init_code info =
176176
~init:0
177177
body)
178178

179-
let is_recursive info ~env =
180-
let f = info.f in
181-
cache info.cont info.recursive (fun { blocks; _ } pc ->
182-
let rec traverse blocks f pc =
183-
Code.traverse
184-
{ fold = fold_children }
185-
(fun pc _ ->
186-
let block = Addr.Map.find pc blocks in
187-
Freevars.iter_block_free_vars
188-
(fun f' -> if Var.equal f f' then raise Exit)
189-
block;
190-
List.iter
191-
~f:(fun i ->
192-
match i with
193-
| Let (f', Closure (_, (pc', _))) ->
194-
if not (Var.Map.mem f' env && (Var.Map.find f' env).dead)
195-
then traverse blocks f pc'
196-
| _ -> ())
197-
block.body)
198-
pc
199-
blocks
200-
()
201-
in
202-
try
203-
traverse blocks f pc;
204-
false
205-
with Exit -> true)
206-
207179
let return_block info =
208180
cache info.cont info.return_block (fun { blocks; _ } pc ->
209181
Code.traverse
@@ -246,10 +218,10 @@ let interesting_parameters info ~live_vars =
246218
[])
247219

248220
let functor_like ~env p info =
249-
(not (contains_loop info p))
221+
(not info.recursive)
222+
&& (not (contains_loop info p))
250223
&& return_block info p
251224
&& count_init_code info p * 2 > body_size info ~env p
252-
&& (not (is_recursive info ~env p))
253225
&& full_size info ~env p - body_size info ~env p <= 20 * closure_count info ~env p
254226

255227
let rec small_function
@@ -262,9 +234,9 @@ let rec small_function
262234
~has_closures
263235
info
264236
args =
265-
body_size info ~env p <= 15
237+
(not info.recursive)
238+
&& body_size info ~env p <= 15
266239
&& closure_count info ~env p = 0
267-
&& (not (is_recursive info ~env p))
268240
&& (not (List.is_empty args))
269241
&&
270242
let relevant_params = interesting_parameters info ~live_vars p in
@@ -343,6 +315,79 @@ and should_inline
343315

344316
(****)
345317

318+
let collect_closures p =
319+
let rec traverse p current pc closures =
320+
Code.traverse
321+
{ fold = Code.fold_children }
322+
(fun pc closures ->
323+
let block = Addr.Map.find pc p.blocks in
324+
List.fold_left
325+
~f:(fun closures i ->
326+
match i with
327+
| Let (f, Closure (params, ((pc', _) as cont))) ->
328+
let closures = Var.Map.add f (params, cont, current) closures in
329+
traverse p (Some f) pc' closures
330+
| _ -> closures)
331+
~init:closures
332+
block.body)
333+
pc
334+
p.blocks
335+
closures
336+
in
337+
traverse p None p.start Var.Map.empty
338+
339+
let add_dep deps current f =
340+
Option.iter
341+
~f:(fun g -> deps := Var.Map.add f (Var.Set.add g (Var.Map.find f !deps)) !deps)
342+
current
343+
344+
let collect_deps p closures =
345+
let deps = ref (Var.Map.map (fun _ -> Var.Set.empty) closures) in
346+
let traverse p current pc =
347+
Code.traverse
348+
{ fold = Code.fold_children }
349+
(fun pc () ->
350+
let block = Addr.Map.find pc p.blocks in
351+
Freevars.iter_block_free_vars
352+
(fun f -> if Var.Map.mem f closures then add_dep deps current f)
353+
block;
354+
List.iter
355+
~f:(fun i ->
356+
match i with
357+
| Let (f, Closure _) -> add_dep deps current f
358+
| _ -> ())
359+
block.body)
360+
pc
361+
p.blocks
362+
()
363+
in
364+
traverse p None p.start;
365+
Var.Map.iter (fun f (_, (pc, _), _) -> traverse p (Some f) pc) closures;
366+
!deps
367+
368+
module Var_SCC = Strongly_connected_components.Make (Var)
369+
370+
let visit_closures p f acc =
371+
let closures = collect_closures p in
372+
let deps = collect_deps p closures in
373+
let scc = Var_SCC.connected_components_sorted_from_roots_to_leaf deps in
374+
let f' recursive acc g =
375+
let params, cont, parent = Var.Map.find g closures in
376+
f recursive parent (Some g) params cont acc
377+
in
378+
let acc =
379+
Array.fold_left
380+
scc
381+
~f:(fun acc group ->
382+
match group with
383+
| Var_SCC.No_loop g -> f' false acc g
384+
| Has_loop l -> List.fold_left ~f:(fun acc g -> f' true acc g) ~init:acc l)
385+
~init:acc
386+
in
387+
f false None None [] (p.start, []) acc
388+
389+
(****)
390+
346391
let rewrite_block pc' pc blocks =
347392
let block = Addr.Map.find pc blocks in
348393
let block =
@@ -468,7 +513,7 @@ let trace_inlining
468513
sz
469514
sz'
470515
(contains_loop info p)
471-
(is_recursive info ~env p)
516+
info.recursive
472517
(closure_count info ~env p)
473518
(count_init_code info p)
474519
(return_block info p)
@@ -547,9 +592,9 @@ let inline_in_block
547592
let inline ~inline_count p ~live_vars =
548593
if debug () then Format.eprintf "====== inlining ======@.";
549594
fst
550-
(Code.fold_closures_in_reverse_postorder
595+
(visit_closures
551596
p
552-
(fun enclosing_function name_opt params ((pc, _) as cont) (p, env) ->
597+
(fun recursive enclosing_function name_opt params ((pc, _) as cont) (p, env) ->
553598
let has_closures = ref (closure_count_uncached ~env p pc > 0) in
554599
let in_loop = blocks_in_loop p pc in
555600
let p =
@@ -591,12 +636,12 @@ let inline ~inline_count p ~live_vars =
591636
; params
592637
; cont
593638
; enclosing_function
639+
; recursive
594640
; loops = ref None
595641
; body_size = ref None
596642
; full_size = ref None
597643
; closure_count = ref None
598644
; init_code = ref None
599-
; recursive = ref None
600645
; return_block = ref None
601646
; interesting_params = ref None
602647
; dead = false

0 commit comments

Comments
 (0)