Handle fixed stack slots in the move resolver (#78)

Fixed stack slots are treated as `PReg`s by most of the register
allocator, but need some additional handling the move resolver to avoid
generating stack-to-stack moves.
This commit is contained in:
Amanieu d'Antras
2022-09-20 03:27:24 +08:00
committed by GitHub
parent 1495c1e342
commit 520cafa129
5 changed files with 75 additions and 23 deletions

View File

@@ -97,7 +97,7 @@
use crate::{
Allocation, AllocationKind, Block, Edit, Function, Inst, InstOrEdit, InstPosition, MachineEnv,
Operand, OperandConstraint, OperandKind, OperandPos, Output, PReg, VReg,
Operand, OperandConstraint, OperandKind, OperandPos, Output, PReg, PRegSet, VReg,
};
use fxhash::{FxHashMap, FxHashSet};
use smallvec::{smallvec, SmallVec};
@@ -169,6 +169,10 @@ pub enum CheckerError {
alloc: Allocation,
vregs: FxHashSet<VReg>,
},
StackToStackMove {
into: Allocation,
from: Allocation,
},
}
/// Abstract state for an allocation.
@@ -560,7 +564,20 @@ impl CheckerState {
}
}
}
&CheckerInst::ParallelMove { .. } | &CheckerInst::Move { .. } => {
&CheckerInst::Move { into, from } => {
// Ensure that the allocator never returns stack-to-stack moves.
let is_stack = |alloc: Allocation| {
if let Some(reg) = alloc.as_reg() {
checker.stack_pregs.contains(reg)
} else {
alloc.is_stack()
}
};
if is_stack(into) && is_stack(from) {
return Err(CheckerError::StackToStackMove { into, from });
}
}
&CheckerInst::ParallelMove { .. } => {
// This doesn't need verification; we just update
// according to the move semantics in the step
// function below.
@@ -813,6 +830,7 @@ pub struct Checker<'a, F: Function> {
edge_insts: FxHashMap<(Block, Block), Vec<CheckerInst>>,
reftyped_vregs: FxHashSet<VReg>,
machine_env: &'a MachineEnv,
stack_pregs: PRegSet,
}
impl<'a, F: Function> Checker<'a, F> {
@@ -841,6 +859,11 @@ impl<'a, F: Function> Checker<'a, F> {
bb_in.insert(f.entry_block(), CheckerState::initial_with_pinned_vregs(f));
let mut stack_pregs = PRegSet::empty();
for &preg in &machine_env.fixed_stack_slots {
stack_pregs.add(preg);
}
Checker {
f,
bb_in,
@@ -848,6 +871,7 @@ impl<'a, F: Function> Checker<'a, F> {
edge_insts,
reftyped_vregs,
machine_env,
stack_pregs,
}
}