Remove mod operands. (#109)

* Remove Mod operands.

* Typo fix.
This commit is contained in:
Chris Fallin
2023-01-24 17:41:46 -08:00
committed by GitHub
parent e09f6519a6
commit 0edb11d3a7
4 changed files with 19 additions and 34 deletions

View File

@@ -373,7 +373,7 @@ impl<'a, F: Function> Env<'a, F> {
let was_live = live.get(op.vreg().vreg()); let was_live = live.get(op.vreg().vreg());
trace!("op {:?} was_live = {}", op, was_live); trace!("op {:?} was_live = {}", op, was_live);
match op.kind() { match op.kind() {
OperandKind::Use | OperandKind::Mod => { OperandKind::Use => {
live.set(op.vreg().vreg(), true); live.set(op.vreg().vreg(), true);
} }
OperandKind::Def => { OperandKind::Def => {
@@ -776,7 +776,6 @@ impl<'a, F: Function> Env<'a, F> {
.cloned() .cloned()
.unwrap_or(self.func.inst_operands(inst)[i]); .unwrap_or(self.func.inst_operands(inst)[i]);
let pos = match (operand.kind(), operand.pos()) { let pos = match (operand.kind(), operand.pos()) {
(OperandKind::Mod, _) => ProgPoint::before(inst),
(OperandKind::Def, OperandPos::Early) => ProgPoint::before(inst), (OperandKind::Def, OperandPos::Early) => ProgPoint::before(inst),
(OperandKind::Def, OperandPos::Late) => ProgPoint::after(inst), (OperandKind::Def, OperandPos::Late) => ProgPoint::after(inst),
(OperandKind::Use, OperandPos::Late) => ProgPoint::after(inst), (OperandKind::Use, OperandPos::Late) => ProgPoint::after(inst),
@@ -817,7 +816,7 @@ impl<'a, F: Function> Env<'a, F> {
} }
match operand.kind() { match operand.kind() {
OperandKind::Def | OperandKind::Mod => { OperandKind::Def => {
trace!("Def of {} at {:?}", operand.vreg(), pos); trace!("Def of {} at {:?}", operand.vreg(), pos);
// Get or create the LiveRange. // Get or create the LiveRange.
@@ -825,11 +824,7 @@ impl<'a, F: Function> Env<'a, F> {
trace!(" -> has existing LR {:?}", lr); trace!(" -> has existing LR {:?}", lr);
// If there was no liverange (dead def), create a trivial one. // If there was no liverange (dead def), create a trivial one.
if !live.get(operand.vreg().vreg()) { if !live.get(operand.vreg().vreg()) {
let from = match operand.kind() { let from = pos;
OperandKind::Def => pos,
OperandKind::Mod => self.cfginfo.block_entry[block.index()],
_ => unreachable!(),
};
// We want to we want to span // We want to we want to span
// until Before of the next // until Before of the next
// inst. This ensures that early // inst. This ensures that early

View File

@@ -906,7 +906,7 @@ impl<'a, F: Function> Env<'a, F> {
let inst = Inst::new(inst); let inst = Inst::new(inst);
for (i, op) in this.func.inst_operands(inst).iter().enumerate() { for (i, op) in this.func.inst_operands(inst).iter().enumerate() {
match op.kind() { match op.kind() {
OperandKind::Def | OperandKind::Mod => { OperandKind::Def => {
let alloc = this.get_alloc(inst, i); let alloc = this.get_alloc(inst, i);
redundant_moves.clear_alloc(alloc); redundant_moves.clear_alloc(alloc);
} }

View File

@@ -426,14 +426,13 @@ impl std::fmt::Display for OperandConstraint {
} }
} }
/// The "kind" of the operand: whether it reads a vreg (Use), writes a /// The "kind" of the operand: whether it reads a vreg (Use) or writes
/// vreg (Def), or reads and then writes (Mod, for "modify"). /// a vreg (Def).
#[derive(Clone, Copy, Debug, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
pub enum OperandKind { pub enum OperandKind {
Def = 0, Def = 0,
Mod = 1, Use = 1,
Use = 2,
} }
/// The "position" of the operand: where it has its read/write /// The "position" of the operand: where it has its read/write
@@ -488,7 +487,7 @@ pub enum OperandPos {
pub struct Operand { pub struct Operand {
/// Bit-pack into 32 bits. /// Bit-pack into 32 bits.
/// ///
/// constraint:7 kind:2 pos:1 class:1 vreg:21 /// constraint:7 kind:1 pos:1 class:2 vreg:21
/// ///
/// where `constraint` is an `OperandConstraint`, `kind` is an /// where `constraint` is an `OperandConstraint`, `kind` is an
/// `OperandKind`, `pos` is an `OperandPos`, `class` is a /// `OperandKind`, `pos` is an `OperandPos`, `class` is a
@@ -532,8 +531,8 @@ impl Operand {
Operand { Operand {
bits: vreg.vreg() as u32 bits: vreg.vreg() as u32
| (class_field << 21) | (class_field << 21)
| (pos_field << 22) | (pos_field << 23)
| (kind_field << 23) | (kind_field << 24)
| (constraint_field << 25), | (constraint_field << 25),
} }
} }
@@ -719,7 +718,7 @@ impl Operand {
/// Get the register class used by this operand. /// Get the register class used by this operand.
#[inline(always)] #[inline(always)]
pub fn class(self) -> RegClass { pub fn class(self) -> RegClass {
let class_field = (self.bits >> 21) & 1; let class_field = (self.bits >> 21) & 3;
match class_field { match class_field {
0 => RegClass::Int, 0 => RegClass::Int,
1 => RegClass::Float, 1 => RegClass::Float,
@@ -727,15 +726,14 @@ impl Operand {
} }
} }
/// Get the "kind" of this operand: a definition (write), a use /// Get the "kind" of this operand: a definition (write) or a use
/// (read), or a "mod" / modify (a read followed by a write). /// (read).
#[inline(always)] #[inline(always)]
pub fn kind(self) -> OperandKind { pub fn kind(self) -> OperandKind {
let kind_field = (self.bits >> 23) & 3; let kind_field = (self.bits >> 24) & 1;
match kind_field { match kind_field {
0 => OperandKind::Def, 0 => OperandKind::Def,
1 => OperandKind::Mod, 1 => OperandKind::Use,
2 => OperandKind::Use,
_ => unreachable!(), _ => unreachable!(),
} }
} }
@@ -746,7 +744,7 @@ impl Operand {
/// at "after", though there are cases where this is not true. /// at "after", though there are cases where this is not true.
#[inline(always)] #[inline(always)]
pub fn pos(self) -> OperandPos { pub fn pos(self) -> OperandPos {
let pos_field = (self.bits >> 22) & 1; let pos_field = (self.bits >> 23) & 1;
match pos_field { match pos_field {
0 => OperandPos::Early, 0 => OperandPos::Early,
1 => OperandPos::Late, 1 => OperandPos::Late,
@@ -808,8 +806,7 @@ impl std::fmt::Debug for Operand {
impl std::fmt::Display for Operand { impl std::fmt::Display for Operand {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match (self.kind(), self.pos()) { match (self.kind(), self.pos()) {
(OperandKind::Def, OperandPos::Late) (OperandKind::Def, OperandPos::Late) | (OperandKind::Use, OperandPos::Early) => {
| (OperandKind::Mod | OperandKind::Use, OperandPos::Early) => {
write!(f, "{:?}", self.kind())?; write!(f, "{:?}", self.kind())?;
} }
_ => { _ => {
@@ -1058,8 +1055,8 @@ pub trait Function {
/// it in a given PReg chosen by the client prior to regalloc. /// it in a given PReg chosen by the client prior to regalloc.
/// ///
/// Every register written by an instruction must either /// Every register written by an instruction must either
/// correspond to (be assigned to) an Operand of kind `Def` or /// correspond to (be assigned to) an Operand of kind `Def`, or
/// `Mod`, or else must be a "clobber". /// else must be a "clobber".
/// ///
/// This can be used to, for example, describe ABI-specified /// This can be used to, for example, describe ABI-specified
/// registers that are not preserved by a call instruction, or /// registers that are not preserved by a call instruction, or

View File

@@ -73,13 +73,6 @@ pub fn validate_ssa<F: Function>(f: &F, cfginfo: &CFGInfo) -> Result<(), RegAllo
// Check all the uses in this instruction // Check all the uses in this instruction
// first, before recording its defs below. // first, before recording its defs below.
} }
OperandKind::Mod => {
// Mod (modify) operands are not used in SSA,
// but can be used by non-SSA code (e.g. with
// the regalloc.rs compatibility shim).
trace!("Unexpected mod {:?}", operand.vreg());
return Err(RegAllocError::SSA(operand.vreg(), iix));
}
} }
} }