Implement DoubleEndedIterator for the ebb_insts() iterator.
Make it possible to iterate backwards over the instructions in an EBB.
This commit is contained in:
@@ -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])]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user