Add fixed-non-allocatable operand support.
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
//! Debugging output.
|
//! Debugging output.
|
||||||
|
|
||||||
use super::Env;
|
use super::Env;
|
||||||
use crate::{Function, ProgPoint, Block};
|
use crate::{Block, Function, ProgPoint};
|
||||||
|
|
||||||
impl<'a, F: Function> Env<'a, F> {
|
impl<'a, F: Function> Env<'a, F> {
|
||||||
pub fn dump_state(&self) {
|
pub fn dump_state(&self) {
|
||||||
|
|||||||
@@ -272,6 +272,9 @@ impl<'a, F: Function> Env<'a, F> {
|
|||||||
|
|
||||||
for pos in &[OperandPos::After, OperandPos::Before] {
|
for pos in &[OperandPos::After, OperandPos::Before] {
|
||||||
for op in self.func.inst_operands(inst) {
|
for op in self.func.inst_operands(inst) {
|
||||||
|
if op.as_fixed().is_some() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if op.pos() == *pos {
|
if op.pos() == *pos {
|
||||||
let was_live = live.get(op.vreg().vreg());
|
let was_live = live.get(op.vreg().vreg());
|
||||||
log::debug!("op {:?} was_live = {}", op, was_live);
|
log::debug!("op {:?} was_live = {}", op, was_live);
|
||||||
@@ -868,6 +871,15 @@ impl<'a, F: Function> Env<'a, F> {
|
|||||||
operand
|
operand
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// If this is a "fixed non-allocatable
|
||||||
|
// register" operand, set the alloc
|
||||||
|
// immediately and then ignore the operand
|
||||||
|
// hereafter.
|
||||||
|
if let Some(preg) = operand.as_fixed() {
|
||||||
|
self.set_alloc(inst, i, Allocation::reg(preg));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
match operand.kind() {
|
match operand.kind() {
|
||||||
OperandKind::Def | OperandKind::Mod => {
|
OperandKind::Def | OperandKind::Mod => {
|
||||||
log::debug!("Def of {} at {:?}", operand.vreg(), pos);
|
log::debug!("Def of {} at {:?}", operand.vreg(), pos);
|
||||||
|
|||||||
30
src/lib.rs
30
src/lib.rs
@@ -144,6 +144,15 @@ impl VReg {
|
|||||||
pub fn invalid() -> Self {
|
pub fn invalid() -> Self {
|
||||||
VReg::new(Self::MAX, RegClass::Int)
|
VReg::new(Self::MAX, RegClass::Int)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn is_valid(self) -> bool {
|
||||||
|
self != Self::invalid()
|
||||||
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn is_invalid(self) -> bool {
|
||||||
|
self == Self::invalid()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for VReg {
|
impl std::fmt::Debug for VReg {
|
||||||
@@ -328,6 +337,19 @@ impl Operand {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create an Operand that always results in an assignment to the
|
||||||
|
/// given fixed `preg`, *without* tracking liveranges in that
|
||||||
|
/// `preg`. Must only be used for non-allocatable registers.
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn fixed(preg: PReg) -> Self {
|
||||||
|
Operand::new(
|
||||||
|
VReg::invalid(),
|
||||||
|
OperandPolicy::FixedReg(preg),
|
||||||
|
OperandKind::Use, // doesn't matter
|
||||||
|
OperandPos::Before, // doesn't matter
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn vreg(self) -> VReg {
|
pub fn vreg(self) -> VReg {
|
||||||
let vreg_idx = ((self.bits as usize) & VReg::MAX) as usize;
|
let vreg_idx = ((self.bits as usize) & VReg::MAX) as usize;
|
||||||
@@ -379,6 +401,14 @@ impl Operand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn as_fixed(self) -> Option<PReg> {
|
||||||
|
match (self.vreg().is_invalid(), self.policy()) {
|
||||||
|
(true, OperandPolicy::FixedReg(preg)) => Some(preg),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn bits(self) -> u32 {
|
pub fn bits(self) -> u32 {
|
||||||
self.bits
|
self.bits
|
||||||
|
|||||||
Reference in New Issue
Block a user