@@ -49,6 +49,8 @@ type t =
49
49
; mutable deleted_instrs : int
50
50
; mutable deleted_blocks : int
51
51
; mutable deleted_params : int
52
+ ; mutable block_shortcut : int
53
+ ; mutable cond_to_branch : int
52
54
}
53
55
54
56
(* ***)
@@ -185,10 +187,27 @@ let annot st pc xi =
185
187
186
188
(* ***)
187
189
188
- let remove_unused_blocks p =
190
+ let remove_unused_blocks' p =
189
191
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
191
204
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
192
211
(* ***)
193
212
194
213
let rec add_arg_dep defs params args =
@@ -209,24 +228,24 @@ let empty_body b =
209
228
| [] | [ Event _ ] -> true
210
229
| _ -> false
211
230
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 =
216
232
let shortcuts = Hashtbl. create 16 in
217
233
let rec resolve_rec visited ((pc , args ) as cont ) =
218
234
if Addr.Set. mem pc visited
219
235
then cont
220
236
else
221
237
match Hashtbl. find_opt shortcuts pc with
222
238
| Some (params , cont ) ->
223
- incr count;
224
239
let pc', args' = resolve_rec (Addr.Set. add pc visited) cont in
225
240
let s = Subst. from_map (Subst. build_mapping params args) in
226
241
pc', List. map ~f: s args'
227
242
| None -> cont
228
243
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
230
249
Addr.Map. iter
231
250
(fun pc block ->
232
251
match block with
@@ -241,7 +260,7 @@ let remove_empty_blocks ~live_vars (p : Code.program) : Code.program =
241
260
used as argument to the continuation *)
242
261
if
243
262
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)
245
264
params
246
265
then Hashtbl. add shortcuts pc (params, cont)
247
266
| _ -> () )
@@ -258,20 +277,19 @@ let remove_empty_blocks ~live_vars (p : Code.program) : Code.program =
258
277
let cont1' = resolve cont1 in
259
278
let cont2' = resolve cont2 in
260
279
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')
263
284
| Switch (x , a1 ) -> Switch (x, Array. map ~f: resolve a1)
264
285
| Pushtrap (cont1 , x , cont2 ) -> Pushtrap (resolve cont1, x, resolve cont2)
265
286
| Poptrap cont -> Poptrap (resolve cont)
266
287
| Return _ | Raise _ | Stop -> branch)
267
288
})
268
289
p.blocks
269
290
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;
275
293
p
276
294
277
295
let f ({ blocks; _ } as p : Code.program ) =
@@ -310,53 +328,60 @@ let f ({ blocks; _ } as p : Code.program) =
310
328
; deleted_instrs = 0
311
329
; deleted_blocks = 0
312
330
; deleted_params = 0
331
+ ; block_shortcut = 0
332
+ ; cond_to_branch = 0
313
333
}
314
334
in
315
335
mark_reachable st p.start;
316
336
if debug () then Print. program Format. err_formatter (fun pc xi -> annot st pc xi) p;
317
337
let all_blocks = blocks in
318
338
let blocks =
319
- Addr.Map. filter_map
339
+ Addr.Map. mapi
320
340
(fun pc block ->
321
341
if not (BitSet. mem st.reachable_blocks pc)
322
- then (
323
- st.deleted_blocks < - st.deleted_blocks + 1 ;
324
- None )
342
+ then block
325
343
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
+ })
343
360
blocks
344
361
in
345
362
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
347
364
if times () then Format. eprintf " dead code elim.: %a@." Timer. print t;
348
365
if stats ()
349
366
then
350
367
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@."
352
370
st.deleted_instrs
353
371
st.deleted_blocks
354
- st.deleted_params;
372
+ st.deleted_params
373
+ st.block_shortcut
374
+ st.cond_to_branch;
355
375
if debug_stats ()
356
376
then
357
377
Code. check_updates
358
378
~name: " deadcode"
359
379
previous_p
360
380
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);
362
387
p, st.live
0 commit comments