Split the default edge of a br_table.

When splitting critical edges for a br_table to handle arguments being
passed, split the default edge along with the normal table edges.
This commit is contained in:
Dan Gohman
2018-10-26 06:20:08 -07:00
committed by Benjamin Bouvier
parent a5cad9a748
commit 3ff8867e57
2 changed files with 39 additions and 8 deletions

View File

@@ -0,0 +1,30 @@
(module
(func (result i32)
(block (result i32)
(block (result i32)
(block (result i32)
(br_table 0 1 2 3 (i32.const 42) (i32.const 0))
)
)
)
)
(func (result i32)
(block (result i32)
(block (result i32)
(block (result i32)
(br_table 3 2 1 0 (i32.const 42) (i32.const 0))
)
)
)
)
(func (result i32)
(block (result i32)
(br_table 0 0 1 1 (i32.const 42) (i32.const 0))
)
)
(func (result i32)
(block (result i32)
(br_table 1 1 0 0 (i32.const 42) (i32.const 0))
)
)
)

View File

@@ -307,15 +307,16 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
}; };
data.push_entry(branch_ebb); data.push_entry(branch_ebb);
} }
let jt = builder.create_jump_table(data); let default_branch_ebb = match dest_ebb_map.entry(default as usize) {
let default_ebb = { hash_map::Entry::Occupied(entry) => *entry.get(),
let i = state.control_stack.len() - 1 - (default as usize); hash_map::Entry::Vacant(entry) => {
let frame = &mut state.control_stack[i]; let ebb = builder.create_ebb();
frame.set_branched_to_exit(); dest_ebb_sequence.push((default as usize, ebb));
frame.br_destination() *entry.insert(ebb)
}
}; };
dest_ebb_sequence.push((default as usize, default_ebb)); let jt = builder.create_jump_table(data);
builder.ins().br_table(val, default_ebb, jt); builder.ins().br_table(val, default_branch_ebb, jt);
for (depth, dest_ebb) in dest_ebb_sequence { for (depth, dest_ebb) in dest_ebb_sequence {
builder.switch_to_block(dest_ebb); builder.switch_to_block(dest_ebb);
builder.seal_block(dest_ebb); builder.seal_block(dest_ebb);