Skip to content

Commit f8962c9

Browse files
committed
Simplify nested conditionals
When a conditional is simplified, it might be possible to simply previous conditionals as well. Do this in one pass.
1 parent 48e11f3 commit f8962c9

File tree

1 file changed

+62
-36
lines changed

1 file changed

+62
-36
lines changed

compiler/lib/deadcode.ml

Lines changed: 62 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -349,28 +349,29 @@ let remove_empty_blocks st (p : Code.program) : Code.program =
349349
if not (Code.cont_equal cont cont') then st.block_shortcut <- st.block_shortcut + 1;
350350
cont'
351351
in
352-
Addr.Map.iter
353-
(fun pc block ->
354-
match block with
355-
| { params; body; branch = Branch cont; _ } when empty_body body ->
356-
let args =
357-
List.fold_left
358-
~f:(fun args x -> Var.Set.add x args)
359-
~init:Var.Set.empty
360-
(snd cont)
361-
in
362-
(* We can skip an empty block if its parameters are only
352+
let register_block_if_empty pc block =
353+
match block with
354+
| { params; body; branch = Branch cont; _ } when empty_body body ->
355+
let args =
356+
List.fold_left
357+
~f:(fun args x -> Var.Set.add x args)
358+
~init:Var.Set.empty
359+
(snd cont)
360+
in
361+
(* We can skip an empty block if its parameters are only
363362
used as argument to the continuation *)
364-
if
365-
List.for_all
366-
~f:(fun x -> st.live.(Var.idx x) = 1 && Var.Set.mem x args)
367-
params
368-
then Addr.Hashtbl.add shortcuts pc (params, cont)
369-
| _ -> ())
370-
p.blocks;
363+
if List.for_all ~f:(fun x -> st.live.(Var.idx x) = 1 && Var.Set.mem x args) params
364+
then Addr.Hashtbl.add shortcuts pc (params, cont)
365+
| _ -> ()
366+
in
367+
Addr.Map.iter register_block_if_empty p.blocks;
368+
let addr_map_rev_fold f m acc =
369+
let l = Addr.Map.fold (fun pc block rem -> (pc, block) :: rem) m [] in
370+
List.fold_left ~f l ~init:acc
371+
in
371372
let blocks =
372-
Addr.Map.fold
373-
(fun pc block blocks ->
373+
addr_map_rev_fold
374+
(fun blocks (pc, block) ->
374375
if
375376
match block.branch with
376377
| Branch (pc, _) | Poptrap (pc, _) -> not (Addr.Hashtbl.mem shortcuts pc)
@@ -383,22 +384,47 @@ let remove_empty_blocks st (p : Code.program) : Code.program =
383384
else
384385
Addr.Map.add
385386
pc
386-
{ block with
387-
branch =
388-
(let branch = block.branch in
389-
match branch with
390-
| Branch cont -> Branch (resolve cont)
391-
| Cond (x, cont1, cont2) ->
392-
let cont1' = resolve cont1 in
393-
let cont2' = resolve cont2 in
394-
if Code.cont_equal cont1' cont2'
395-
then Branch cont1'
396-
else Cond (x, cont1', cont2')
397-
| Switch (x, a1) -> Switch (x, Array.map ~f:resolve a1)
398-
| Pushtrap (cont1, x, cont2) -> Pushtrap (resolve cont1, x, resolve cont2)
399-
| Poptrap cont -> Poptrap (resolve cont)
400-
| Return _ | Raise _ | Stop -> assert false)
401-
}
387+
(match block with
388+
| { body; branch = Cond (x, cont1, cont2); _ } ->
389+
let cont1' = resolve cont1 in
390+
let cont2' = resolve cont2 in
391+
if Code.cont_equal cont1' cont2'
392+
then (
393+
let decr_usage x = st.live.(Var.idx x) <- st.live.(Var.idx x) - 1 in
394+
decr_usage x;
395+
let body =
396+
if List.compare_length_with body ~len:100 > 0
397+
then body
398+
else
399+
List.fold_right
400+
~f:(fun i rem ->
401+
if live_instr st i
402+
then
403+
match i, rem with
404+
| Event _, Event _ :: _ -> rem
405+
| _ -> i :: rem
406+
else (
407+
Freevars.iter_instr_free_vars decr_usage i;
408+
rem))
409+
block.body
410+
~init:[]
411+
in
412+
let block = { block with body; branch = Branch cont1' } in
413+
register_block_if_empty pc block;
414+
block)
415+
else { block with branch = Cond (x, cont1', cont2') }
416+
| _ ->
417+
{ block with
418+
branch =
419+
(let branch = block.branch in
420+
match branch with
421+
| Branch cont -> Branch (resolve cont)
422+
| Switch (x, a1) -> Switch (x, Array.map ~f:resolve a1)
423+
| Pushtrap (cont1, x, cont2) ->
424+
Pushtrap (resolve cont1, x, resolve cont2)
425+
| Poptrap cont -> Poptrap (resolve cont)
426+
| Cond _ | Return _ | Raise _ | Stop -> assert false)
427+
})
402428
blocks)
403429
p.blocks
404430
p.blocks

0 commit comments

Comments
 (0)