CSSA verifier.

During register allocation, the code must be kept in conventional SSA
form. Add a verifier that checks this property.
This commit is contained in:
Jakob Stoklund Olesen
2017-07-13 13:18:18 -07:00
parent 5a4aa11274
commit 6d6035b918
5 changed files with 137 additions and 3 deletions

View File

@@ -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};
use verifier::{verify_context, verify_liveness, verify_cssa};
/// Persistent memory allocations for register allocation.
pub struct Context {
@@ -85,6 +85,7 @@ impl Context {
if isa.flags().enable_verifier() {
verify_context(func, cfg, domtree, Some(isa))?;
verify_liveness(isa, func, cfg, &self.liveness)?;
verify_cssa(func, cfg, domtree, &self.liveness, &self.virtregs)?;
}
@@ -101,6 +102,7 @@ impl Context {
if isa.flags().enable_verifier() {
verify_context(func, cfg, domtree, Some(isa))?;
verify_liveness(isa, func, cfg, &self.liveness)?;
verify_cssa(func, cfg, domtree, &self.liveness, &self.virtregs)?;
}
// Pass: Reload.
@@ -115,6 +117,7 @@ impl Context {
if isa.flags().enable_verifier() {
verify_context(func, cfg, domtree, Some(isa))?;
verify_liveness(isa, func, cfg, &self.liveness)?;
verify_cssa(func, cfg, domtree, &self.liveness, &self.virtregs)?;
}
// Pass: Coloring.
@@ -124,6 +127,7 @@ impl Context {
if isa.flags().enable_verifier() {
verify_context(func, cfg, domtree, Some(isa))?;
verify_liveness(isa, func, cfg, &self.liveness)?;
verify_cssa(func, cfg, domtree, &self.liveness, &self.virtregs)?;
}
Ok(())
}

View File

@@ -7,6 +7,7 @@ pub mod liveness;
pub mod allocatable_set;
pub mod live_value_tracker;
pub mod coloring;
pub mod virtregs;
mod affinity;
mod coalescing;
@@ -16,7 +17,6 @@ mod pressure;
mod reload;
mod solver;
mod spilling;
mod virtregs;
pub use self::allocatable_set::AllocatableSet;
pub use self::context::Context;

View File

@@ -12,11 +12,12 @@
//! memory-to-memory copies when a spilled value is passed as an EBB argument.
use entity_list::{EntityList, ListPool};
use entity_map::{EntityMap, PrimaryEntityData};
use entity_map::{EntityMap, PrimaryEntityData, Keys};
use ir::Value;
use packed_option::PackedOption;
use ref_slice::ref_slice;
/// A virtual register reference.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
pub struct VirtReg(u32);
entity_impl!(VirtReg, "vreg");
@@ -71,6 +72,11 @@ impl VirtRegs {
self.vregs[vreg].as_slice(&self.pool)
}
/// Get an iterator over all virtual registers.
pub fn all_virtregs(&self) -> Keys<VirtReg> {
self.vregs.keys()
}
/// Get the congruence class of `value`.
///
/// If `value` belongs to a virtual register, the congruence class is the values of the virtual