Browse Source

Implement DoubleEndedIterator for the ebb_insts() iterator.

Make it possible to iterate backwards over the instructions in an EBB.
pull/3/head
Jakob Stoklund Olesen 8 years ago
parent
commit
8390c829d3
  1. 38
      lib/cretonne/src/ir/layout.rs

38
lib/cretonne/src/ir/layout.rs

@ -452,7 +452,8 @@ impl Layout {
pub fn ebb_insts<'f>(&'f self, ebb: Ebb) -> Insts<'f> {
Insts {
layout: self,
next: self.ebbs[ebb].first_inst.wrap(),
head: self.ebbs[ebb].first_inst.wrap(),
tail: self.ebbs[ebb].last_inst.wrap(),
}
}
@ -535,20 +536,39 @@ struct InstNode {
/// Iterate over instructions in an EBB in layout order. See `Layout::ebb_insts()`.
pub struct Insts<'f> {
layout: &'f Layout,
next: Option<Inst>,
head: Option<Inst>,
tail: Option<Inst>,
}
impl<'f> Iterator for Insts<'f> {
type Item = Inst;
fn next(&mut self) -> Option<Inst> {
match self.next {
Some(inst) => {
self.next = self.layout.insts[inst].next.wrap();
Some(inst)
let rval = self.head;
if let Some(inst) = rval {
if self.head == self.tail {
self.head = None;
self.tail = None;
} else {
self.head = Some(self.layout.insts[inst].next);
}
None => None,
}
rval
}
}
impl<'f> DoubleEndedIterator for Insts<'f> {
fn next_back(&mut self) -> Option<Inst> {
let rval = self.tail;
if let Some(inst) = rval {
if self.head == self.tail {
self.head = None;
self.tail = None;
} else {
self.tail = Some(self.layout.insts[inst].prev);
}
}
rval
}
}
@ -1077,6 +1097,10 @@ mod tests {
let v: Vec<Inst> = layout.ebb_insts(e1).collect();
assert_eq!(v, [i1, i2]);
// Test double-ended instruction iterator.
let v: Vec<Inst> = layout.ebb_insts(e1).rev().collect();
assert_eq!(v, [i2, i1]);
layout.append_inst(i0, e1);
verify(&mut layout, &[(e1, &[i1, i2, i0])]);

Loading…
Cancel
Save