Mass rename Ebb and relatives to Block (#1365)
* Manually rename BasicBlock to BlockPredecessor BasicBlock is a pair of (Ebb, Inst) that is used to represent the basic block subcomponent of an Ebb that is a predecessor to an Ebb. Eventually we will be able to remove this struct, but for now it makes sense to give it a non-conflicting name so that we can start to transition Ebb to represent a basic block. I have not updated any comments that refer to BasicBlock, as eventually we will remove BlockPredecessor and replace with Block, which is a basic block, so the comments will become correct. * Manually rename SSABuilder block types to avoid conflict SSABuilder has its own Block and BlockData types. These along with associated identifier will cause conflicts in a later commit, so they are renamed to be more verbose here. * Automatically rename 'Ebb' to 'Block' in *.rs * Automatically rename 'EBB' to 'block' in *.rs * Automatically rename 'ebb' to 'block' in *.rs * Automatically rename 'extended basic block' to 'basic block' in *.rs * Automatically rename 'an basic block' to 'a basic block' in *.rs * Manually update comment for `Block` `Block`'s wikipedia article required an update. * Automatically rename 'an `Block`' to 'a `Block`' in *.rs * Automatically rename 'extended_basic_block' to 'basic_block' in *.rs * Automatically rename 'ebb' to 'block' in *.clif * Manually rename clif constant that contains 'ebb' as substring to avoid conflict * Automatically rename filecheck uses of 'EBB' to 'BB' 'regex: EBB' -> 'regex: BB' '$EBB' -> '$BB' * Automatically rename 'EBB' 'Ebb' to 'block' in *.clif * Automatically rename 'an block' to 'a block' in *.clif * Fix broken testcase when function name length increases Test function names are limited to 16 characters. This causes the new longer name to be truncated and fail a filecheck test. An outdated comment was also fixed.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
//! Liveness verifier.
|
||||
|
||||
use crate::flowgraph::{BasicBlock, ControlFlowGraph};
|
||||
use crate::flowgraph::{BlockPredecessor, ControlFlowGraph};
|
||||
use crate::ir::entities::AnyEntity;
|
||||
use crate::ir::{ExpandedProgramPoint, Function, ProgramPoint, Value};
|
||||
use crate::isa::TargetIsa;
|
||||
@@ -16,7 +16,7 @@ use crate::verifier::{VerifierErrors, VerifierStepResult};
|
||||
/// - All values in the program must have a live range.
|
||||
/// - The live range def point must match where the value is defined.
|
||||
/// - The live range must reach all uses.
|
||||
/// - When a live range is live-in to an EBB, it must be live at all the predecessors.
|
||||
/// - When a live range is live-in to an block, it must be live at all the predecessors.
|
||||
/// - The live range affinity must be compatible with encoding constraints.
|
||||
///
|
||||
/// We don't verify that live ranges are minimal. This would require recomputing live ranges for
|
||||
@@ -35,7 +35,7 @@ pub fn verify_liveness(
|
||||
cfg,
|
||||
liveness,
|
||||
};
|
||||
verifier.check_ebbs(errors)?;
|
||||
verifier.check_blocks(errors)?;
|
||||
verifier.check_insts(errors)?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -48,17 +48,18 @@ struct LivenessVerifier<'a> {
|
||||
}
|
||||
|
||||
impl<'a> LivenessVerifier<'a> {
|
||||
/// Check all EBB arguments.
|
||||
fn check_ebbs(&self, errors: &mut VerifierErrors) -> VerifierStepResult<()> {
|
||||
for ebb in self.func.layout.ebbs() {
|
||||
for &val in self.func.dfg.ebb_params(ebb) {
|
||||
/// Check all block arguments.
|
||||
fn check_blocks(&self, errors: &mut VerifierErrors) -> VerifierStepResult<()> {
|
||||
for block in self.func.layout.blocks() {
|
||||
for &val in self.func.dfg.block_params(block) {
|
||||
let lr = match self.liveness.get(val) {
|
||||
Some(lr) => lr,
|
||||
None => {
|
||||
return errors.fatal((ebb, format!("EBB arg {} has no live range", val)))
|
||||
return errors
|
||||
.fatal((block, format!("block arg {} has no live range", val)))
|
||||
}
|
||||
};
|
||||
self.check_lr(ebb.into(), val, lr, errors)?;
|
||||
self.check_lr(block.into(), val, lr, errors)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
@@ -66,8 +67,8 @@ impl<'a> LivenessVerifier<'a> {
|
||||
|
||||
/// Check all instructions.
|
||||
fn check_insts(&self, errors: &mut VerifierErrors) -> VerifierStepResult<()> {
|
||||
for ebb in self.func.layout.ebbs() {
|
||||
for inst in self.func.layout.ebb_insts(ebb) {
|
||||
for block in self.func.layout.blocks() {
|
||||
for inst in self.func.layout.block_insts(block) {
|
||||
let encoding = self.func.encodings[inst];
|
||||
|
||||
// Check the defs.
|
||||
@@ -110,8 +111,8 @@ impl<'a> LivenessVerifier<'a> {
|
||||
None => return errors.fatal((inst, format!("{} has no live range", val))),
|
||||
};
|
||||
|
||||
debug_assert!(self.func.layout.inst_ebb(inst).unwrap() == ebb);
|
||||
if !lr.reaches_use(inst, ebb, &self.func.layout) {
|
||||
debug_assert!(self.func.layout.inst_block(inst).unwrap() == block);
|
||||
if !lr.reaches_use(inst, block, &self.func.layout) {
|
||||
return errors.fatal((inst, format!("{} is not live at this use", val)));
|
||||
}
|
||||
|
||||
@@ -143,7 +144,7 @@ impl<'a> LivenessVerifier<'a> {
|
||||
let l = &self.func.layout;
|
||||
|
||||
let loc: AnyEntity = match def.into() {
|
||||
ExpandedProgramPoint::Ebb(e) => e.into(),
|
||||
ExpandedProgramPoint::Block(e) => e.into(),
|
||||
ExpandedProgramPoint::Inst(i) => i.into(),
|
||||
};
|
||||
if lr.def() != def {
|
||||
@@ -159,66 +160,70 @@ impl<'a> LivenessVerifier<'a> {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
let def_ebb = match def.into() {
|
||||
ExpandedProgramPoint::Ebb(e) => e,
|
||||
ExpandedProgramPoint::Inst(i) => l.inst_ebb(i).unwrap(),
|
||||
let def_block = match def.into() {
|
||||
ExpandedProgramPoint::Block(e) => e,
|
||||
ExpandedProgramPoint::Inst(i) => l.inst_block(i).unwrap(),
|
||||
};
|
||||
match lr.def_local_end().into() {
|
||||
ExpandedProgramPoint::Ebb(e) => {
|
||||
ExpandedProgramPoint::Block(e) => {
|
||||
return errors.fatal((
|
||||
loc,
|
||||
format!("Def local range for {} can't end at {}", val, e),
|
||||
));
|
||||
}
|
||||
ExpandedProgramPoint::Inst(i) => {
|
||||
if self.func.layout.inst_ebb(i) != Some(def_ebb) {
|
||||
return errors.fatal((loc, format!("Def local end for {} in wrong ebb", val)));
|
||||
if self.func.layout.inst_block(i) != Some(def_block) {
|
||||
return errors
|
||||
.fatal((loc, format!("Def local end for {} in wrong block", val)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now check the live-in intervals against the CFG.
|
||||
for (mut ebb, end) in lr.liveins() {
|
||||
if !l.is_ebb_inserted(ebb) {
|
||||
for (mut block, end) in lr.liveins() {
|
||||
if !l.is_block_inserted(block) {
|
||||
return errors.fatal((
|
||||
loc,
|
||||
format!("{} livein at {} which is not in the layout", val, ebb),
|
||||
format!("{} livein at {} which is not in the layout", val, block),
|
||||
));
|
||||
}
|
||||
let end_ebb = match l.inst_ebb(end) {
|
||||
let end_block = match l.inst_block(end) {
|
||||
Some(e) => e,
|
||||
None => {
|
||||
return errors.fatal((
|
||||
loc,
|
||||
format!(
|
||||
"{} livein for {} ends at {} which is not in the layout",
|
||||
val, ebb, end
|
||||
val, block, end
|
||||
),
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
// Check all the EBBs in the interval independently.
|
||||
// Check all the blocks in the interval independently.
|
||||
loop {
|
||||
// If `val` is live-in at `ebb`, it must be live at all the predecessors.
|
||||
for BasicBlock { inst: pred, ebb } in self.cfg.pred_iter(ebb) {
|
||||
if !lr.reaches_use(pred, ebb, &self.func.layout) {
|
||||
// If `val` is live-in at `block`, it must be live at all the predecessors.
|
||||
for BlockPredecessor { inst: pred, block } in self.cfg.pred_iter(block) {
|
||||
if !lr.reaches_use(pred, block, &self.func.layout) {
|
||||
return errors.fatal((
|
||||
pred,
|
||||
format!("{} is live in to {} but not live at predecessor", val, ebb),
|
||||
format!(
|
||||
"{} is live in to {} but not live at predecessor",
|
||||
val, block
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if ebb == end_ebb {
|
||||
if block == end_block {
|
||||
break;
|
||||
}
|
||||
ebb = match l.next_ebb(ebb) {
|
||||
block = match l.next_block(block) {
|
||||
Some(e) => e,
|
||||
None => {
|
||||
return errors.fatal((
|
||||
loc,
|
||||
format!("end of {} livein ({}) never reached", val, end_ebb),
|
||||
format!("end of {} livein ({}) never reached", val, end_block),
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user