Skip to content

Commit

Permalink
checkpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
elliottt committed Nov 1, 2022
1 parent 56014ea commit 528e71e
Showing 1 changed file with 36 additions and 20 deletions.
56 changes: 36 additions & 20 deletions cranelift/codegen/src/machinst/reg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,24 +293,10 @@ pub struct OperandCollector<'a, 'env, F: Fn(VReg) -> VReg> {
renamer: F,
}

macro_rules! debug_assert_allocatable {
($env:expr, $reg:expr) => {
if cfg!(debug_assertions) {
let class = $reg.class() as usize;
if let Some(reg) = pinned_vreg_to_preg($reg) {
assert!(
$env.preferred_regs_by_class[class]
.iter()
.copied()
.any(|r| r == reg)
|| $env.non_preferred_regs_by_class[class]
.iter()
.copied()
.any(|r| r == reg)
);
}
}
};
macro_rules! debug_assert_is_virtual {
($reg:expr) => {
debug_assert!($reg.is_virtual(), "`{:?}` was used, but is not virtual", $reg);
}
}

impl<'a, 'env, F: Fn(VReg) -> VReg> OperandCollector<'a, 'env, F> {
Expand All @@ -326,6 +312,22 @@ impl<'a, 'env, F: Fn(VReg) -> VReg> OperandCollector<'a, 'env, F> {
}
}

pub fn is_allocatable_preg(&self, reg: PReg) -> bool {
let class = reg.class() as usize;
self.machine_env.preferred_regs_by_class[class]
.iter()
.copied()
.any(|r| r == reg)
|| self.machine_env.non_preferred_regs_by_class[class]
.iter()
.copied()
.any(|r| r == reg)
}

pub fn is_allocatable_reg(&self, reg: Reg) -> bool {
pinned_vreg_to_preg(reg.0).map_or(false, |preg| self.is_allocatable_preg(preg))
}

/// Add an operand.
fn add_operand(&mut self, operand: Operand) {
let vreg = (self.renamer)(operand.vreg());
Expand All @@ -345,17 +347,20 @@ impl<'a, 'env, F: Fn(VReg) -> VReg> OperandCollector<'a, 'env, F> {
/// Add a register use, at the start of the instruction (`Before`
/// position).
pub fn reg_use(&mut self, reg: Reg) {
debug_assert_is_virtual!(reg);
self.add_operand(Operand::reg_use(reg.into()));
}

/// Add a register use, at the end of the instruction (`After` position).
pub fn reg_late_use(&mut self, reg: Reg) {
debug_assert_is_virtual!(reg);
self.add_operand(Operand::reg_use_at_end(reg.into()));
}

/// Add multiple register uses.
pub fn reg_uses(&mut self, regs: &[Reg]) {
for &reg in regs {
debug_assert_is_virtual!(reg);
self.reg_use(reg);
}
}
Expand All @@ -364,12 +369,14 @@ impl<'a, 'env, F: Fn(VReg) -> VReg> OperandCollector<'a, 'env, F> {
/// position). Use only when this def will be written after all
/// uses are read.
pub fn reg_def(&mut self, reg: Writable<Reg>) {
debug_assert_is_virtual!(reg.to_reg());
self.add_operand(Operand::reg_def(reg.to_reg().into()));
}

/// Add multiple register defs.
pub fn reg_defs(&mut self, regs: &[Writable<Reg>]) {
for &reg in regs {
debug_assert_is_virtual!(reg.to_reg());
self.reg_def(reg);
}
}
Expand All @@ -379,21 +386,24 @@ impl<'a, 'env, F: Fn(VReg) -> VReg> OperandCollector<'a, 'env, F> {
/// when the def may be written before all uses are read; the
/// regalloc will ensure that it does not overwrite any uses.
pub fn reg_early_def(&mut self, reg: Writable<Reg>) {
debug_assert_is_virtual!(reg.to_reg());
self.add_operand(Operand::reg_def_at_start(reg.to_reg().into()));
}

/// Add a register "fixed use", which ties a vreg to a particular
/// RealReg at this point.
pub fn reg_fixed_use(&mut self, reg: Reg, rreg: Reg) {
debug_assert_allocatable!(self.machine_env, rreg.0);
debug_assert_is_virtual!(reg);
debug_assert!(self.is_allocatable_reg(rreg));
let rreg = rreg.to_real_reg().expect("fixed reg is not a RealReg");
self.add_operand(Operand::reg_fixed_use(reg.into(), rreg.into()));
}

/// Add a register "fixed def", which ties a vreg to a particular
/// RealReg at this point.
pub fn reg_fixed_def(&mut self, reg: Writable<Reg>, rreg: Reg) {
debug_assert_allocatable!(self.machine_env, rreg.0);
debug_assert_is_virtual!(reg.to_reg());
debug_assert!(self.is_allocatable_reg(rreg));
let rreg = rreg.to_real_reg().expect("fixed reg is not a RealReg");
self.add_operand(Operand::reg_fixed_def(reg.to_reg().into(), rreg.into()));
}
Expand All @@ -402,6 +412,7 @@ impl<'a, 'env, F: Fn(VReg) -> VReg> OperandCollector<'a, 'env, F> {
/// allocation. The index of that earlier operand (relative to the
/// current instruction's start of operands) must be known.
pub fn reg_reuse_def(&mut self, reg: Writable<Reg>, idx: usize) {
debug_assert_is_virtual!(reg.to_reg());
if reg.to_reg().to_virtual_reg().is_some() {
self.add_operand(Operand::reg_reuse_def(reg.to_reg().into(), idx));
} else {
Expand All @@ -417,6 +428,11 @@ impl<'a, 'env, F: Fn(VReg) -> VReg> OperandCollector<'a, 'env, F> {
/// are written by the instruction, so must be reserved (not used)
/// for the whole instruction, but are not used afterward.
pub fn reg_clobbers(&mut self, regs: PRegSet) {
if cfg!(debug_assertions) {
for reg in regs.clone() {
debug_assert!(self.is_allocatable_preg(reg));
}
}
self.clobbers.union_from(regs);
}
}
Expand Down

0 comments on commit 528e71e

Please sign in to comment.