Skip to content

Commit 0b4b086

Browse files
committed
make traversal::postorder traverse RPO cache backwards
1 parent 0eec39b commit 0b4b086

File tree

1 file changed

+36
-4
lines changed

1 file changed

+36
-4
lines changed

compiler/rustc_middle/src/mir/traversal.rs

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -188,10 +188,6 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> {
188188
}
189189
}
190190

191-
pub fn postorder<'a, 'tcx>(body: &'a Body<'tcx>) -> Postorder<'a, 'tcx> {
192-
Postorder::new(&body.basic_blocks, START_BLOCK)
193-
}
194-
195191
impl<'a, 'tcx> Iterator for Postorder<'a, 'tcx> {
196192
type Item = (BasicBlock, &'a BasicBlockData<'tcx>);
197193

@@ -219,6 +215,42 @@ impl<'a, 'tcx> Iterator for Postorder<'a, 'tcx> {
219215
}
220216
}
221217

218+
/// Creates an iterator over the `Body`'s basic blocks, that:
219+
/// - returns basic blocks in a postorder,
220+
/// - traverses the `BasicBlocks` CFG cache's reverse postorder backwards, and does not cache the
221+
/// postorder itself.
222+
pub fn postorder<'a, 'tcx>(body: &'a Body<'tcx>) -> PostorderIter<'a, 'tcx> {
223+
let blocks = body.basic_blocks.reverse_postorder();
224+
let len = blocks.len();
225+
PostorderIter { body, blocks, idx: len }
226+
}
227+
228+
#[derive(Clone)]
229+
pub struct PostorderIter<'a, 'tcx> {
230+
body: &'a Body<'tcx>,
231+
blocks: &'a [BasicBlock],
232+
idx: usize,
233+
}
234+
235+
impl<'a, 'tcx> Iterator for PostorderIter<'a, 'tcx> {
236+
type Item = (BasicBlock, &'a BasicBlockData<'tcx>);
237+
238+
fn next(&mut self) -> Option<(BasicBlock, &'a BasicBlockData<'tcx>)> {
239+
if self.idx == 0 {
240+
return None;
241+
}
242+
self.idx -= 1;
243+
244+
self.blocks.get(self.idx).map(|&bb| (bb, &self.body[bb]))
245+
}
246+
247+
fn size_hint(&self) -> (usize, Option<usize>) {
248+
(self.idx, Some(self.idx))
249+
}
250+
}
251+
252+
impl<'a, 'tcx> ExactSizeIterator for PostorderIter<'a, 'tcx> {}
253+
222254
/// Reverse postorder traversal of a graph
223255
///
224256
/// Reverse postorder is the reverse order of a postorder traversal.

0 commit comments

Comments
 (0)