Add a value location verifier.
This is a verification pass that can be run after register allocation. It verifies that value locations are consistent with constraints on their uses, and that the register diversions are consistent. Make it clear that register diversions are local to an EBB only. This affects what branch relaxation is allowed to do. The verify_locations() takes an optional Liveness parameter which is used to check that no diverted values are live across CFG edges.
This commit is contained in:
@@ -468,7 +468,7 @@ impl<'a> Context<'a> {
|
||||
//
|
||||
// Values with a global live range that are not live in to `dest` could appear as branch
|
||||
// arguments, so they can't always be un-diverted.
|
||||
self.undivert_regs(|lr, func| lr.livein_local_end(dest, &func.layout).is_some());
|
||||
self.undivert_regs(|lr, func| lr.is_livein(dest, &func.layout));
|
||||
|
||||
// Now handle the EBB arguments.
|
||||
let br_args = self.cur.func.dfg.inst_variable_args(inst);
|
||||
|
||||
@@ -17,7 +17,7 @@ use regalloc::spilling::Spilling;
|
||||
use regalloc::virtregs::VirtRegs;
|
||||
use result::CtonResult;
|
||||
use topo_order::TopoOrder;
|
||||
use verifier::{verify_context, verify_liveness, verify_cssa};
|
||||
use verifier::{verify_context, verify_liveness, verify_cssa, verify_locations};
|
||||
|
||||
/// Persistent memory allocations for register allocation.
|
||||
pub struct Context {
|
||||
@@ -138,6 +138,7 @@ impl Context {
|
||||
if isa.flags().enable_verifier() {
|
||||
verify_context(func, cfg, domtree, isa)?;
|
||||
verify_liveness(isa, func, cfg, &self.liveness)?;
|
||||
verify_locations(isa, func, Some(&self.liveness))?;
|
||||
verify_cssa(func, cfg, domtree, &self.liveness, &self.virtregs)?;
|
||||
}
|
||||
Ok(())
|
||||
|
||||
@@ -383,6 +383,13 @@ impl LiveRange {
|
||||
})
|
||||
}
|
||||
|
||||
/// Is this value live-in to `ebb`?
|
||||
///
|
||||
/// An EBB argument is not considered to be live in.
|
||||
pub fn is_livein<PO: ProgramOrder>(&self, ebb: Ebb, order: &PO) -> bool {
|
||||
self.livein_local_end(ebb, order).is_some()
|
||||
}
|
||||
|
||||
/// Get all the live-in intervals.
|
||||
pub fn liveins(&self) -> &[Interval] {
|
||||
&self.liveins
|
||||
|
||||
Reference in New Issue
Block a user