make traversal::reverse_postorder use RPO cache
This commit is contained in:
@@ -295,34 +295,11 @@ pub fn reachable_as_bitset(body: &Body<'_>) -> BitSet<BasicBlock> {
|
|||||||
iter.visited
|
iter.visited
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
/// Creates an iterator over the `Body`'s basic blocks, that:
|
||||||
pub struct ReversePostorderIter<'a, 'tcx> {
|
/// - returns basic blocks in a reverse postorder,
|
||||||
|
/// - makes use of the `BasicBlocks` CFG cache's reverse postorder.
|
||||||
|
pub fn reverse_postorder<'a, 'tcx>(
|
||||||
body: &'a Body<'tcx>,
|
body: &'a Body<'tcx>,
|
||||||
blocks: &'a [BasicBlock],
|
) -> impl Iterator<Item = (BasicBlock, &'a BasicBlockData<'tcx>)> + ExactSizeIterator {
|
||||||
idx: usize,
|
body.basic_blocks.reverse_postorder().iter().map(|&bb| (bb, &body.basic_blocks[bb]))
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'tcx> Iterator for ReversePostorderIter<'a, 'tcx> {
|
|
||||||
type Item = (BasicBlock, &'a BasicBlockData<'tcx>);
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<(BasicBlock, &'a BasicBlockData<'tcx>)> {
|
|
||||||
if self.idx == 0 {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
self.idx -= 1;
|
|
||||||
|
|
||||||
self.blocks.get(self.idx).map(|&bb| (bb, &self.body[bb]))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
||||||
(self.idx, Some(self.idx))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'tcx> ExactSizeIterator for ReversePostorderIter<'a, 'tcx> {}
|
|
||||||
|
|
||||||
pub fn reverse_postorder<'a, 'tcx>(body: &'a Body<'tcx>) -> ReversePostorderIter<'a, 'tcx> {
|
|
||||||
let blocks = body.basic_blocks.postorder();
|
|
||||||
let len = blocks.len();
|
|
||||||
ReversePostorderIter { body, blocks, idx: len }
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user