pub struct MoveResolver { /* private fields */ }Expand description
Resolves parallel copies. Keeps its buffers between calls.
§Examples
A rotation of three registers and a register into a slot, with a free register to break the cycle when swaps are off:
use backend_lang::RegSet;
use backend_lang::mir::StackSlot;
use backend_lang::moves::{Loc, Move, MoveEnv, MoveResolver, Source, Step};
use backend_lang::x86_64::{self, GPR, RAX, RBX, RCX, R11};
let moves = [
Move::new(RAX, RBX, GPR),
Move::new(RBX, RCX, GPR),
Move::new(RCX, RAX, GPR),
Move::new(StackSlot::new(0), RAX, GPR),
];
let env = MoveEnv::new().with_free(RegSet::of(&[R11])).with_swap(false);
let mut steps = Vec::new();
MoveResolver::new().resolve(&x86_64::TARGET, &moves, &env, &mut steps)?;
// The slot copy of rax doubles as the cycle's saved value: four moves.
assert_eq!(steps.len(), 4);
assert_eq!(steps[0], Step::Move { dst: Loc::Slot(StackSlot::new(0)), src: Source::from(RAX), class: GPR });Implementations§
Source§impl MoveResolver
impl MoveResolver
Sourcepub fn new() -> MoveResolver
pub fn new() -> MoveResolver
A resolver with empty buffers.
§Examples
use backend_lang::moves::MoveResolver;
let _r = MoveResolver::new();Sourcepub fn resolve(
&mut self,
target: &Target,
moves: &[Move],
env: &MoveEnv,
out: &mut Vec<Step>,
) -> Result<Resolved, MoveError>
pub fn resolve( &mut self, target: &Target, moves: &[Move], env: &MoveEnv, out: &mut Vec<Step>, ) -> Result<Resolved, MoveError>
Resolves the parallel copy moves on target, appending the steps to
out.
Moves whose source is their destination are dropped. Executing the
appended steps in order leaves every destination holding its source’s
value from before the copy, and every other location unchanged except
env.free registers (which are dead) and the scratch and victim
slots.
§Errors
MoveError::DuplicateDestination, MoveError::ClassMismatch,
MoveError::NoScratch or MoveError::NoTemp when a scratch or
temporary is needed and env provides none, MoveError::TooMany.
On error, out may hold a partial sequence; discard it.
§Examples
use backend_lang::mir::StackSlot;
use backend_lang::moves::{Loc, Move, MoveEnv, MoveResolver, Source, Step};
use backend_lang::x86_64::{self, GPR, RAX, R11};
use backend_lang::RegSet;
// Slot to slot on x86-64 goes through a register.
let copy = [Move::new(StackSlot::new(1), StackSlot::new(0), GPR)];
let env = MoveEnv::new().with_free(RegSet::of(&[R11]));
let mut out = Vec::new();
MoveResolver::new().resolve(&x86_64::TARGET, ©, &env, &mut out)?;
assert_eq!(out, [
Step::Move { dst: Loc::Reg(R11), src: Source::from(StackSlot::new(0)), class: GPR },
Step::Move { dst: Loc::Slot(StackSlot::new(1)), src: Source::from(R11), class: GPR },
]);