From 2473661d49b9bc0996b8ef3254066237b98ef276 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Tue, 12 Dec 2017 16:16:01 -0600 Subject: [PATCH] Loosen the required order of values in a virtual register. Instead of requiring the values in a virtual register to be sorted according to the domtree.rpo_cmp() order, just require any topological ordering w.r.t. dominance. The coalescer with stop using the RPO shortly. --- lib/cretonne/src/regalloc/virtregs.rs | 9 +++---- lib/cretonne/src/verifier/cssa.rs | 39 ++++++++++++++------------- 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/lib/cretonne/src/regalloc/virtregs.rs b/lib/cretonne/src/regalloc/virtregs.rs index 852f1e0af0..b9388277e0 100644 --- a/lib/cretonne/src/regalloc/virtregs.rs +++ b/lib/cretonne/src/regalloc/virtregs.rs @@ -33,9 +33,6 @@ pub struct VirtRegs { pool: ListPool, /// The primary table of virtual registers. - /// - /// The list of values ion a virtual register is kept sorted according to the dominator tree's - /// RPO of the value defs. vregs: PrimaryMap, /// Each value belongs to at most one virtual register. @@ -65,8 +62,8 @@ impl VirtRegs { self.value_vregs[value].into() } - /// Get the list of values in `vreg`. The values are ordered according to `DomTree::rpo_cmp` of - /// their definition points. + /// Get the list of values in `vreg`. + /// The values are topologically ordered according dominance of their definition points. pub fn values(&self, vreg: VirtReg) -> &[Value] { self.vregs[vreg].as_slice(&self.pool) } @@ -103,7 +100,7 @@ impl VirtRegs { /// If a value belongs to a virtual register, all of the values in that register must be /// present. /// - /// The values are assumed to already be in RPO order. + /// The values are assumed to already be in topological order. pub fn unify(&mut self, values: &[Value]) -> VirtReg { // Start by clearing all virtual registers involved. // Pick a virtual register to reuse (the smallest number) or allocate a new one. diff --git a/lib/cretonne/src/verifier/cssa.rs b/lib/cretonne/src/verifier/cssa.rs index 935279c7f1..5c35f8811e 100644 --- a/lib/cretonne/src/verifier/cssa.rs +++ b/lib/cretonne/src/verifier/cssa.rs @@ -1,11 +1,11 @@ //! Verify conventional SSA form. +use dbg::DisplayList; use dominator_tree::DominatorTree; use flowgraph::ControlFlowGraph; use ir::Function; use regalloc::liveness::Liveness; use regalloc::virtregs::VirtRegs; -use std::cmp::Ordering; use timing; use verifier::Result; @@ -20,7 +20,7 @@ use verifier::Result; /// /// Additionally, we verify this property of virtual registers: /// -/// - The values in a virtual register are ordered according to the dominator tree's `rpo_cmp()`. +/// - The values in a virtual register are topologically ordered w.r.t. dominance. /// /// We don't verify that virtual registers are minimal. Minimal CSSA is not required. pub fn verify_cssa( @@ -67,33 +67,34 @@ impl<'a> CssaVerifier<'a> { return err!(val, "Value in {} has no live range", vreg); }; - // Check RPO ordering with the previous values in the virtual register. + // Check topological ordering with the previous values in the virtual register. let def = self.func.dfg.value_def(val).into(); let def_ebb = self.func.layout.pp_ebb(def); for &prev_val in &values[0..idx] { let prev_def = self.func.dfg.value_def(prev_val); - // Enforce RPO of defs in the virtual register. - match self.domtree.rpo_cmp(prev_def, def, &self.func.layout) { - Ordering::Less => {} - Ordering::Equal => { - return err!(val, "Value in {} has same def as {}", vreg, prev_val); - } - Ordering::Greater => { - return err!( - val, - "Value in {} in wrong order relative to {}", - vreg, - prev_val - ); - } + // Enforce topological ordering of defs in the virtual register. + if self.domtree.dominates(def, prev_def, &self.func.layout) { + return err!( + val, + "Value in {} = {} def dominates previous {}", + vreg, + DisplayList(values), + prev_val + ); } - // Knowing that values are in RPO order, we can check for interference this + // Knowing that values are in topo order, we can check for interference this // way. let ctx = self.liveness.context(&self.func.layout); if self.liveness[prev_val].overlaps_def(def, def_ebb, ctx) { - return err!(val, "Value def in {} interferes with {}", vreg, prev_val); + return err!( + val, + "Value def in {} = {} interferes with {}", + vreg, + DisplayList(values), + prev_val + ); } } }