Skip to content

Commit d01a127

Browse files
committed
WIP
1 parent f169621 commit d01a127

File tree

7 files changed

+80
-51
lines changed

7 files changed

+80
-51
lines changed

compiler/lib/deadcode.ml

Lines changed: 66 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ type t =
4949
; mutable deleted_instrs : int
5050
; mutable deleted_blocks : int
5151
; mutable deleted_params : int
52+
; mutable block_shortcut : int
53+
; mutable cond_to_branch : int
5254
}
5355

5456
(****)
@@ -185,10 +187,27 @@ let annot st pc xi =
185187

186188
(****)
187189

188-
let remove_unused_blocks p =
190+
let remove_unused_blocks' p =
189191
let visited = Code.mark_unused_blocks p in
190-
{ p with blocks = Addr.Map.filter (fun pc _ -> BitSet.mem visited pc) p.blocks }
192+
let count = ref 0 in
193+
let blocks =
194+
Addr.Map.filter
195+
(fun pc _ ->
196+
match BitSet.mem visited pc with
197+
| true -> true
198+
| false ->
199+
incr count;
200+
false)
201+
p.blocks
202+
in
203+
{ p with blocks }, !count
191204

205+
let remove_unused_blocks p =
206+
let t = Timer.make () in
207+
let p, count = remove_unused_blocks' p in
208+
if times () then Format.eprintf " dead block elim.: %a@." Timer.print t;
209+
if stats () then Format.eprintf "Stats - dead block: %d unused blocks@." count;
210+
p, count
192211
(****)
193212

194213
let rec add_arg_dep defs params args =
@@ -209,24 +228,24 @@ let empty_body b =
209228
| [] | [ Event _ ] -> true
210229
| _ -> false
211230

212-
let remove_empty_blocks ~live_vars (p : Code.program) : Code.program =
213-
let previous_p = p in
214-
let t = Timer.make () in
215-
let count = ref 0 in
231+
let remove_empty_blocks st (p : Code.program) : Code.program =
216232
let shortcuts = Hashtbl.create 16 in
217233
let rec resolve_rec visited ((pc, args) as cont) =
218234
if Addr.Set.mem pc visited
219235
then cont
220236
else
221237
match Hashtbl.find_opt shortcuts pc with
222238
| Some (params, cont) ->
223-
incr count;
224239
let pc', args' = resolve_rec (Addr.Set.add pc visited) cont in
225240
let s = Subst.from_map (Subst.build_mapping params args) in
226241
pc', List.map ~f:s args'
227242
| None -> cont
228243
in
229-
let resolve cont = resolve_rec Addr.Set.empty cont in
244+
let resolve cont =
245+
let cont' = resolve_rec Addr.Set.empty cont in
246+
if not (Code.cont_equal cont cont') then st.block_shortcut <- st.block_shortcut + 1;
247+
cont'
248+
in
230249
Addr.Map.iter
231250
(fun pc block ->
232251
match block with
@@ -241,7 +260,7 @@ let remove_empty_blocks ~live_vars (p : Code.program) : Code.program =
241260
used as argument to the continuation *)
242261
if
243262
List.for_all
244-
~f:(fun x -> live_vars.(Var.idx x) = 1 && Var.Set.mem x args)
263+
~f:(fun x -> st.live.(Var.idx x) = 1 && Var.Set.mem x args)
245264
params
246265
then Hashtbl.add shortcuts pc (params, cont)
247266
| _ -> ())
@@ -258,20 +277,19 @@ let remove_empty_blocks ~live_vars (p : Code.program) : Code.program =
258277
let cont1' = resolve cont1 in
259278
let cont2' = resolve cont2 in
260279
if Code.cont_equal cont1' cont2'
261-
then Branch cont1'
262-
else Cond (x, resolve cont1, resolve cont2)
280+
then (
281+
st.cond_to_branch <- st.cond_to_branch + 1;
282+
Branch cont1')
283+
else Cond (x, cont1', cont2')
263284
| Switch (x, a1) -> Switch (x, Array.map ~f:resolve a1)
264285
| Pushtrap (cont1, x, cont2) -> Pushtrap (resolve cont1, x, resolve cont2)
265286
| Poptrap cont -> Poptrap (resolve cont)
266287
| Return _ | Raise _ | Stop -> branch)
267288
})
268289
p.blocks
269290
in
270-
let p = remove_unused_blocks { p with blocks } in
271-
if times () then Format.eprintf " dead code elim. empty blocks: %a@." Timer.print t;
272-
if stats () then Format.eprintf "Stats - dead code empty blocks: %d@." !count;
273-
if debug_stats ()
274-
then Code.check_updates ~name:"emptyblock" previous_p p ~updates:!count;
291+
let p, deleted_blocks = remove_unused_blocks' { p with blocks } in
292+
st.deleted_blocks <- deleted_blocks;
275293
p
276294

