diff options
| author | kennytm <kennytm@gmail.com> | 2018-10-26 18:25:02 +0800 |
|---|---|---|
| committer | kennytm <kennytm@gmail.com> | 2018-10-26 23:06:25 +0800 |
| commit | 9111fab74df4e0f6f2b8bfb5936f3772ba59a960 (patch) | |
| tree | 8242128230ababd385bb4fccf0de66c501f3d9e7 | |
| parent | 46f504543d47e18484a65251918a937147bb8a45 (diff) | |
| parent | 80a6b736acca2c109547e100d217fe5ca5f4ec30 (diff) | |
| download | rust-9111fab74df4e0f6f2b8bfb5936f3772ba59a960.tar.gz rust-9111fab74df4e0f6f2b8bfb5936f3772ba59a960.zip | |
Rollup merge of #55271 - sinkuu:traversal_iter, r=matthewjasper
Unimplement ExactSizeIterator for MIR traversing iterators If `root` is not `START_BLOCK`, `basic_blocks().len() - visited` does not represent their exact size.
| -rw-r--r-- | src/librustc/mir/traversal.rs | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/src/librustc/mir/traversal.rs b/src/librustc/mir/traversal.rs index db1bc3e7519..a1e2b7a0646 100644 --- a/src/librustc/mir/traversal.rs +++ b/src/librustc/mir/traversal.rs @@ -34,6 +34,7 @@ pub struct Preorder<'a, 'tcx: 'a> { mir: &'a Mir<'tcx>, visited: BitSet<BasicBlock>, worklist: Vec<BasicBlock>, + root_is_start_block: bool, } impl<'a, 'tcx> Preorder<'a, 'tcx> { @@ -44,6 +45,7 @@ impl<'a, 'tcx> Preorder<'a, 'tcx> { mir, visited: BitSet::new_empty(mir.basic_blocks().len()), worklist, + root_is_start_block: root == START_BLOCK, } } } @@ -75,15 +77,19 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> { fn size_hint(&self) -> (usize, Option<usize>) { // All the blocks, minus the number of blocks we've visited. - let remaining = self.mir.basic_blocks().len() - self.visited.count(); + let upper = self.mir.basic_blocks().len() - self.visited.count(); - // We will visit all remaining blocks exactly once. - (remaining, Some(remaining)) + let lower = if self.root_is_start_block { + // We will visit all remaining blocks exactly once. + upper + } else { + self.worklist.len() + }; + + (lower, Some(upper)) } } -impl<'a, 'tcx> ExactSizeIterator for Preorder<'a, 'tcx> {} - /// Postorder traversal of a graph. /// /// Postorder traversal is when each node is visited after all of it's @@ -105,7 +111,8 @@ impl<'a, 'tcx> ExactSizeIterator for Preorder<'a, 'tcx> {} pub struct Postorder<'a, 'tcx: 'a> { mir: &'a Mir<'tcx>, visited: BitSet<BasicBlock>, - visit_stack: Vec<(BasicBlock, Successors<'a>)> + visit_stack: Vec<(BasicBlock, Successors<'a>)>, + root_is_start_block: bool, } impl<'a, 'tcx> Postorder<'a, 'tcx> { @@ -113,7 +120,8 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> { let mut po = Postorder { mir, visited: BitSet::new_empty(mir.basic_blocks().len()), - visit_stack: Vec::new() + visit_stack: Vec::new(), + root_is_start_block: root == START_BLOCK, }; @@ -214,15 +222,19 @@ impl<'a, 'tcx> Iterator for Postorder<'a, 'tcx> { fn size_hint(&self) -> (usize, Option<usize>) { // All the blocks, minus the number of blocks we've visited. - let remaining = self.mir.basic_blocks().len() - self.visited.count(); + let upper = self.mir.basic_blocks().len() - self.visited.count(); - // We will visit all remaining blocks exactly once. - (remaining, Some(remaining)) + let lower = if self.root_is_start_block { + // We will visit all remaining blocks exactly once. + upper + } else { + self.visit_stack.len() + }; + + (lower, Some(upper)) } } -impl<'a, 'tcx> ExactSizeIterator for Postorder<'a, 'tcx> {} - /// Reverse postorder traversal of a graph /// /// Reverse postorder is the reverse order of a postorder traversal. |
