use crate::Constrain;
use crate::Iterable;
use crate::Sequence;
pub trait Peephole {
fn modify(&mut self) -> bool {
unreachable!();
}
fn check(_a: &Self, _b: &Self) -> bool {
false
}
}
#[derive(Debug, Default)]
pub struct PeepholeOptimizer<Insn>
where
Insn: Peephole,
{
i: std::marker::PhantomData<Insn>,
}
impl<Insn> PeepholeOptimizer<Insn>
where
Insn: Peephole,
{
fn check(&self, seq: &Sequence<Insn>, offset: usize) -> bool {
if offset >= seq.len() - 1 {
false
} else {
Insn::check(&seq[offset], &seq[offset + 1])
}
}
}
impl<Insn> Constrain<Insn> for PeepholeOptimizer<Insn>
where
Insn: Peephole + Iterable,
{
fn fixup(&self, seq: &mut Sequence<Insn>) -> Option<(usize, &'static str)> {
for offset in 0..(seq.len() - 1) {
if self.check(seq, offset) {
seq.mut_at(Insn::modify, offset);
return Some((offset, "peephole"));
}
}
None
}
}