Don't special-case br_table with an empty table.

Empty br_table tables are very uncommon (they're easy for wasm producers to
optimize away), so we don't need to special-case them.
This commit is contained in:
Dan Gohman
2017-08-30 09:21:58 -07:00
parent 4ccd21ba94
commit a0a3401ef1

View File

@@ -523,17 +523,15 @@ fn translate_operator(op: &Operator,
if jump_args_count == 0 { if jump_args_count == 0 {
// No jump arguments // No jump arguments
let val = stack.pop().unwrap(); let val = stack.pop().unwrap();
if depths.len() > 0 { let jt = builder.create_jump_table();
let jt = builder.create_jump_table(); for (index, depth) in depths.iter().enumerate() {
for (index, depth) in depths.iter().enumerate() { let i = control_stack.len() - 1 - (*depth as usize);
let i = control_stack.len() - 1 - (*depth as usize); let frame = &mut control_stack[i];
let frame = &mut control_stack[i]; let ebb = frame.br_destination();
let ebb = frame.br_destination(); builder.insert_jump_table_entry(jt, index, ebb);
builder.insert_jump_table_entry(jt, index, ebb); frame.set_reachable();
frame.set_reachable();
}
builder.ins().br_table(val, jt);
} }
builder.ins().br_table(val, jt);
let i = control_stack.len() - 1 - (default as usize); let i = control_stack.len() - 1 - (default as usize);
let frame = &mut control_stack[i]; let frame = &mut control_stack[i];
let ebb = frame.br_destination(); let ebb = frame.br_destination();
@@ -546,44 +544,36 @@ fn translate_operator(op: &Operator,
let val = stack.pop().unwrap(); let val = stack.pop().unwrap();
let cut_index = stack.len() - jump_args_count; let cut_index = stack.len() - jump_args_count;
let jump_args = stack.split_off(cut_index); let jump_args = stack.split_off(cut_index);
if depths.len() > 0 { let jt = builder.create_jump_table();
let jt = builder.create_jump_table(); let dest_ebbs: HashMap<usize, Ebb> = depths
let dest_ebbs: HashMap<usize, Ebb> = depths .iter()
.iter() .enumerate()
.enumerate() .fold(HashMap::new(), |mut acc, (index, &depth)| {
.fold(HashMap::new(), |mut acc, (index, &depth)| { if acc.get(&(depth as usize)).is_none() {
if acc.get(&(depth as usize)).is_none() { let branch_ebb = builder.create_ebb();
let branch_ebb = builder.create_ebb();
builder.insert_jump_table_entry(jt, index, branch_ebb);
acc.insert(depth as usize, branch_ebb);
return acc;
};
let branch_ebb = acc.get(&(depth as usize)).unwrap().clone();
builder.insert_jump_table_entry(jt, index, branch_ebb); builder.insert_jump_table_entry(jt, index, branch_ebb);
acc acc.insert(depth as usize, branch_ebb);
}); return acc;
builder.ins().br_table(val, jt); };
let default_ebb = control_stack[control_stack.len() - 1 - (default as usize)] let branch_ebb = acc.get(&(depth as usize)).unwrap().clone();
.br_destination(); builder.insert_jump_table_entry(jt, index, branch_ebb);
builder.ins().jump(default_ebb, jump_args.as_slice()); acc
stack.extend(jump_args.clone()); });
for (depth, dest_ebb) in dest_ebbs { builder.ins().br_table(val, jt);
builder.switch_to_block(dest_ebb, &[]); let default_ebb = control_stack[control_stack.len() - 1 - (default as usize)]
builder.seal_block(dest_ebb); .br_destination();
let i = control_stack.len() - 1 - (depth as usize); builder.ins().jump(default_ebb, jump_args.as_slice());
let frame = &mut control_stack[i]; stack.extend(jump_args.clone());
let real_dest_ebb = frame.br_destination(); for (depth, dest_ebb) in dest_ebbs {
builder.ins().jump(real_dest_ebb, jump_args.as_slice()); builder.switch_to_block(dest_ebb, &[]);
frame.set_reachable(); builder.seal_block(dest_ebb);
} let i = control_stack.len() - 1 - (depth as usize);
state.real_unreachable_stack_depth = 1 + min_depth as usize; let frame = &mut control_stack[i];
} else { let real_dest_ebb = frame.br_destination();
let ebb = control_stack[control_stack.len() - 1 - (default as usize)] builder.ins().jump(real_dest_ebb, jump_args.as_slice());
.br_destination(); frame.set_reachable();
builder.ins().jump(ebb, jump_args.as_slice());
stack.extend(jump_args);
state.real_unreachable_stack_depth = 1 + min_depth as usize;
} }
state.real_unreachable_stack_depth = 1 + min_depth as usize;
} }
} }
Operator::Return => { Operator::Return => {