diff options
| author | Rémy Rakic <remy.rakic+github@gmail.com> | 2023-06-14 20:00:23 +0000 |
|---|---|---|
| committer | Rémy Rakic <remy.rakic+github@gmail.com> | 2023-06-14 23:01:36 +0000 |
| commit | 0b4b0869a7968a2612c9bd93019a021ce168c557 (patch) | |
| tree | a24bb47f52b32279152058dfd84d813eb58c28c6 /compiler/rustc_middle/src/mir/traversal.rs | |
| parent | 0eec39b67d12d121095a1da4e24109ce4dc41054 (diff) | |
| download | rust-0b4b0869a7968a2612c9bd93019a021ce168c557.tar.gz rust-0b4b0869a7968a2612c9bd93019a021ce168c557.zip | |
make `traversal::postorder` traverse RPO cache backwards
Diffstat (limited to 'compiler/rustc_middle/src/mir/traversal.rs')
| -rw-r--r-- | compiler/rustc_middle/src/mir/traversal.rs | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/compiler/rustc_middle/src/mir/traversal.rs b/compiler/rustc_middle/src/mir/traversal.rs index 780003f5fa0..6d44234d11f 100644 --- a/compiler/rustc_middle/src/mir/traversal.rs +++ b/compiler/rustc_middle/src/mir/traversal.rs @@ -188,10 +188,6 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> { } } -pub fn postorder<'a, 'tcx>(body: &'a Body<'tcx>) -> Postorder<'a, 'tcx> { - Postorder::new(&body.basic_blocks, START_BLOCK) -} - impl<'a, 'tcx> Iterator for Postorder<'a, 'tcx> { type Item = (BasicBlock, &'a BasicBlockData<'tcx>); @@ -219,6 +215,42 @@ impl<'a, 'tcx> Iterator for Postorder<'a, 'tcx> { } } +/// Creates an iterator over the `Body`'s basic blocks, that: +/// - returns basic blocks in a postorder, +/// - traverses the `BasicBlocks` CFG cache's reverse postorder backwards, and does not cache the +/// postorder itself. +pub fn postorder<'a, 'tcx>(body: &'a Body<'tcx>) -> PostorderIter<'a, 'tcx> { + let blocks = body.basic_blocks.reverse_postorder(); + let len = blocks.len(); + PostorderIter { body, blocks, idx: len } +} + +#[derive(Clone)] +pub struct PostorderIter<'a, 'tcx> { + body: &'a Body<'tcx>, + blocks: &'a [BasicBlock], + idx: usize, +} + +impl<'a, 'tcx> Iterator for PostorderIter<'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 PostorderIter<'a, 'tcx> {} + /// Reverse postorder traversal of a graph /// /// Reverse postorder is the reverse order of a postorder traversal. |
