Remove register class from SpillSlot (#80)

* Remove register class from `SpillSlot`

The register allocator was already allowing moves between spillslots and
registers of different classes, so this PR formalizes this by making
spillslots independent of register class.

This also fixes #79 by properly tracking the register class of an
`InsertedMove` with the `to_vreg` field which turns out to never
be `None` in practice. Removing the `Option` allows the register
class of the `VReg` to be used when building the per-class move lists.

Fixes #79

* Address review feedback
This commit is contained in:
Amanieu d'Antras
2022-09-21 05:05:23 +08:00
committed by GitHub
parent 3db1b7199b
commit 906a053208
6 changed files with 40 additions and 74 deletions

View File

@@ -324,13 +324,11 @@ impl SpillSlot {
/// The maximum spillslot index.
pub const MAX: usize = (1 << 24) - 1;
/// Create a new SpillSlot of a given class.
/// Create a new SpillSlot.
#[inline(always)]
pub fn new(slot: usize, class: RegClass) -> Self {
pub fn new(slot: usize) -> Self {
debug_assert!(slot <= Self::MAX);
SpillSlot {
bits: (slot as u32) | (class as u8 as u32) << 24,
}
SpillSlot { bits: slot as u32 }
}
/// Get the spillslot index for this spillslot.
@@ -339,20 +337,10 @@ impl SpillSlot {
(self.bits & 0x00ffffff) as usize
}
/// Get the class for this spillslot.
#[inline(always)]
pub fn class(self) -> RegClass {
match (self.bits >> 24) as u8 {
0 => RegClass::Int,
1 => RegClass::Float,
_ => unreachable!(),
}
}
/// Get the spillslot `offset` slots away.
#[inline(always)]
pub fn plus(self, offset: usize) -> Self {
SpillSlot::new(self.index() + offset, self.class())
SpillSlot::new(self.index() + offset)
}
/// Get the invalid spillslot, used for initializing data structures.
@@ -965,18 +953,6 @@ pub enum AllocationKind {
Stack = 2,
}
impl Allocation {
/// Get the register class of an allocation's value.
#[inline(always)]
pub fn class(self) -> RegClass {
match self.kind() {
AllocationKind::None => panic!("Allocation::None has no class"),
AllocationKind::Reg => self.as_reg().unwrap().class(),
AllocationKind::Stack => self.as_stack().unwrap().class(),
}
}
}
/// A trait defined by the regalloc client to provide access to its
/// machine-instruction / CFG representation.
///