Refactor matches that used to consume BranchInfo (#5734)
Explicitly borrow the instruction data, and use a mutable borrow to avoid rematch.
This commit is contained in:
@@ -351,7 +351,7 @@ impl DominatorTree {
|
|||||||
/// post-order except for the insertion of the new block header at the split point.
|
/// post-order except for the insertion of the new block header at the split point.
|
||||||
fn push_successors(&mut self, func: &Function, block: Block) {
|
fn push_successors(&mut self, func: &Function, block: Block) {
|
||||||
if let Some(inst) = func.layout.last_inst(block) {
|
if let Some(inst) = func.layout.last_inst(block) {
|
||||||
match func.dfg.insts[inst] {
|
match &func.dfg.insts[inst] {
|
||||||
ir::InstructionData::Jump {
|
ir::InstructionData::Jump {
|
||||||
destination: succ, ..
|
destination: succ, ..
|
||||||
} => self.push_if_unseen(succ.block(&func.dfg.value_lists)),
|
} => self.push_if_unseen(succ.block(&func.dfg.value_lists)),
|
||||||
@@ -367,10 +367,10 @@ impl DominatorTree {
|
|||||||
destination: dest,
|
destination: dest,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
for succ in func.jump_tables[jt].iter() {
|
for succ in func.jump_tables[*jt].iter() {
|
||||||
self.push_if_unseen(*succ);
|
self.push_if_unseen(*succ);
|
||||||
}
|
}
|
||||||
self.push_if_unseen(dest);
|
self.push_if_unseen(*dest);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ impl ControlFlowGraph {
|
|||||||
|
|
||||||
fn compute_block(&mut self, func: &Function, block: Block) {
|
fn compute_block(&mut self, func: &Function, block: Block) {
|
||||||
if let Some(inst) = func.layout.last_inst(block) {
|
if let Some(inst) = func.layout.last_inst(block) {
|
||||||
match func.dfg.insts[inst] {
|
match &func.dfg.insts[inst] {
|
||||||
ir::InstructionData::Jump {
|
ir::InstructionData::Jump {
|
||||||
destination: dest, ..
|
destination: dest, ..
|
||||||
} => {
|
} => {
|
||||||
@@ -135,9 +135,9 @@ impl ControlFlowGraph {
|
|||||||
destination: dest,
|
destination: dest,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
self.add_edge(block, inst, dest);
|
self.add_edge(block, inst, *dest);
|
||||||
|
|
||||||
for dest in func.jump_tables[jt].iter() {
|
for dest in func.jump_tables[*jt].iter() {
|
||||||
self.add_edge(block, inst, *dest);
|
self.add_edge(block, inst, *dest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ pub(crate) fn visit_block_succs<F: FnMut(Inst, Block, bool)>(
|
|||||||
mut visit: F,
|
mut visit: F,
|
||||||
) {
|
) {
|
||||||
if let Some(inst) = f.layout.last_inst(block) {
|
if let Some(inst) = f.layout.last_inst(block) {
|
||||||
match f.dfg.insts[inst] {
|
match &f.dfg.insts[inst] {
|
||||||
ir::InstructionData::Jump {
|
ir::InstructionData::Jump {
|
||||||
destination: dest, ..
|
destination: dest, ..
|
||||||
} => {
|
} => {
|
||||||
@@ -197,9 +197,9 @@ pub(crate) fn visit_block_succs<F: FnMut(Inst, Block, bool)>(
|
|||||||
} => {
|
} => {
|
||||||
// The default block is reached via a direct conditional branch,
|
// The default block is reached via a direct conditional branch,
|
||||||
// so it is not part of the table.
|
// so it is not part of the table.
|
||||||
visit(inst, dest, false);
|
visit(inst, *dest, false);
|
||||||
|
|
||||||
for &dest in f.jump_tables[table].as_slice() {
|
for &dest in f.jump_tables[*table].as_slice() {
|
||||||
visit(inst, dest, true);
|
visit(inst, dest, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -277,14 +277,12 @@ impl FunctionStencil {
|
|||||||
/// Rewrite the branch destination to `new_dest` if the destination matches `old_dest`.
|
/// Rewrite the branch destination to `new_dest` if the destination matches `old_dest`.
|
||||||
/// Does nothing if called with a non-jump or non-branch instruction.
|
/// Does nothing if called with a non-jump or non-branch instruction.
|
||||||
pub fn rewrite_branch_destination(&mut self, inst: Inst, old_dest: Block, new_dest: Block) {
|
pub fn rewrite_branch_destination(&mut self, inst: Inst, old_dest: Block, new_dest: Block) {
|
||||||
match self.dfg.insts[inst] {
|
match &mut self.dfg.insts[inst] {
|
||||||
InstructionData::Jump {
|
InstructionData::Jump {
|
||||||
destination: dest, ..
|
destination: dest, ..
|
||||||
} => {
|
} => {
|
||||||
if dest.block(&self.dfg.value_lists) == old_dest {
|
if dest.block(&self.dfg.value_lists) == old_dest {
|
||||||
for block in self.dfg.insts[inst].branch_destination_mut() {
|
dest.set_block(new_dest, &mut self.dfg.value_lists)
|
||||||
block.set_block(new_dest, &mut self.dfg.value_lists)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,27 +291,11 @@ impl FunctionStencil {
|
|||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
if block_then.block(&self.dfg.value_lists) == old_dest {
|
if block_then.block(&self.dfg.value_lists) == old_dest {
|
||||||
if let InstructionData::Brif {
|
|
||||||
blocks: [block_then, _],
|
|
||||||
..
|
|
||||||
} = &mut self.dfg.insts[inst]
|
|
||||||
{
|
|
||||||
block_then.set_block(new_dest, &mut self.dfg.value_lists);
|
block_then.set_block(new_dest, &mut self.dfg.value_lists);
|
||||||
} else {
|
|
||||||
unreachable!();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if block_else.block(&self.dfg.value_lists) == old_dest {
|
if block_else.block(&self.dfg.value_lists) == old_dest {
|
||||||
if let InstructionData::Brif {
|
|
||||||
blocks: [_, block_else],
|
|
||||||
..
|
|
||||||
} = &mut self.dfg.insts[inst]
|
|
||||||
{
|
|
||||||
block_else.set_block(new_dest, &mut self.dfg.value_lists);
|
block_else.set_block(new_dest, &mut self.dfg.value_lists);
|
||||||
} else {
|
|
||||||
unreachable!();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,22 +304,14 @@ impl FunctionStencil {
|
|||||||
destination: default_dest,
|
destination: default_dest,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
self.jump_tables[table].iter_mut().for_each(|entry| {
|
self.jump_tables[*table].iter_mut().for_each(|entry| {
|
||||||
if *entry == old_dest {
|
if *entry == old_dest {
|
||||||
*entry = new_dest;
|
*entry = new_dest;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if default_dest == old_dest {
|
if *default_dest == old_dest {
|
||||||
match &mut self.dfg.insts[inst] {
|
*default_dest = new_dest;
|
||||||
InstructionData::BranchTable { destination, .. } => {
|
|
||||||
*destination = new_dest;
|
|
||||||
}
|
|
||||||
_ => panic!(
|
|
||||||
"Unexpected instruction {} having default destination",
|
|
||||||
self.dfg.display_inst(inst)
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -943,7 +943,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
|
|||||||
let (inst, succ) = self.vcode.block_order().succ_indices(block)[succ_idx];
|
let (inst, succ) = self.vcode.block_order().succ_indices(block)[succ_idx];
|
||||||
|
|
||||||
// Get branch args and convert to Regs.
|
// Get branch args and convert to Regs.
|
||||||
let branch_args = match self.f.dfg.insts[inst] {
|
let branch_args = match &self.f.dfg.insts[inst] {
|
||||||
InstructionData::Jump {
|
InstructionData::Jump {
|
||||||
destination: block, ..
|
destination: block, ..
|
||||||
} => block.args_slice(&self.f.dfg.value_lists),
|
} => block.args_slice(&self.f.dfg.value_lists),
|
||||||
|
|||||||
@@ -1293,7 +1293,7 @@ impl<'a> Verifier<'a> {
|
|||||||
inst: Inst,
|
inst: Inst,
|
||||||
errors: &mut VerifierErrors,
|
errors: &mut VerifierErrors,
|
||||||
) -> VerifierStepResult<()> {
|
) -> VerifierStepResult<()> {
|
||||||
match self.func.dfg.insts[inst] {
|
match &self.func.dfg.insts[inst] {
|
||||||
ir::InstructionData::Jump {
|
ir::InstructionData::Jump {
|
||||||
destination: block, ..
|
destination: block, ..
|
||||||
} => {
|
} => {
|
||||||
@@ -1333,7 +1333,7 @@ impl<'a> Verifier<'a> {
|
|||||||
destination: block,
|
destination: block,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let arg_count = self.func.dfg.num_block_params(block);
|
let arg_count = self.func.dfg.num_block_params(*block);
|
||||||
if arg_count != 0 {
|
if arg_count != 0 {
|
||||||
return errors.nonfatal((
|
return errors.nonfatal((
|
||||||
inst,
|
inst,
|
||||||
@@ -1344,7 +1344,7 @@ impl<'a> Verifier<'a> {
|
|||||||
),
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
for block in self.func.jump_tables[table].iter() {
|
for block in self.func.jump_tables[*table].iter() {
|
||||||
let arg_count = self.func.dfg.num_block_params(*block);
|
let arg_count = self.func.dfg.num_block_params(*block);
|
||||||
if arg_count != 0 {
|
if arg_count != 0 {
|
||||||
return errors.nonfatal((
|
return errors.nonfatal((
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ impl<'short, 'long> InstBuilderBase<'short> for FuncInstBuilder<'short, 'long> {
|
|||||||
self.builder.func.set_srcloc(inst, self.builder.srcloc);
|
self.builder.func.set_srcloc(inst, self.builder.srcloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.builder.func.dfg.insts[inst] {
|
match &self.builder.func.dfg.insts[inst] {
|
||||||
ir::InstructionData::Jump {
|
ir::InstructionData::Jump {
|
||||||
destination: dest, ..
|
destination: dest, ..
|
||||||
} => {
|
} => {
|
||||||
@@ -140,7 +140,7 @@ impl<'short, 'long> InstBuilderBase<'short> for FuncInstBuilder<'short, 'long> {
|
|||||||
.builder
|
.builder
|
||||||
.func
|
.func
|
||||||
.jump_tables
|
.jump_tables
|
||||||
.get(table)
|
.get(*table)
|
||||||
.expect("you are referencing an undeclared jump table")
|
.expect("you are referencing an undeclared jump table")
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|&dest_block| unique.insert(*dest_block))
|
.filter(|&dest_block| unique.insert(*dest_block))
|
||||||
@@ -152,7 +152,7 @@ impl<'short, 'long> InstBuilderBase<'short> for FuncInstBuilder<'short, 'long> {
|
|||||||
.ssa
|
.ssa
|
||||||
.declare_block_predecessor(*dest_block, inst);
|
.declare_block_predecessor(*dest_block, inst);
|
||||||
}
|
}
|
||||||
self.builder.declare_successor(destination, inst);
|
self.builder.declare_successor(*destination, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|||||||
@@ -577,7 +577,7 @@ impl SSABuilder {
|
|||||||
dest_block: Block,
|
dest_block: Block,
|
||||||
val: Value,
|
val: Value,
|
||||||
) -> Option<(Block, Inst)> {
|
) -> Option<(Block, Inst)> {
|
||||||
match func.dfg.insts[branch] {
|
match &func.dfg.insts[branch] {
|
||||||
// For a single destination appending a jump argument to the instruction
|
// For a single destination appending a jump argument to the instruction
|
||||||
// is sufficient.
|
// is sufficient.
|
||||||
InstructionData::Jump { .. } => {
|
InstructionData::Jump { .. } => {
|
||||||
|
|||||||
Reference in New Issue
Block a user