let phase2 f ~info =
let n_blocks = Array.length f.body in
let new_body = Array.make n_blocks [] in
for i = 0 to n_blocks - 1 do
let body_instrs = convert_block ~f ~info i in
let phi_assignments = make_phi_assigns info.(i).phi_assignments_at_bottom in
let main, last_branch = separate_last_branch body_instrs in
let last_branch =
if last_branch = [] && i < n_blocks - 1 && info.(i + 1).trampoline_blocks <> []
then
[make_il0 (IL0stmtGoto(label_direct (i + 1)))]
else
last_branch
in
let phi = make_phi_assigns info.(i).phi_assignments_at_bottom in
let make_trampoline from assigns =
(make_il0 (IL0stmtLabel (label_trampoline from i))) ::
[make_phi_assigns assigns]
in
let trampoline_instrs =
let rec iter = function
[] -> []
| [from, assigns] -> make_trampoline from assigns
| (from, assigns)::tl ->
make_trampoline from assigns @ (make_il0 (IL0stmtGoto (label_direct i)) :: iter tl)
in
iter info.(i).trampoline_blocks
in
let main_label = [make_il0 (IL0stmtLabel (label_direct i))] in
new_body.(i) <- trampoline_instrs @ main_label @ main @ phi :: last_branch
done;
let l = Array.fold_right
(fun l r -> l @ r) new_body []
in
enclose_sequence l