let eliminate_unreachable f =
let length = Array.length f in
let mark = Array.create length false in
let rec visit i =
if not mark.(i) then begin
mark.(i) <- true;
let rec check = function
[] -> visit (i + 1)
| i::l -> match i.il1_t with
IL1stmtDeclAutoScalar _ |
IL1stmtDeclBulk _ |
IL1stmtDefTemp _ |
IL1stmtReadToTemp _ |
IL1stmtWrite _ |
IL1stmtParallel _ -> check l
| IL1stmtIf( _, _, n ) -> visit n; check l
| IL1stmtSwitch( _, jump_table ) ->
List.iter (function _, n -> visit n) jump_table
| IL1stmtGoto n -> visit n
| IL1stmtReturn _ -> ()
| IL1stmtSequence _ -> assert false
in
check f.(i).code
end
in
visit 0;
let rename_table = Array.create length (-1) in
let reverse_table = Array.create length (-1) in
let rename i = rename_table.(i) in
let j = ref 0 in
for i = 0 to length - 1 do
if mark.(i) then begin
rename_table.(i) <- !j;
reverse_table.(!j) <- i;
incr j
end
done;
let new_length = !j in
let rename_code i1 =
let mk i = { i1 with il1_t = i } in
match i1.il1_t with
| IL1stmtIf( v, e, n ) -> mk (IL1stmtIf( v, e, rename n ))
| IL1stmtSwitch( e, jump_table ) ->
mk (IL1stmtSwitch( e, List.map (function c, n -> c, rename n) jump_table ))
| IL1stmtGoto n -> mk (IL1stmtGoto (rename n))
| _ -> i1
in
let rename_basic_block i =
let j = reverse_table.(i) in
{
predecessor = List.map rename f.(j).predecessor;
successor = List.map rename f.(j).successor;
immediate_dominator = f.(j).immediate_dominator;
code = List.map rename_code f.(j).code
}
in
Array.init new_length rename_basic_block