From 3ff8867e5785bf7ea74bd60b4cdeacf040da7c8c Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 26 Oct 2018 06:20:08 -0700 Subject: [PATCH] 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. --- cranelift/wasmtests/br_table.wat | 30 ++++++++++++++++++++++++++++++ lib/wasm/src/code_translator.rs | 17 +++++++++-------- 2 files changed, 39 insertions(+), 8 deletions(-) create mode 100644 cranelift/wasmtests/br_table.wat diff --git a/cranelift/wasmtests/br_table.wat b/cranelift/wasmtests/br_table.wat new file mode 100644 index 0000000000..75444fa49c --- /dev/null +++ b/cranelift/wasmtests/br_table.wat @@ -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)) + ) + ) +) diff --git a/lib/wasm/src/code_translator.rs b/lib/wasm/src/code_translator.rs index e7a62b65fe..8d5fee979a 100644 --- a/lib/wasm/src/code_translator.rs +++ b/lib/wasm/src/code_translator.rs @@ -307,15 +307,16 @@ pub fn translate_operator( }; data.push_entry(branch_ebb); } - let jt = builder.create_jump_table(data); - let default_ebb = { - let i = state.control_stack.len() - 1 - (default as usize); - let frame = &mut state.control_stack[i]; - frame.set_branched_to_exit(); - frame.br_destination() + let default_branch_ebb = match dest_ebb_map.entry(default as usize) { + hash_map::Entry::Occupied(entry) => *entry.get(), + hash_map::Entry::Vacant(entry) => { + let ebb = builder.create_ebb(); + dest_ebb_sequence.push((default as usize, ebb)); + *entry.insert(ebb) + } }; - dest_ebb_sequence.push((default as usize, default_ebb)); - builder.ins().br_table(val, default_ebb, jt); + let jt = builder.create_jump_table(data); + builder.ins().br_table(val, default_branch_ebb, jt); for (depth, dest_ebb) in dest_ebb_sequence { builder.switch_to_block(dest_ebb); builder.seal_block(dest_ebb);