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

@@ -10,6 +10,15 @@ use regalloc2::fuzzing::moves::{MoveAndScratchResolver, ParallelMoves};
use regalloc2::{Allocation, PReg, RegClass, SpillSlot};
use std::collections::{HashMap, HashSet};
fn is_stack_alloc(alloc: Allocation) -> bool {
// Treat registers 20..=29 as fixed stack slots.
if let Some(reg) = alloc.as_reg() {
reg.index() > 20
} else {
alloc.is_stack()
}
}
#[derive(Clone, Debug)]
struct TestCase {
moves: Vec<(Allocation, Allocation)>,
@@ -82,7 +91,8 @@ fuzz_target!(|testcase: TestCase| {
Allocation::stack(SpillSlot::new(slot, RegClass::Int))
};
let preferred_victim = PReg::new(0, RegClass::Int);
let scratch_resolver = MoveAndScratchResolver::new(get_reg, get_stackslot, preferred_victim);
let scratch_resolver =
MoveAndScratchResolver::new(get_reg, get_stackslot, is_stack_alloc, preferred_victim);
let moves = scratch_resolver.compute(moves);
log::trace!("resolved moves: {:?}", moves);
@@ -97,7 +107,7 @@ fuzz_target!(|testcase: TestCase| {
// Simulate the sequence of moves.
let mut locations: HashMap<Allocation, Allocation> = HashMap::new();
for (src, dst, _) in moves {
if src.is_stack() && dst.is_stack() {
if is_stack_alloc(src) && is_stack_alloc(dst) {
panic!("Stack-to-stack move!");
}