@@ -19,17 +19,20 @@ use super::*;
19
19
///
20
20
/// A preorder traversal of this graph is either `A B D C` or `A C D B`
21
21
#[ derive( Clone ) ]
22
- pub struct Preorder < ' a , ' tcx > {
23
- body : & ' a Body < ' tcx > ,
22
+ pub ( crate ) struct Preorder < ' a , ' tcx > {
23
+ basic_blocks : & ' a IndexSlice < BasicBlock , BasicBlockData < ' tcx > > ,
24
24
visited : DenseBitSet < BasicBlock > ,
25
25
worklist : Vec < BasicBlock > ,
26
26
}
27
27
28
28
impl < ' a , ' tcx > Preorder < ' a , ' tcx > {
29
- pub fn new ( body : & ' a Body < ' tcx > , root : BasicBlock ) -> Preorder < ' a , ' tcx > {
29
+ pub ( crate ) fn new (
30
+ basic_blocks : & ' a IndexSlice < BasicBlock , BasicBlockData < ' tcx > > ,
31
+ root : BasicBlock ,
32
+ ) -> Preorder < ' a , ' tcx > {
30
33
let worklist = vec ! [ root] ;
31
34
32
- Preorder { body , visited : DenseBitSet :: new_empty ( body . basic_blocks . len ( ) ) , worklist }
35
+ Preorder { basic_blocks , visited : DenseBitSet :: new_empty ( basic_blocks. len ( ) ) , worklist }
33
36
}
34
37
}
35
38
@@ -39,8 +42,10 @@ impl<'a, 'tcx> Preorder<'a, 'tcx> {
39
42
/// returns basic blocks in a preorder.
40
43
///
41
44
/// See [`Preorder`]'s docs to learn what is preorder traversal.
42
- pub fn preorder < ' a , ' tcx > ( body : & ' a Body < ' tcx > ) -> Preorder < ' a , ' tcx > {
43
- Preorder :: new ( body, START_BLOCK )
45
+ pub fn preorder < ' a , ' tcx > (
46
+ body : & ' a Body < ' tcx > ,
47
+ ) -> impl Iterator < Item = ( BasicBlock , & ' a BasicBlockData < ' tcx > ) > {
48
+ body. basic_blocks . preorder ( ) . iter ( ) . map ( |& bb| ( bb, & body. basic_blocks [ bb] ) )
44
49
}
45
50
46
51
impl < ' a , ' tcx > Iterator for Preorder < ' a , ' tcx > {
@@ -52,7 +57,7 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> {
52
57
continue ;
53
58
}
54
59
55
- let data = & self . body [ idx] ;
60
+ let data = & self . basic_blocks [ idx] ;
56
61
57
62
if let Some ( ref term) = data. terminator {
58
63
self . worklist . extend ( term. successors ( ) ) ;
@@ -69,7 +74,7 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> {
69
74
let lower = 0 ;
70
75
71
76
// This is extremely loose, but it's not worth a popcnt loop to do better.
72
- let upper = self . body . basic_blocks . len ( ) ;
77
+ let upper = self . basic_blocks . len ( ) ;
73
78
74
79
( lower, Some ( upper) )
75
80
}
@@ -251,9 +256,11 @@ pub fn reachable<'a, 'tcx>(
251
256
252
257
/// Returns a `DenseBitSet` containing all basic blocks reachable from the `START_BLOCK`.
253
258
pub fn reachable_as_bitset ( body : & Body < ' _ > ) -> DenseBitSet < BasicBlock > {
254
- let mut iter = preorder ( body) ;
255
- while let Some ( _) = iter. next ( ) { }
256
- iter. visited
259
+ let mut reachable = DenseBitSet :: new_empty ( body. basic_blocks . len ( ) ) ;
260
+ for & bb in body. basic_blocks . preorder ( ) {
261
+ reachable. insert ( bb) ;
262
+ }
263
+ reachable
257
264
}
258
265
259
266
/// Reverse postorder traversal of a graph.
0 commit comments