Skip to content

Commit e9c0562

Browse files
authored
Keep reachable jump tables (#5721)
Instead of identifying unused branch tables by looking for unused blocks inside of them, track used branch tables while traversing reachable blocks. This introduces an extra allocation of an EntitySet to track the used jump tables, but as those are few and this function runs once per ir::Function, the allocation seems reasonable.
1 parent 65c1f65 commit e9c0562

File tree

1 file changed

+9
-9
lines changed

1 file changed

+9
-9
lines changed

cranelift/codegen/src/unreachable_code.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! Unreachable code elimination.
22
3+
use cranelift_entity::EntitySet;
4+
35
use crate::cursor::{Cursor, FuncCursor};
46
use crate::dominator_tree::DominatorTree;
57
use crate::flowgraph::ControlFlowGraph;
@@ -19,8 +21,13 @@ pub fn eliminate_unreachable_code(
1921
) {
2022
let _tt = timing::unreachable_code();
2123
let mut pos = FuncCursor::new(func);
24+
let mut used_tables = EntitySet::with_capacity(pos.func.jump_tables.len());
2225
while let Some(block) = pos.next_block() {
2326
if domtree.is_reachable(block) {
27+
let inst = pos.func.layout.last_inst(block).unwrap();
28+
if let ir::InstructionData::BranchTable { table, .. } = pos.func.dfg.insts[inst] {
29+
used_tables.insert(table);
30+
}
2431
continue;
2532
}
2633

@@ -43,15 +50,8 @@ pub fn eliminate_unreachable_code(
4350
pos.func.layout.remove_block(block);
4451
}
4552

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

0 commit comments

Comments
 (0)