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:
@@ -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(())
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user