Move default blocks into jump tables (#5756)
Move the default block off of the br_table instrution, and into the JumpTable that it references.
This commit is contained in:
@@ -129,9 +129,7 @@ impl<'short, 'long> InstBuilderBase<'short> for FuncInstBuilder<'short, 'long> {
|
||||
}
|
||||
}
|
||||
|
||||
ir::InstructionData::BranchTable {
|
||||
table, destination, ..
|
||||
} => {
|
||||
ir::InstructionData::BranchTable { table, .. } => {
|
||||
// Unlike all other jumps/branches, jump tables are
|
||||
// capable of having the same successor appear
|
||||
// multiple times, so we must deduplicate.
|
||||
@@ -144,9 +142,12 @@ impl<'short, 'long> InstBuilderBase<'short> for FuncInstBuilder<'short, 'long> {
|
||||
.jump_tables
|
||||
.get(*table)
|
||||
.expect("you are referencing an undeclared jump table")
|
||||
.iter()
|
||||
.filter(|&dest_block| unique.insert(*dest_block))
|
||||
.all_branches()
|
||||
{
|
||||
if !unique.insert(*dest_block) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Call `declare_block_predecessor` instead of `declare_successor` for
|
||||
// avoiding the borrow checker.
|
||||
self.builder
|
||||
@@ -154,7 +155,6 @@ impl<'short, 'long> InstBuilderBase<'short> for FuncInstBuilder<'short, 'long> {
|
||||
.ssa
|
||||
.declare_block_predecessor(*dest_block, inst);
|
||||
}
|
||||
self.builder.declare_successor(*destination, inst);
|
||||
}
|
||||
|
||||
inst => debug_assert!(!inst.opcode().is_branch()),
|
||||
|
||||
@@ -591,27 +591,18 @@ impl SSABuilder {
|
||||
}
|
||||
None
|
||||
}
|
||||
InstructionData::BranchTable {
|
||||
table: jt,
|
||||
destination,
|
||||
..
|
||||
} => {
|
||||
InstructionData::BranchTable { table: jt, .. } => {
|
||||
// In the case of a jump table, the situation is tricky because br_table doesn't
|
||||
// support arguments. We have to split the critical edge.
|
||||
let middle_block = dfg.blocks.add();
|
||||
func.stencil.layout.append_block(middle_block);
|
||||
|
||||
let table = &mut dfg.jump_tables[*jt];
|
||||
for block in table.iter_mut() {
|
||||
for block in dfg.jump_tables[*jt].all_branches_mut() {
|
||||
if *block == dest_block {
|
||||
*block = middle_block;
|
||||
}
|
||||
}
|
||||
|
||||
if *destination == dest_block {
|
||||
*destination = middle_block;
|
||||
}
|
||||
|
||||
let mut cur = FuncCursor::new(func).at_bottom(middle_block);
|
||||
let middle_jump_inst = cur.ins().jump(dest_block, &[val]);
|
||||
Some((middle_block, middle_jump_inst))
|
||||
@@ -1001,9 +992,6 @@ mod tests {
|
||||
let block0 = func.dfg.make_block();
|
||||
let block1 = func.dfg.make_block();
|
||||
let block2 = func.dfg.make_block();
|
||||
let mut jump_table = JumpTableData::new();
|
||||
jump_table.push_entry(block2);
|
||||
jump_table.push_entry(block1);
|
||||
{
|
||||
let mut cur = FuncCursor::new(&mut func);
|
||||
cur.insert_block(block0);
|
||||
@@ -1022,9 +1010,10 @@ mod tests {
|
||||
ssa.def_var(x_var, x1, block0);
|
||||
ssa.use_var(&mut func, x_var, I32, block0).0;
|
||||
let br_table = {
|
||||
let jump_table = JumpTableData::new(block2, vec![block2, block1]);
|
||||
let jt = func.create_jump_table(jump_table);
|
||||
let mut cur = FuncCursor::new(&mut func).at_bottom(block0);
|
||||
cur.ins().br_table(x1, block2, jt)
|
||||
cur.ins().br_table(x1, jt)
|
||||
};
|
||||
|
||||
// block1
|
||||
|
||||
@@ -220,7 +220,7 @@ impl Switch {
|
||||
"Jump tables bigger than 2^32-1 are not yet supported"
|
||||
);
|
||||
|
||||
let jt_data = JumpTableData::with_blocks(Vec::from(blocks));
|
||||
let jt_data = JumpTableData::new(otherwise, Vec::from(blocks));
|
||||
let jump_table = bx.create_jump_table(jt_data);
|
||||
|
||||
let discr = if first_index == 0 {
|
||||
@@ -256,7 +256,7 @@ impl Switch {
|
||||
_ => discr,
|
||||
};
|
||||
|
||||
bx.ins().br_table(discr, otherwise, jump_table);
|
||||
bx.ins().br_table(discr, jump_table);
|
||||
}
|
||||
|
||||
/// Build the switch
|
||||
|
||||
Reference in New Issue
Block a user