From b521254149a9d655814cf01caf47ed50c9c3cf96 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Wed, 10 May 2017 12:31:59 -0700 Subject: [PATCH] Solver variables keep track of where they came from. The register constraint solver has two kinds of variables: 1. Live values that were already in a register, and 2. Values defined by the instruction. Make a record of the original register holding the first kind of value. --- lib/cretonne/src/regalloc/coloring.rs | 2 +- lib/cretonne/src/regalloc/solver.rs | 63 ++++++++++++++++----------- 2 files changed, 39 insertions(+), 26 deletions(-) diff --git a/lib/cretonne/src/regalloc/coloring.rs b/lib/cretonne/src/regalloc/coloring.rs index 521b1c9cba..d8d3571ad6 100644 --- a/lib/cretonne/src/regalloc/coloring.rs +++ b/lib/cretonne/src/regalloc/coloring.rs @@ -357,7 +357,7 @@ impl<'a> Context<'a> { .unwrap_or_else(|_| self.iterate_solution()); // Apply the solution to the defs. - for v in self.solver.vars().iter().filter(|&v| v.is_define) { + for v in self.solver.vars().iter().filter(|&v| v.is_define()) { *locations.ensure(v.value) = ValueLoc::Reg(v.solution); } diff --git a/lib/cretonne/src/regalloc/solver.rs b/lib/cretonne/src/regalloc/solver.rs index 05751c5155..0001169e96 100644 --- a/lib/cretonne/src/regalloc/solver.rs +++ b/lib/cretonne/src/regalloc/solver.rs @@ -129,6 +129,10 @@ pub struct Variable { /// The value whose register assignment we're looking for. pub value: Value, + /// Original register unit holding this live value before the instruction, or `None` for a + /// value that is defined by the instruction. + from: Option, + /// Avoid interference on the input side. is_input: bool, @@ -138,9 +142,6 @@ pub struct Variable { /// Avoid interference with the global registers. is_global: bool, - /// The value is defined by the current instruction. - pub is_define: bool, - /// Number of registers available in the domain of this variable. domain: u16, @@ -152,6 +153,37 @@ pub struct Variable { } impl Variable { + fn new_live(value: Value, constraint: RegClass, from: RegUnit) -> Variable { + Variable { + value, + constraint, + from: Some(from), + is_input: true, + is_output: true, + is_global: false, + domain: 0, + solution: !0, + } + } + + fn new_def(value: Value, constraint: RegClass) -> Variable { + Variable { + value, + constraint, + from: None, + is_input: false, + is_output: true, + is_global: false, + domain: 0, + solution: !0, + } + } + + /// Does this variable represent a value defined by the current instruction? + pub fn is_define(&self) -> bool { + self.from.is_none() + } + /// Get an iterator over possible register choices, given the available registers on the input /// and output sides respectively. fn iter(&self, iregs: &AllocatableSet, oregs: &AllocatableSet) -> RegSetIter { @@ -179,7 +211,7 @@ impl fmt::Display for Variable { if self.is_global { write!(f, ", global")?; } - if self.is_define { + if self.is_define() { write!(f, ", def")?; } if self.domain > 0 { @@ -369,16 +401,7 @@ impl Solver { self.regs_out.free(constraint, from); } self.vars - .push(Variable { - value, - constraint, - is_input: true, - is_output: true, - is_global: false, - is_define: false, - domain: 0, - solution: !0, - }); + .push(Variable::new_live(value, constraint, from)); } /// Check for conflicts between fixed input assignments and existing live values. @@ -474,17 +497,7 @@ impl Solver { /// This is similar to `add_var`, except the value doesn't have a prior register assignment. pub fn add_def(&mut self, value: Value, constraint: RegClass) { debug_assert!(self.inputs_done); - self.vars - .push(Variable { - value, - constraint, - is_input: false, - is_output: true, - is_global: false, - is_define: true, - domain: 0, - solution: !0, - }); + self.vars.push(Variable::new_def(value, constraint)); } }