Path: blob/main/cranelift/codegen/src/unreachable_code.rs
1693 views
//! Unreachable code elimination.12use cranelift_entity::EntitySet;34use crate::cursor::{Cursor, FuncCursor};5use crate::dominator_tree::DominatorTree;6use crate::flowgraph::ControlFlowGraph;7use crate::timing;8use crate::{ir, trace};910/// Eliminate unreachable code.11///12/// This pass deletes whole blocks that can't be reached from the entry block. It does not delete13/// individual instructions whose results are unused.14///15/// The reachability analysis is performed by the dominator tree analysis.16pub fn eliminate_unreachable_code(17func: &mut ir::Function,18cfg: &mut ControlFlowGraph,19domtree: &DominatorTree,20) {21let _tt = timing::unreachable_code();22let mut pos = FuncCursor::new(func);23let mut used_tables = EntitySet::with_capacity(pos.func.stencil.dfg.jump_tables.len());24let mut used_exception_tables =25EntitySet::with_capacity(pos.func.stencil.dfg.exception_tables.len());26while let Some(block) = pos.next_block() {27if domtree.is_reachable(block) {28let inst = pos.func.layout.last_inst(block).unwrap();29match pos.func.dfg.insts[inst] {30ir::InstructionData::BranchTable { table, .. } => {31used_tables.insert(table);32}33ir::InstructionData::TryCall { exception, .. }34| ir::InstructionData::TryCallIndirect { exception, .. } => {35used_exception_tables.insert(exception);36}37_ => (),38}39continue;40}4142trace!("Eliminating unreachable {}", block);43// Move the cursor out of the way and make sure the next lop iteration goes to the right44// block.45pos.prev_block();4647// Remove all instructions from `block`.48while let Some(inst) = pos.func.layout.first_inst(block) {49trace!(" - {}", pos.func.dfg.display_inst(inst));50pos.func.layout.remove_inst(inst);51}5253// Once the block is completely empty, we can update the CFG which removes it from any54// predecessor lists.55cfg.recompute_block(pos.func, block);5657// Finally, remove the block from the layout.58pos.func.layout.remove_block(block);59}6061for (table, jt_data) in func.stencil.dfg.jump_tables.iter_mut() {62if !used_tables.contains(table) {63jt_data.clear();64}65}6667for (exception, exception_data) in func.stencil.dfg.exception_tables.iter_mut() {68if !used_exception_tables.contains(exception) {69exception_data.clear();70}71}72}737475