Support program moves, including pinned vregs, in the checker. (#43)
The checker was built to validate programs produced by the fuzzing testcase generator, which was built before regalloc2 supported special handling of moves. (In a pure-SSA world, move elision is not needed, because moves are not needed, and blockparams are the only way of tying together vregs.) Due to this, the checker works great for our independent regalloc2 fuzzing setup, but when used on regalloc inputs produced by Cranelift, cannot prove correctness. This PR extends the checker's analysis to properly handle "program moves", which are distinct from regalloc-inserted moves in that they are present in the original program and hence are semantically relevant. A program move edits all sets of symbolic vregs at all allocs, and where the source vreg appears, it inserts the dest vreg as well. (It also removes the dest vreg from all other sets, since the old value becomes stale, as is done for other defs.) Given this, and given some additional checking for moves to/from pinned vregs, the checker can now be used to fully validate Cranelift-sourced regalloc2 invocations.
This commit is contained in:
26
src/lib.rs
26
src/lib.rs
@@ -582,6 +582,32 @@ impl Operand {
|
||||
)
|
||||
}
|
||||
|
||||
/// Create an `Operand` that designates a use of a vreg and places
|
||||
/// no constraints on its location (i.e., it can be allocated into
|
||||
/// either a register or on the stack).
|
||||
#[inline(always)]
|
||||
pub fn any_use(vreg: VReg) -> Self {
|
||||
Operand::new(
|
||||
vreg,
|
||||
OperandConstraint::Any,
|
||||
OperandKind::Use,
|
||||
OperandPos::Early,
|
||||
)
|
||||
}
|
||||
|
||||
/// Create an `Operand` that designates a def of a vreg and places
|
||||
/// no constraints on its location (i.e., it can be allocated into
|
||||
/// either a register or on the stack).
|
||||
#[inline(always)]
|
||||
pub fn any_def(vreg: VReg) -> Self {
|
||||
Operand::new(
|
||||
vreg,
|
||||
OperandConstraint::Any,
|
||||
OperandKind::Def,
|
||||
OperandPos::Late,
|
||||
)
|
||||
}
|
||||
|
||||
/// Get the virtual register designated by an operand. Every
|
||||
/// operand must name some virtual register, even if it constrains
|
||||
/// the operand to a fixed physical register as well; the vregs
|
||||
|
||||
Reference in New Issue
Block a user