Skip to content

Commit 852540e

Browse files
committed
alternative approach
1 parent 54dc89b commit 852540e

File tree

1 file changed

+57
-52
lines changed

1 file changed

+57
-52
lines changed

compiler/lib/inline.ml

Lines changed: 57 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ We try to find a good order to traverse the code:
3939
first
4040
*)
4141

42-
let collect_closures p =
42+
let collect_closures closures_position p =
4343
let closures = Var.Hashtbl.create 128 in
4444
let rec traverse p enclosing pc =
4545
Code.traverse
@@ -51,6 +51,7 @@ let collect_closures p =
5151
match i with
5252
| Let (f, Closure (params, ((pc', _) as cont), _)) ->
5353
Var.Hashtbl.add closures f (params, cont, enclosing);
54+
Var.Hashtbl.add closures_position f pc;
5455
traverse p (Some f) pc'
5556
| _ -> ())
5657
block.body)
@@ -91,25 +92,20 @@ let collect_deps p closures =
9192

9293
module Var_SCC = Strongly_connected_components.Make (Var)
9394

94-
let visit_closures p ~live_vars f ~cleanup acc =
95-
let closures = collect_closures p in
95+
let visit_closures p closures_position ~live_vars f acc =
96+
let closures = collect_closures closures_position p in
9697
let deps = collect_deps p closures in
9798
let scc = Var_SCC.connected_components_sorted_from_roots_to_leaf deps in
9899
let f' recursive acc g =
99100
let params, cont, enclosing_function = Var.Hashtbl.find closures g in
100101
f ~recursive ~enclosing_function ~current_function:(Some g) ~params ~cont acc
101102
in
102-
let cleanup' l acc =
103-
List.fold_left l ~init:acc ~f:(fun acc x ->
104-
let _, (pc, _), _ = Var.Hashtbl.find closures x in
105-
cleanup pc acc)
106-
in
107103
let acc =
108104
Array.fold_left
109105
scc
110106
~f:(fun acc group ->
111107
match group with
112-
| Var_SCC.No_loop g -> f' false acc g |> cleanup' [ g ]
108+
| Var_SCC.No_loop g -> f' false acc g
113109
| Has_loop l ->
114110
let set = Var.Set.of_list l in
115111
let deps' =
@@ -129,14 +125,9 @@ let visit_closures p ~live_vars f ~cleanup acc =
129125
scc
130126
~f:(fun acc group ->
131127
match group with
132-
| Var_SCC.No_loop g -> f' true acc g |> cleanup' [ g ]
133-
| Has_loop l ->
134-
List.fold_left
135-
~f:(fun acc g -> f' true acc g |> cleanup' [ g ])
136-
~init:acc
137-
l)
138-
~init:acc
139-
|> cleanup' l)
128+
| Var_SCC.No_loop g -> f' true acc g
129+
| Has_loop l -> List.fold_left ~f:(fun acc g -> f' true acc g) ~init:acc l)
130+
~init:acc)
140131
~init:acc
141132
in
142133
f
@@ -146,7 +137,6 @@ let visit_closures p ~live_vars f ~cleanup acc =
146137
~params:[]
147138
~cont:(p.start, [])
148139
acc
149-
|> cleanup p.start
150140

151141
(****)
152142

@@ -196,6 +186,7 @@ type info =
196186

197187
type context =
198188
{ profile : Profile.t (** Aggressive inlining? *)
189+
; closures_position : Addr.t Var.Hashtbl.t
199190
; p : program
200191
; live_vars : int array (** Occurence count of all variables *)
201192
; inline_count : int ref (** Inlining statistics *)
@@ -481,32 +472,17 @@ let remove_dead_closures_from_block ~live_vars block =
481472
f < Array.length live_vars && live_vars.(f) = 0
482473
| _ -> false
483474
in
484-
if List.exists ~f:is_dead_closure block.body
485-
then
486-
{ block with
487-
body =
488-
List.fold_left block.body ~init:[] ~f:(fun acc i ->
489-
match i, acc with
490-
| Event _, Event _ :: prev ->
491-
(* Avoid consecutive events (keep just the last one) *)
492-
i :: prev
493-
| _ -> if is_dead_closure i then acc else i :: acc)
494-
|> List.rev
495-
}
496-
else block
497-
498-
let remove_dead_closures ~live_vars p pc =
499-
Code.traverse
500-
{ fold = fold_children }
501-
(fun pc p ->
502-
let block = Addr.Map.find pc p.blocks in
503-
let block' = remove_dead_closures_from_block ~live_vars block in
504-
if phys_equal block block'
505-
then p
506-
else { p with blocks = Addr.Map.add pc block' p.blocks })
507-
pc
508-
p.blocks
509-
p
475+
assert (List.exists ~f:is_dead_closure block.body);
476+
{ block with
477+
body =
478+
List.fold_left block.body ~init:[] ~f:(fun acc i ->
479+
match i, acc with
480+
| Event _, Event _ :: prev ->
481+
(* Avoid consecutive events (keep just the last one) *)
482+
i :: prev
483+
| _ -> if is_dead_closure i then acc else i :: acc)
484+
|> List.rev
485+
}
510486

511487
(****)
512488

@@ -527,7 +503,7 @@ let rewrite_closure blocks cont_pc clos_pc =
527503
blocks
528504
blocks
529505

530-
let inline_function p rem branch x params cont args =
506+
let inline_function closures_position p rem branch x params cont args =
531507
let blocks, cont_pc, free_pc =
532508
match rem, branch with
533509
| [], Return y when Var.equal x y ->
@@ -536,6 +512,9 @@ let inline_function p rem branch x params cont args =
536512
| _ ->
537513
let fresh_addr = p.free_pc in
538514
let free_pc = fresh_addr + 1 in
515+
List.iter rem ~f:(function
516+
| Let (x, Closure _) -> Var.Hashtbl.replace closures_position x fresh_addr
517+
| _ -> ());
539518
( Addr.Map.add fresh_addr { params = [ x ]; body = rem; branch } p.blocks
540519
, Some fresh_addr
541520
, free_pc )
@@ -552,7 +531,7 @@ let inline_function p rem branch x params cont args =
552531
in
553532
[], (Branch (fresh_addr, args), { p with blocks; free_pc })
554533

555-
let inline_in_block ~context pc block p =
534+
let inline_in_block ~context pc block p inlined =
556535
let body, (branch, p) =
557536
List.fold_right
558537
~f:(fun i (rem, state) ->
@@ -565,13 +544,15 @@ let inline_in_block ~context pc block p =
565544
then (
566545
let branch, p = state in
567546
incr context.inline_count;
547+
inlined := Var.Set.add f !inlined;
568548
if closure_count ~context info > 0 then context.has_closures := true;
569549
context.live_vars.(Var.idx f) <- context.live_vars.(Var.idx f) - 1;
570550
if context.live_vars.(Var.idx f) > 0
571551
then
572552
let p, _, params, cont = Duplicate.closure p ~f ~params ~cont in
573-
inline_function p rem branch x params cont args
574-
else inline_function p rem branch x params cont args)
553+
inline_function context.closures_position p rem branch x params cont args
554+
else
555+
inline_function context.closures_position p rem branch x params cont args)
575556
else i :: rem, state
576557
| _ -> i :: rem, state)
577558
~init:([], (block.branch, p))
@@ -580,9 +561,11 @@ let inline_in_block ~context pc block p =
580561
{ p with blocks = Addr.Map.add pc { block with body; branch } p.blocks }
581562

582563
let inline ~profile ~inline_count p ~live_vars =
564+
let closures_position = Var.Hashtbl.create 18 in
583565
if debug () then Format.eprintf "====== inlining ======@.";
584566
(visit_closures
585567
p
568+
closures_position
586569
~live_vars
587570
(fun ~recursive
588571
~enclosing_function
@@ -597,6 +580,7 @@ let inline ~profile ~inline_count p ~live_vars =
597580
let context =
598581
{ context with has_closures; enclosing_function; current_function }
599582
in
583+
let inlined = ref Var.Set.empty in
600584
let p =
601585
Code.traverse
602586
{ fold = Code.fold_children }
@@ -616,11 +600,34 @@ let inline ~profile ~inline_count p ~live_vars =
616600
~context:{ context with in_loop = Addr.Set.mem pc in_loop }
617601
pc
618602
block
619-
p)
603+
p
604+
inlined)
620605
pc
621606
p.blocks
622607
p
623608
in
609+
let blocks_to_clean =
610+
Var.Set.fold
611+
(fun f acc ->
612+
let f_idx = Var.idx f in
613+
if f_idx < Array.length live_vars && live_vars.(f_idx) = 0
614+
then
615+
let pc = Var.Hashtbl.find closures_position f in
616+
Addr.Set.add pc acc
617+
else acc)
618+
!inlined
619+
Addr.Set.empty
620+
in
621+
let blocks =
622+
Addr.Set.fold
623+
(fun pc blocks ->
624+
let block = Addr.Map.find pc blocks in
625+
let block = remove_dead_closures_from_block ~live_vars block in
626+
Addr.Map.add pc block blocks)
627+
blocks_to_clean
628+
p.blocks
629+
in
630+
let p = { p with blocks } in
624631
let env =
625632
match current_function with
626633
| Some f ->
@@ -643,10 +650,8 @@ let inline ~profile ~inline_count p ~live_vars =
643650
| None -> context.env
644651
in
645652
{ context with p; env })
646-
~cleanup:(fun pc context ->
647-
let p = remove_dead_closures ~live_vars context.p pc in
648-
{ context with p })
649653
{ profile
654+
; closures_position
650655
; p
651656
; live_vars
652657
; inline_count

0 commit comments

Comments
 (0)