@@ -22,27 +22,41 @@ use super::*;
2222/// A preorder traversal of this graph is either `A B D C` or `A C D B`
2323#[ derive( Clone ) ]
2424pub struct Preorder < ' a , ' tcx > {
25- body : & ' a Body < ' tcx > ,
25+ basic_blocks : & ' a IndexSlice < BasicBlock , BasicBlockData < ' tcx > > ,
2626 visited : BitSet < BasicBlock > ,
2727 worklist : Vec < BasicBlock > ,
2828 root_is_start_block : bool ,
2929}
3030
3131impl < ' a , ' tcx > Preorder < ' a , ' tcx > {
32- pub fn new ( body : & ' a Body < ' tcx > , root : BasicBlock ) -> Preorder < ' a , ' tcx > {
32+ pub fn new (
33+ basic_blocks : & ' a IndexSlice < BasicBlock , BasicBlockData < ' tcx > > ,
34+ root : BasicBlock ,
35+ ) -> Preorder < ' a , ' tcx > {
3336 let worklist = vec ! [ root] ;
3437
3538 Preorder {
36- body ,
37- visited : BitSet :: new_empty ( body . basic_blocks . len ( ) ) ,
39+ basic_blocks ,
40+ visited : BitSet :: new_empty ( basic_blocks. len ( ) ) ,
3841 worklist,
3942 root_is_start_block : root == START_BLOCK ,
4043 }
4144 }
45+
46+ pub ( super ) fn into_visited ( self ) -> BitSet < BasicBlock > {
47+ self . visited
48+ }
4249}
4350
44- pub fn preorder < ' a , ' tcx > ( body : & ' a Body < ' tcx > ) -> Preorder < ' a , ' tcx > {
45- Preorder :: new ( body, START_BLOCK )
51+ pub type PreorderIter < ' a , ' tcx : ' a > =
52+ impl Iterator < Item = ( BasicBlock , & ' a BasicBlockData < ' tcx > ) > + ExactSizeIterator ;
53+
54+ pub fn preorder < ' a , ' tcx > ( body : & ' a Body < ' tcx > ) -> PreorderIter < ' a , ' tcx > {
55+ body. basic_blocks
56+ . preorder_and_reachable_bitset ( )
57+ . 0
58+ . iter ( )
59+ . map ( |& bb| ( bb, & body. basic_blocks [ bb] ) )
4660}
4761
4862impl < ' a , ' tcx > Iterator for Preorder < ' a , ' tcx > {
@@ -54,7 +68,7 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> {
5468 continue ;
5569 }
5670
57- let data = & self . body [ idx] ;
71+ let data = & self . basic_blocks [ idx] ;
5872
5973 if let Some ( ref term) = data. terminator {
6074 self . worklist . extend ( term. successors ( ) ) ;
@@ -68,7 +82,7 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> {
6882
6983 fn size_hint ( & self ) -> ( usize , Option < usize > ) {
7084 // All the blocks, minus the number of blocks we've visited.
71- let upper = self . body . basic_blocks . len ( ) - self . visited . count ( ) ;
85+ let upper = self . basic_blocks . len ( ) - self . visited . count ( ) ;
7286
7387 let lower = if self . root_is_start_block {
7488 // We will visit all remaining blocks exactly once.
@@ -285,17 +299,13 @@ impl<'a, 'tcx> ExactSizeIterator for ReversePostorder<'a, 'tcx> {}
285299/// order.
286300///
287301/// This is clearer than writing `preorder` in cases where the order doesn't matter.
288- pub fn reachable < ' a , ' tcx > (
289- body : & ' a Body < ' tcx > ,
290- ) -> impl ' a + Iterator < Item = ( BasicBlock , & ' a BasicBlockData < ' tcx > ) > {
302+ pub fn reachable < ' a , ' tcx > ( body : & ' a Body < ' tcx > ) -> PreorderIter < ' a , ' tcx > {
291303 preorder ( body)
292304}
293305
294306/// Returns a `BitSet` containing all basic blocks reachable from the `START_BLOCK`.
295- pub fn reachable_as_bitset ( body : & Body < ' _ > ) -> BitSet < BasicBlock > {
296- let mut iter = preorder ( body) ;
297- ( & mut iter) . for_each ( drop) ;
298- iter. visited
307+ pub fn reachable_as_bitset < ' a > ( body : & ' a Body < ' _ > ) -> & ' a BitSet < BasicBlock > {
308+ body. basic_blocks . preorder_and_reachable_bitset ( ) . 1
299309}
300310
301311#[ derive( Clone ) ]
0 commit comments