Promote the (Block, Inst) tuple into a PredBlock struct;

This commit is contained in:
Benjamin Bouvier
2018-07-19 16:06:47 +02:00
committed by Dan Gohman
parent f72ff791b4
commit 78b04fc8ab
2 changed files with 31 additions and 12 deletions

View File

@@ -544,10 +544,9 @@ where
Some(entry) => self.position.ebb.unwrap() == entry, Some(entry) => self.position.ebb.unwrap() == entry,
}; };
!is_entry && self.func_ctx.ssa.is_sealed(self.position.ebb.unwrap()) !is_entry && self.func_ctx.ssa.is_sealed(self.position.ebb.unwrap())
&& self.func_ctx && !self.func_ctx
.ssa .ssa
.predecessors(self.position.ebb.unwrap()) .has_any_predecessors(self.position.ebb.unwrap())
.is_empty()
} }
/// Returns `true` if and only if no instructions have been added since the last call to /// Returns `true` if and only if no instructions have been added since the last call to

View File

@@ -93,7 +93,7 @@ impl<Variable> BlockData<Variable> {
BlockData::EbbBody { .. } => panic!("you can't add a predecessor to a body block"), BlockData::EbbBody { .. } => panic!("you can't add a predecessor to a body block"),
BlockData::EbbHeader(ref mut data) => { BlockData::EbbHeader(ref mut data) => {
debug_assert!(!data.sealed, "sealed blocks cannot accept new predecessors"); debug_assert!(!data.sealed, "sealed blocks cannot accept new predecessors");
data.predecessors.push((pred, inst)); data.predecessors.push(PredBlock::new(pred, inst));
} }
} }
} }
@@ -105,17 +105,28 @@ impl<Variable> BlockData<Variable> {
// in all non-pathological cases // in all non-pathological cases
let pred: usize = data.predecessors let pred: usize = data.predecessors
.iter() .iter()
.position(|pair| pair.1 == inst) .position(|&PredBlock { branch, .. }| branch == inst)
.expect("the predecessor you are trying to remove is not declared"); .expect("the predecessor you are trying to remove is not declared");
data.predecessors.swap_remove(pred).0 data.predecessors.swap_remove(pred).block
} }
} }
} }
} }
struct PredBlock {
block: Block,
branch: Inst,
}
impl PredBlock {
fn new(block: Block, branch: Inst) -> Self {
Self { block, branch }
}
}
struct EbbHeaderBlockData<Variable> { struct EbbHeaderBlockData<Variable> {
// The predecessors of the Ebb header block, with the block and branch instruction. // The predecessors of the Ebb header block, with the block and branch instruction.
predecessors: Vec<(Block, Inst)>, predecessors: Vec<PredBlock>,
// A ebb header block is sealed if all of its predecessors have been declared. // A ebb header block is sealed if all of its predecessors have been declared.
sealed: bool, sealed: bool,
// The ebb which this block is part of. // The ebb which this block is part of.
@@ -307,7 +318,7 @@ where
if data.sealed { if data.sealed {
if data.predecessors.len() == 1 { if data.predecessors.len() == 1 {
// Only one predecessor, straightforward case // Only one predecessor, straightforward case
UseVarCases::SealedOnePredecessor(data.predecessors[0].0) UseVarCases::SealedOnePredecessor(data.predecessors[0].block)
} else { } else {
let val = func.dfg.append_ebb_param(data.ebb, ty); let val = func.dfg.append_ebb_param(data.ebb, ty);
UseVarCases::SealedMultiplePredecessors(val, data.ebb) UseVarCases::SealedMultiplePredecessors(val, data.ebb)
@@ -504,7 +515,7 @@ where
self.predecessors(dest_ebb) self.predecessors(dest_ebb)
.iter() .iter()
.rev() .rev()
.map(|&(pred, _)| Call::UseVar(pred)), .map(|&PredBlock { block: pred, .. }| Call::UseVar(pred)),
); );
self.calls = calls; self.calls = calls;
} }
@@ -580,7 +591,11 @@ where
// to keep the ebb argument. To avoid borrowing `self` for the whole loop, // to keep the ebb argument. To avoid borrowing `self` for the whole loop,
// temporarily detach the predecessors list and replace it with an empty list. // temporarily detach the predecessors list and replace it with an empty list.
let mut preds = mem::replace(self.predecessors_mut(dest_ebb), Vec::new()); let mut preds = mem::replace(self.predecessors_mut(dest_ebb), Vec::new());
for &mut (ref mut pred_block, ref mut last_inst) in &mut preds { for &mut PredBlock {
block: ref mut pred_block,
branch: ref mut last_inst,
} in &mut preds
{
// We already did a full `use_var` above, so we can do just the fast path. // We already did a full `use_var` above, so we can do just the fast path.
let pred_val = self.variables let pred_val = self.variables
.get(temp_arg_var) .get(temp_arg_var)
@@ -657,7 +672,7 @@ where
} }
/// Returns the list of `Ebb`s that have been declared as predecessors of the argument. /// Returns the list of `Ebb`s that have been declared as predecessors of the argument.
pub fn predecessors(&self, ebb: Ebb) -> &[(Block, Inst)] { fn predecessors(&self, ebb: Ebb) -> &[PredBlock] {
let block = self.header_block(ebb); let block = self.header_block(ebb);
match self.blocks[block] { match self.blocks[block] {
BlockData::EbbBody { .. } => panic!("should not happen"), BlockData::EbbBody { .. } => panic!("should not happen"),
@@ -665,8 +680,13 @@ where
} }
} }
/// Returns whether the given Ebb has any predecessor or not.
pub fn has_any_predecessors(&self, ebb: Ebb) -> bool {
!self.predecessors(ebb).is_empty()
}
/// Same as predecessors, but for &mut. /// Same as predecessors, but for &mut.
pub fn predecessors_mut(&mut self, ebb: Ebb) -> &mut Vec<(Block, Inst)> { fn predecessors_mut(&mut self, ebb: Ebb) -> &mut Vec<PredBlock> {
let block = self.header_block(ebb); let block = self.header_block(ebb);
match self.blocks[block] { match self.blocks[block] {
BlockData::EbbBody { .. } => panic!("should not happen"), BlockData::EbbBody { .. } => panic!("should not happen"),