Skip to content

Commit

Permalink
Unimplement ExactSizeIterator
Browse files Browse the repository at this point in the history
If root is not START_BLOCK, `basic_blocks().len() - visited` does not represent
their exact size.
  • Loading branch information
sinkuu committed Oct 22, 2018
1 parent 89be71a commit 80a6b73
Showing 1 changed file with 24 additions and 12 deletions.
36 changes: 24 additions & 12 deletions src/librustc/mir/traversal.rs
Expand Up @@ -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> {
Expand All @@ -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,
}
}
}
Expand Down Expand Up @@ -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
Expand All @@ -105,15 +111,17 @@ 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> {
pub fn new(mir: &'a Mir<'tcx>, root: BasicBlock) -> 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,
};


Expand Down Expand Up @@ -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.
Expand Down

0 comments on commit 80a6b73

Please sign in to comment.