@@ -104,23 +104,21 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> {
104
104
/// ```
105
105
///
106
106
/// A Postorder traversal of this graph is `D B C A` or `D C B A`
107
- pub struct Postorder < ' a , ' tcx , C > {
107
+ pub struct Postorder < ' a , ' tcx > {
108
108
basic_blocks : & ' a IndexSlice < BasicBlock , BasicBlockData < ' tcx > > ,
109
109
visited : DenseBitSet < BasicBlock > ,
110
110
visit_stack : Vec < ( BasicBlock , Successors < ' a > ) > ,
111
111
root_is_start_block : bool ,
112
- extra : C ,
112
+ /// A non-empty `extra` allows for a precise calculation of the successors.
113
+ extra : Option < ( TyCtxt < ' tcx > , Instance < ' tcx > ) > ,
113
114
}
114
115
115
- impl < ' a , ' tcx , C > Postorder < ' a , ' tcx , C >
116
- where
117
- C : Customization < ' tcx > ,
118
- {
116
+ impl < ' a , ' tcx > Postorder < ' a , ' tcx > {
119
117
pub fn new (
120
118
basic_blocks : & ' a IndexSlice < BasicBlock , BasicBlockData < ' tcx > > ,
121
119
root : BasicBlock ,
122
- extra : C ,
123
- ) -> Postorder < ' a , ' tcx , C > {
120
+ extra : Option < ( TyCtxt < ' tcx > , Instance < ' tcx > ) > ,
121
+ ) -> Postorder < ' a , ' tcx > {
124
122
let mut po = Postorder {
125
123
basic_blocks,
126
124
visited : DenseBitSet :: new_empty ( basic_blocks. len ( ) ) ,
@@ -140,7 +138,11 @@ where
140
138
return ;
141
139
}
142
140
let data = & self . basic_blocks [ bb] ;
143
- let successors = C :: successors ( data, self . extra ) ;
141
+ let successors = if let Some ( extra) = self . extra {
142
+ data. mono_successors ( extra. 0 , extra. 1 )
143
+ } else {
144
+ data. terminator ( ) . successors ( )
145
+ } ;
144
146
self . visit_stack . push ( ( bb, successors) ) ;
145
147
}
146
148
@@ -198,10 +200,7 @@ where
198
200
}
199
201
}
200
202
201
- impl < ' tcx , C > Iterator for Postorder < ' _ , ' tcx , C >
202
- where
203
- C : Customization < ' tcx > ,
204
- {
203
+ impl < ' tcx > Iterator for Postorder < ' _ , ' tcx > {
205
204
type Item = BasicBlock ;
206
205
207
206
fn next ( & mut self ) -> Option < BasicBlock > {
@@ -241,32 +240,12 @@ pub fn postorder<'a, 'tcx>(
241
240
reverse_postorder ( body) . rev ( )
242
241
}
243
242
244
- /// Lets us plug in some additional logic and data into a Postorder traversal. Or not.
245
- pub trait Customization < ' tcx > : Copy {
246
- fn successors < ' a > ( _: & ' a BasicBlockData < ' tcx > , _: Self ) -> Successors < ' a > ;
247
- }
248
-
249
- impl < ' tcx > Customization < ' tcx > for ( ) {
250
- fn successors < ' a > ( data : & ' a BasicBlockData < ' tcx > , _: ( ) ) -> Successors < ' a > {
251
- data. terminator ( ) . successors ( )
252
- }
253
- }
254
-
255
- impl < ' tcx > Customization < ' tcx > for ( TyCtxt < ' tcx > , Instance < ' tcx > ) {
256
- fn successors < ' a > (
257
- data : & ' a BasicBlockData < ' tcx > ,
258
- ( tcx, instance) : ( TyCtxt < ' tcx > , Instance < ' tcx > ) ,
259
- ) -> Successors < ' a > {
260
- data. mono_successors ( tcx, instance)
261
- }
262
- }
263
-
264
243
pub fn mono_reachable_reverse_postorder < ' a , ' tcx > (
265
244
body : & ' a Body < ' tcx > ,
266
245
tcx : TyCtxt < ' tcx > ,
267
246
instance : Instance < ' tcx > ,
268
247
) -> Vec < BasicBlock > {
269
- let mut iter = Postorder :: new ( & body. basic_blocks , START_BLOCK , ( tcx, instance) ) ;
248
+ let mut iter = Postorder :: new ( & body. basic_blocks , START_BLOCK , Some ( ( tcx, instance) ) ) ;
270
249
let mut items = Vec :: with_capacity ( body. basic_blocks . len ( ) ) ;
271
250
while let Some ( block) = iter. next ( ) {
272
251
items. push ( block) ;
0 commit comments