pub fn unreachable_code() -> TimingToken
Expand description

Remove unreachable blocks

Examples found in repository?
src/unreachable_code.rs (line 20)
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
pub fn eliminate_unreachable_code(
    func: &mut ir::Function,
    cfg: &mut ControlFlowGraph,
    domtree: &DominatorTree,
) {
    let _tt = timing::unreachable_code();
    let mut pos = FuncCursor::new(func);
    while let Some(block) = pos.next_block() {
        if domtree.is_reachable(block) {
            continue;
        }

        trace!("Eliminating unreachable {}", block);
        // Move the cursor out of the way and make sure the next lop iteration goes to the right
        // block.
        pos.prev_block();

        // Remove all instructions from `block`.
        while let Some(inst) = pos.func.layout.first_inst(block) {
            trace!(" - {}", pos.func.dfg.display_inst(inst));
            pos.func.layout.remove_inst(inst);
        }

        // Once the block is completely empty, we can update the CFG which removes it from any
        // predecessor lists.
        cfg.recompute_block(pos.func, block);

        // Finally, remove the block from the layout.
        pos.func.layout.remove_block(block);
    }

    // Remove all jumptable block-list contents that refer to unreachable
    // blocks; the jumptable itself must have been unused (or used only in an
    // unreachable block) if so. Note that we are not necessarily removing *all*
    // unused jumptables, because that would require computing their
    // reachability as well; we are just removing enough to clean up references
    // to deleted blocks.
    for jt_data in func.jump_tables.values_mut() {
        let invalid_ref = jt_data.iter().any(|block| !domtree.is_reachable(*block));
        if invalid_ref {
            jt_data.clear();
        }
    }
}