@@ -34,6 +34,7 @@ pub struct Preorder<'a, 'tcx: 'a> {
34
34
mir : & ' a Mir < ' tcx > ,
35
35
visited : BitSet < BasicBlock > ,
36
36
worklist : Vec < BasicBlock > ,
37
+ root_is_start_block : bool ,
37
38
}
38
39
39
40
impl < ' a , ' tcx > Preorder < ' a , ' tcx > {
@@ -44,6 +45,7 @@ impl<'a, 'tcx> Preorder<'a, 'tcx> {
44
45
mir,
45
46
visited : BitSet :: new_empty ( mir. basic_blocks ( ) . len ( ) ) ,
46
47
worklist,
48
+ root_is_start_block : root == START_BLOCK ,
47
49
}
48
50
}
49
51
}
@@ -75,15 +77,19 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> {
75
77
76
78
fn size_hint ( & self ) -> ( usize , Option < usize > ) {
77
79
// All the blocks, minus the number of blocks we've visited.
78
- let remaining = self . mir . basic_blocks ( ) . len ( ) - self . visited . count ( ) ;
80
+ let upper = self . mir . basic_blocks ( ) . len ( ) - self . visited . count ( ) ;
79
81
80
- // We will visit all remaining blocks exactly once.
81
- ( remaining, Some ( remaining) )
82
+ let lower = if self . root_is_start_block {
83
+ // We will visit all remaining blocks exactly once.
84
+ upper
85
+ } else {
86
+ self . worklist . len ( )
87
+ } ;
88
+
89
+ ( lower, Some ( upper) )
82
90
}
83
91
}
84
92
85
- impl < ' a , ' tcx > ExactSizeIterator for Preorder < ' a , ' tcx > { }
86
-
87
93
/// Postorder traversal of a graph.
88
94
///
89
95
/// Postorder traversal is when each node is visited after all of it's
@@ -105,15 +111,17 @@ impl<'a, 'tcx> ExactSizeIterator for Preorder<'a, 'tcx> {}
105
111
pub struct Postorder < ' a , ' tcx : ' a > {
106
112
mir : & ' a Mir < ' tcx > ,
107
113
visited : BitSet < BasicBlock > ,
108
- visit_stack : Vec < ( BasicBlock , Successors < ' a > ) >
114
+ visit_stack : Vec < ( BasicBlock , Successors < ' a > ) > ,
115
+ root_is_start_block : bool ,
109
116
}
110
117
111
118
impl < ' a , ' tcx > Postorder < ' a , ' tcx > {
112
119
pub fn new ( mir : & ' a Mir < ' tcx > , root : BasicBlock ) -> Postorder < ' a , ' tcx > {
113
120
let mut po = Postorder {
114
121
mir,
115
122
visited : BitSet :: new_empty ( mir. basic_blocks ( ) . len ( ) ) ,
116
- visit_stack : Vec :: new ( )
123
+ visit_stack : Vec :: new ( ) ,
124
+ root_is_start_block : root == START_BLOCK ,
117
125
} ;
118
126
119
127
@@ -214,15 +222,19 @@ impl<'a, 'tcx> Iterator for Postorder<'a, 'tcx> {
214
222
215
223
fn size_hint ( & self ) -> ( usize , Option < usize > ) {
216
224
// All the blocks, minus the number of blocks we've visited.
217
- let remaining = self . mir . basic_blocks ( ) . len ( ) - self . visited . count ( ) ;
225
+ let upper = self . mir . basic_blocks ( ) . len ( ) - self . visited . count ( ) ;
218
226
219
- // We will visit all remaining blocks exactly once.
220
- ( remaining, Some ( remaining) )
227
+ let lower = if self . root_is_start_block {
228
+ // We will visit all remaining blocks exactly once.
229
+ upper
230
+ } else {
231
+ self . visit_stack . len ( )
232
+ } ;
233
+
234
+ ( lower, Some ( upper) )
221
235
}
222
236
}
223
237
224
- impl < ' a , ' tcx > ExactSizeIterator for Postorder < ' a , ' tcx > { }
225
-
226
238
/// Reverse postorder traversal of a graph
227
239
///
228
240
/// Reverse postorder is the reverse order of a postorder traversal.
0 commit comments