@@ -104,23 +104,21 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> {
104104/// ```
105105///
106106/// 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 > {
108108 basic_blocks : & ' a IndexSlice < BasicBlock , BasicBlockData < ' tcx > > ,
109109 visited : DenseBitSet < BasicBlock > ,
110110 visit_stack : Vec < ( BasicBlock , Successors < ' a > ) > ,
111111 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 > ) > ,
113114}
114115
115- impl < ' a , ' tcx , C > Postorder < ' a , ' tcx , C >
116- where
117- C : Customization < ' tcx > ,
118- {
116+ impl < ' a , ' tcx > Postorder < ' a , ' tcx > {
119117 pub fn new (
120118 basic_blocks : & ' a IndexSlice < BasicBlock , BasicBlockData < ' tcx > > ,
121119 root : BasicBlock ,
122- extra : C ,
123- ) -> Postorder < ' a , ' tcx , C > {
120+ extra : Option < ( TyCtxt < ' tcx > , Instance < ' tcx > ) > ,
121+ ) -> Postorder < ' a , ' tcx > {
124122 let mut po = Postorder {
125123 basic_blocks,
126124 visited : DenseBitSet :: new_empty ( basic_blocks. len ( ) ) ,
@@ -140,7 +138,11 @@ where
140138 return ;
141139 }
142140 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+ } ;
144146 self . visit_stack . push ( ( bb, successors) ) ;
145147 }
146148
@@ -198,10 +200,7 @@ where
198200 }
199201}
200202
201- impl < ' tcx , C > Iterator for Postorder < ' _ , ' tcx , C >
202- where
203- C : Customization < ' tcx > ,
204- {
203+ impl < ' tcx > Iterator for Postorder < ' _ , ' tcx > {
205204 type Item = BasicBlock ;
206205
207206 fn next ( & mut self ) -> Option < BasicBlock > {
@@ -241,32 +240,12 @@ pub fn postorder<'a, 'tcx>(
241240 reverse_postorder ( body) . rev ( )
242241}
243242
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-
264243pub fn mono_reachable_reverse_postorder < ' a , ' tcx > (
265244 body : & ' a Body < ' tcx > ,
266245 tcx : TyCtxt < ' tcx > ,
267246 instance : Instance < ' tcx > ,
268247) -> 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) ) ) ;
270249 let mut items = Vec :: with_capacity ( body. basic_blocks . len ( ) ) ;
271250 while let Some ( block) = iter. next ( ) {
272251 items. push ( block) ;
0 commit comments