277295
let f ({ blocks; _ } as p : Code.program) =
@@ -310,53 +328,60 @@ let f ({ blocks; _ } as p : Code.program) =
310328
; deleted_instrs = 0
311329
; deleted_blocks = 0
312330
; deleted_params = 0
331+
; block_shortcut = 0
332+
; cond_to_branch = 0
313333
}
314334
in
315335
mark_reachable st p.start;
316336
if debug () then Print.program Format.err_formatter (fun pc xi -> annot st pc xi) p;
317337
let all_blocks = blocks in
318338
let blocks =
319-
Addr.Map.filter_map
339+
Addr.Map.mapi
320340
(fun pc block ->
321341
if not (BitSet.mem st.reachable_blocks pc)
322-
then (
323-
st.deleted_blocks <- st.deleted_blocks + 1;
324-
None)
342+
then block
325343
else
326-
Some
327-
{ params = List.filter block.params ~f:(fun x -> st.live.(Var.idx x) > 0)
328-
; body =
329-
List.fold_left block.body ~init:[] ~f:(fun acc i ->
330-
match i, acc with
331-
| Event _, Event _ :: prev ->
332-
(* Avoid consecutive events (keep just the last one) *)
333-
i :: prev
334-
| _ ->
335-
if live_instr st i
336-
then filter_closure all_blocks st i :: acc
337-
else (
338-
st.deleted_instrs <- st.deleted_instrs + 1;
339-
acc))
340-
|> List.rev
341-
; branch = filter_live_last all_blocks st block.branch
342-
})
344+
{ params = List.filter block.params ~f:(fun x -> st.live.(Var.idx x) > 0)
345+
; body =
346+
List.fold_left block.body ~init:[] ~f:(fun acc i ->
347+
match i, acc with
348+
| Event _, Event _ :: prev ->
349+
(* Avoid consecutive events (keep just the last one) *)
350+
i :: prev
351+
| _ ->
352+
if live_instr st i
353+
then filter_closure all_blocks st i :: acc
354+
else (
355+
st.deleted_instrs <- st.deleted_instrs + 1;
356+
acc))
357+
|> List.rev
358+
; branch = filter_live_last all_blocks st block.branch
359+
})
343360
blocks
344361
in
345362
let p = { p with blocks } in
346-
let p = remove_empty_blocks ~live_vars:st.live p in
363+
let p = remove_empty_blocks st p in
347364
if times () then Format.eprintf " dead code elim.: %a@." Timer.print t;
348365
if stats ()
349366
then
350367
Format.eprintf
351-
"Stats - dead code: deleted %d instructions, %d blocks, %d parameters@."
368+
"Stats - dead code: deleted %d instructions, %d blocks, %d parameters, %d \
369+
branches, %d conds@."
352370
st.deleted_instrs
353371
st.deleted_blocks
354-
st.deleted_params;
372+
st.deleted_params
373+
st.block_shortcut
374+
st.cond_to_branch;
355375
if debug_stats ()
356376
then
357377
Code.check_updates
358378
~name:"deadcode"
359379
previous_p
360380
p
361-
~updates:(st.deleted_instrs + st.deleted_blocks + st.deleted_params);
381+
~updates:
382+
(st.deleted_instrs
383+
+ st.deleted_blocks
384+
+ st.deleted_params
385+
+ st.block_shortcut
386+
+ st.cond_to_branch);
362387
p, st.live

