@@ -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