Merge pull request #11 from Amanieu/requirement
Simplify Requirement by removing register classes
This commit is contained in:
@@ -748,6 +748,7 @@ impl<'a, F: Function> Env<'a, F> {
|
|||||||
bundle: LiveBundleIndex,
|
bundle: LiveBundleIndex,
|
||||||
reg_hint: PReg,
|
reg_hint: PReg,
|
||||||
) -> Result<(), RegAllocError> {
|
) -> Result<(), RegAllocError> {
|
||||||
|
let class = self.spillsets[self.bundles[bundle.index()].spillset.index()].class;
|
||||||
let req = self.compute_requirement(bundle);
|
let req = self.compute_requirement(bundle);
|
||||||
// Grab a hint from either the queue or our spillset, if any.
|
// Grab a hint from either the queue or our spillset, if any.
|
||||||
let hint_reg = if reg_hint != PReg::invalid() {
|
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
|
// spill bundle is already present, then move the LRs over to
|
||||||
// the spill bundle right away.
|
// the spill bundle right away.
|
||||||
match req {
|
match req {
|
||||||
Requirement::Unknown | Requirement::Any(_) => {
|
Requirement::Unknown | Requirement::Any => {
|
||||||
if let Some(spill) =
|
if let Some(spill) =
|
||||||
self.get_or_create_spill_bundle(bundle, /* create_if_absent = */ false)
|
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);
|
log::trace!("attempt {}, req {:?}", attempts, req);
|
||||||
debug_assert!(attempts < 100 * self.func.num_insts());
|
debug_assert!(attempts < 100 * self.func.num_insts());
|
||||||
|
|
||||||
let (class, fixed_preg) = match req {
|
let fixed_preg = match req {
|
||||||
Requirement::Fixed(preg) => (preg.class(), Some(preg)),
|
Requirement::Fixed(preg) => Some(preg),
|
||||||
Requirement::Register(class) => (class, None),
|
Requirement::Register => None,
|
||||||
Requirement::Stack(_) => {
|
Requirement::Stack => {
|
||||||
// If we must be on the stack, mark our spillset
|
// If we must be on the stack, mark our spillset
|
||||||
// as required immediately.
|
// as required immediately.
|
||||||
self.spillsets[self.bundles[bundle.index()].spillset.index()].required = true;
|
self.spillsets[self.bundles[bundle.index()].spillset.index()].required = true;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
Requirement::Any(_) | Requirement::Unknown => {
|
Requirement::Any | Requirement::Unknown => {
|
||||||
self.spilled_bundles.push(bundle);
|
self.spilled_bundles.push(bundle);
|
||||||
return Ok(());
|
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.is_none()
|
||||||
|| lowest_cost_evict_conflict_cost.unwrap() >= our_spill_weight)
|
|| 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.
|
// Check if this is a too-many-live-registers situation.
|
||||||
let range = self.bundles[bundle.index()].ranges[0].range;
|
let range = self.bundles[bundle.index()].ranges[0].range;
|
||||||
log::trace!("checking for too many live regs");
|
log::trace!("checking for too many live regs");
|
||||||
|
|||||||
@@ -1,63 +1,28 @@
|
|||||||
//! Requirements computation.
|
//! Requirements computation.
|
||||||
|
|
||||||
use super::{Env, LiveBundleIndex};
|
use super::{Env, LiveBundleIndex};
|
||||||
use crate::{Function, Operand, OperandConstraint, PReg, RegClass};
|
use crate::{Function, Operand, OperandConstraint, PReg};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
pub enum Requirement {
|
pub enum Requirement {
|
||||||
Unknown,
|
Unknown,
|
||||||
Fixed(PReg),
|
Fixed(PReg),
|
||||||
Register(RegClass),
|
Register,
|
||||||
Stack(RegClass),
|
Stack,
|
||||||
Any(RegClass),
|
Any,
|
||||||
Conflict,
|
Conflict,
|
||||||
}
|
}
|
||||||
impl Requirement {
|
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)]
|
#[inline(always)]
|
||||||
pub fn merge(self, other: Requirement) -> Requirement {
|
pub fn merge(self, other: Requirement) -> Requirement {
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
(Requirement::Unknown, other) | (other, Requirement::Unknown) => other,
|
(Requirement::Unknown, other) | (other, Requirement::Unknown) => other,
|
||||||
(Requirement::Conflict, _) | (_, Requirement::Conflict) => Requirement::Conflict,
|
(Requirement::Conflict, _) | (_, Requirement::Conflict) => Requirement::Conflict,
|
||||||
(other, Requirement::Any(rc)) | (Requirement::Any(rc), other) => {
|
(other, Requirement::Any) | (Requirement::Any, other) => other,
|
||||||
if other.class() == rc {
|
(Requirement::Stack, Requirement::Stack) => self,
|
||||||
other
|
(Requirement::Register, Requirement::Fixed(preg))
|
||||||
} else {
|
| (Requirement::Fixed(preg), Requirement::Register) => Requirement::Fixed(preg),
|
||||||
Requirement::Conflict
|
(Requirement::Register, Requirement::Register) => self,
|
||||||
}
|
|
||||||
}
|
|
||||||
(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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(Requirement::Fixed(a), Requirement::Fixed(b)) if a == b => self,
|
(Requirement::Fixed(a), Requirement::Fixed(b)) if a == b => self,
|
||||||
_ => Requirement::Conflict,
|
_ => Requirement::Conflict,
|
||||||
}
|
}
|
||||||
@@ -66,11 +31,9 @@ impl Requirement {
|
|||||||
pub fn from_operand(op: Operand) -> Requirement {
|
pub fn from_operand(op: Operand) -> Requirement {
|
||||||
match op.constraint() {
|
match op.constraint() {
|
||||||
OperandConstraint::FixedReg(preg) => Requirement::Fixed(preg),
|
OperandConstraint::FixedReg(preg) => Requirement::Fixed(preg),
|
||||||
OperandConstraint::Reg | OperandConstraint::Reuse(_) => {
|
OperandConstraint::Reg | OperandConstraint::Reuse(_) => Requirement::Register,
|
||||||
Requirement::Register(op.class())
|
OperandConstraint::Stack => Requirement::Stack,
|
||||||
}
|
_ => Requirement::Any,
|
||||||
OperandConstraint::Stack => Requirement::Stack(op.class()),
|
|
||||||
_ => Requirement::Any(op.class()),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user