compiler/lib/deadcode.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,4 @@ type variable_uses =
2323

2424
val f : Code.program -> Code.program * variable_uses
2525

26-
val remove_unused_blocks : Code.program -> Code.program
26+
val remove_unused_blocks : Code.program -> Code.program * int

compiler/lib/driver.ml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,16 +142,19 @@ let print p =
142142
if debug () then Code.Print.program Format.err_formatter (fun _ _ -> "") p;
143143
p
144144

145+
let stats = Debug.find "stats"
146+
145147
let rec loop max name round i (p : 'a) : 'a =
146-
if times () then Format.eprintf "%s#%d...@." name i;
148+
let debug = times () || stats () in
149+
if debug then Format.eprintf "%s#%d...@." name i;
147150
let p' = round p in
148151
if i >= max
149152
then (
150-
if times () then Format.eprintf "%s#%d: couldn't reach fix point.@." name i;
153+
if debug then Format.eprintf "%s#%d: couldn't reach fix point.@." name i;
151154
p')
152155
else if Code.equal p' p
153156
then (
154-
if times () then Format.eprintf "%s#%d: fix-point reached.@." name i;
157+
if debug then Format.eprintf "%s#%d: fix-point reached.@." name i;
155158
p')
156159
else loop max name round (i + 1) p'
157160

compiler/lib/eval.ml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -791,7 +791,6 @@ let f info p =
791791
p.blocks
792792
in
793793
let blocks = drop_exception_handler drop_count blocks in
794-
let p = Deadcode.remove_unused_blocks { p with blocks } in
795794
if times () then Format.eprintf " eval: %a@." Timer.print t;
796795
if stats ()
797796
then
@@ -802,11 +801,13 @@ let f info p =
802801
!inline_constant
803802
!drop_count
804803
!update_branch;
804+
let p, deadblock = Deadcode.remove_unused_blocks { p with blocks } in
805805
if debug_stats ()
806806
then
807807
Code.check_updates
808808
~name:"eval"
809809
previous_p
810810
p
811-
~updates:(!update_count + !inline_constant + !drop_count + !update_branch);
811+
~updates:
812+
(deadblock + !update_count + !inline_constant + !drop_count + !update_branch);
812813
p

compiler/lib/inline.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -341,10 +341,10 @@ let f p live_vars =
341341
(closures, p)
342342
in
343343
(* Inlining a raising function can result in empty blocks *)
344-
let p = Deadcode.remove_unused_blocks p in
345344
if times () then Format.eprintf " inlining: %a@." Timer.print t;
346345
if stats () then Format.eprintf "Stats - inline: %d optimizations@." !inline_count;
346+
let p, deadblock = Deadcode.remove_unused_blocks p in
347347
if debug_stats ()
348-
then Code.check_updates ~name:"inline" previous_p p ~updates:!inline_count;
348+
then Code.check_updates ~name:"inline" previous_p p ~updates:(!inline_count + deadblock);
349349
Code.invariant p;
350350
p

compiler/lib/specialize_js.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,5 +475,5 @@ let f_once_after p =
475475
(fun block -> { block with Code.body = List.map block.body ~f })
476476
p.blocks
477477
in
478-
Deadcode.remove_unused_blocks { p with blocks }
478+
fst (Deadcode.remove_unused_blocks { p with blocks })
479479
else p

dune-workspace

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@
77
(runtest_alias runtest-wasm))
88
(js_of_ocaml
99
;; enable for debugging
10-
;; (flags (:standard --debug stats-debug))
10+
;; (flags (:standard --debug stats-debug --debug invariant))
1111
(runtest_alias runtest-js))))

0 commit comments

Comments
 (0)