From 448f210e32adf640753ccf89aca83faa8b363086 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Sun, 5 Sep 2021 19:15:54 +0200 Subject: [PATCH] Simplify Requirement by removing register classes We never merge bundles from vregs of different classes, so we don't need to check for register class conflicts. --- src/ion/process.rs | 15 ++++++----- src/ion/requirement.rs | 61 +++++++++--------------------------------- 2 files changed, 20 insertions(+), 56 deletions(-) diff --git a/src/ion/process.rs b/src/ion/process.rs index 8c10a9bb..4aac38f9 100644 --- a/src/ion/process.rs +++ b/src/ion/process.rs @@ -748,6 +748,7 @@ impl<'a, F: Function> Env<'a, F> { bundle: LiveBundleIndex, reg_hint: PReg, ) -> Result<(), RegAllocError> { + let class = self.spillsets[self.bundles[bundle.index()].spillset.index()].class; let req = self.compute_requirement(bundle); // Grab a hint from either the queue or our spillset, if any. let hint_reg = if reg_hint != PReg::invalid() { @@ -778,7 +779,7 @@ impl<'a, F: Function> Env<'a, F> { // spill bundle is already present, then move the LRs over to // the spill bundle right away. match req { - Requirement::Unknown | Requirement::Any(_) => { + Requirement::Unknown | Requirement::Any => { if let Some(spill) = self.get_or_create_spill_bundle(bundle, /* create_if_absent = */ false) { @@ -801,17 +802,17 @@ impl<'a, F: Function> Env<'a, F> { log::trace!("attempt {}, req {:?}", attempts, req); debug_assert!(attempts < 100 * self.func.num_insts()); - let (class, fixed_preg) = match req { - Requirement::Fixed(preg) => (preg.class(), Some(preg)), - Requirement::Register(class) => (class, None), - Requirement::Stack(_) => { + let fixed_preg = match req { + Requirement::Fixed(preg) => Some(preg), + Requirement::Register => None, + Requirement::Stack => { // If we must be on the stack, mark our spillset // as required immediately. self.spillsets[self.bundles[bundle.index()].spillset.index()].required = true; return Ok(()); } - Requirement::Any(_) | Requirement::Unknown => { + Requirement::Any | Requirement::Unknown => { self.spilled_bundles.push(bundle); return Ok(()); } @@ -966,7 +967,7 @@ impl<'a, F: Function> Env<'a, F> { || lowest_cost_evict_conflict_cost.is_none() || lowest_cost_evict_conflict_cost.unwrap() >= our_spill_weight) { - if let Requirement::Register(class) = req { + if let Requirement::Register = req { // Check if this is a too-many-live-registers situation. let range = self.bundles[bundle.index()].ranges[0].range; log::trace!("checking for too many live regs"); diff --git a/src/ion/requirement.rs b/src/ion/requirement.rs index 1540fe4e..fdc1f684 100644 --- a/src/ion/requirement.rs +++ b/src/ion/requirement.rs @@ -1,63 +1,28 @@ //! Requirements computation. use super::{Env, LiveBundleIndex}; -use crate::{Function, Operand, OperandConstraint, PReg, RegClass}; +use crate::{Function, Operand, OperandConstraint, PReg}; #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum Requirement { Unknown, Fixed(PReg), - Register(RegClass), - Stack(RegClass), - Any(RegClass), + Register, + Stack, + Any, Conflict, } impl Requirement { - #[inline(always)] - pub fn class(self) -> RegClass { - match self { - Requirement::Unknown => panic!("No class for unknown Requirement"), - Requirement::Fixed(preg) => preg.class(), - Requirement::Register(class) | Requirement::Any(class) | Requirement::Stack(class) => { - class - } - Requirement::Conflict => panic!("No class for conflicted Requirement"), - } - } #[inline(always)] pub fn merge(self, other: Requirement) -> Requirement { match (self, other) { (Requirement::Unknown, other) | (other, Requirement::Unknown) => other, (Requirement::Conflict, _) | (_, Requirement::Conflict) => Requirement::Conflict, - (other, Requirement::Any(rc)) | (Requirement::Any(rc), other) => { - if other.class() == rc { - other - } else { - Requirement::Conflict - } - } - (Requirement::Stack(rc1), Requirement::Stack(rc2)) => { - if rc1 == rc2 { - self - } else { - Requirement::Conflict - } - } - (Requirement::Register(rc), Requirement::Fixed(preg)) - | (Requirement::Fixed(preg), Requirement::Register(rc)) => { - if rc == preg.class() { - Requirement::Fixed(preg) - } else { - Requirement::Conflict - } - } - (Requirement::Register(rc1), Requirement::Register(rc2)) => { - if rc1 == rc2 { - self - } else { - Requirement::Conflict - } - } + (other, Requirement::Any) | (Requirement::Any, other) => other, + (Requirement::Stack, Requirement::Stack) => self, + (Requirement::Register, Requirement::Fixed(preg)) + | (Requirement::Fixed(preg), Requirement::Register) => Requirement::Fixed(preg), + (Requirement::Register, Requirement::Register) => self, (Requirement::Fixed(a), Requirement::Fixed(b)) if a == b => self, _ => Requirement::Conflict, } @@ -66,11 +31,9 @@ impl Requirement { pub fn from_operand(op: Operand) -> Requirement { match op.constraint() { OperandConstraint::FixedReg(preg) => Requirement::Fixed(preg), - OperandConstraint::Reg | OperandConstraint::Reuse(_) => { - Requirement::Register(op.class()) - } - OperandConstraint::Stack => Requirement::Stack(op.class()), - _ => Requirement::Any(op.class()), + OperandConstraint::Reg | OperandConstraint::Reuse(_) => Requirement::Register, + OperandConstraint::Stack => Requirement::Stack, + _ => Requirement::Any, } } }