cranelift_codegen/
unreachable_code.rs1use cranelift_entity::EntitySet;
4
5use crate::cursor::{Cursor, FuncCursor};
6use crate::flowgraph::ControlFlowGraph;
7use crate::timing;
8use crate::{ir, trace};
9
10pub fn eliminate_unreachable_code(
15 func: &mut ir::Function,
16 cfg: &mut ControlFlowGraph,
17 is_reachable: impl Fn(ir::Block) -> bool,
18) {
19 let _tt = timing::unreachable_code();
20 let mut pos = FuncCursor::new(func);
21 let mut used_tables = EntitySet::with_capacity(pos.func.stencil.dfg.jump_tables.len());
22 let mut used_exception_tables =
23 EntitySet::with_capacity(pos.func.stencil.dfg.exception_tables.len());
24 while let Some(block) = pos.next_block() {
25 if is_reachable(block) {
26 let inst = pos.func.layout.last_inst(block).unwrap();
27 match pos.func.dfg.insts[inst] {
28 ir::InstructionData::BranchTable { table, .. } => {
29 used_tables.insert(table);
30 }
31 ir::InstructionData::TryCall { exception, .. }
32 | ir::InstructionData::TryCallIndirect { exception, .. } => {
33 used_exception_tables.insert(exception);
34 }
35 _ => (),
36 }
37 continue;
38 }
39
40 trace!("Eliminating unreachable {}", block);
41 pos.prev_block();
44
45 while let Some(inst) = pos.func.layout.first_inst(block) {
47 trace!(" - {}", pos.func.dfg.display_inst(inst));
48 pos.func.layout.remove_inst(inst);
49 }
50
51 cfg.recompute_block(pos.func, block);
54
55 pos.func.layout.remove_block(block);
57 }
58
59 for (table, jt_data) in func.stencil.dfg.jump_tables.iter_mut() {
60 if !used_tables.contains(table) {
61 jt_data.clear();
62 }
63 }
64
65 for (exception, exception_data) in func.stencil.dfg.exception_tables.iter_mut() {
66 if !used_exception_tables.contains(exception) {
67 exception_data.clear();
68 }
69 }
70}