@@ -91,43 +91,8 @@ impl<'tcx> MirPass<'tcx> for JumpThreading {
9191 opportunities : Vec :: new ( ) ,
9292 } ;
9393
94- for ( bb, bbdata) in body. basic_blocks . iter_enumerated ( ) {
95- debug ! ( ?bb, term = ?bbdata. terminator( ) ) ;
96- if bbdata. is_cleanup || loop_headers. contains ( bb) {
97- continue ;
98- }
99- let Some ( ( discr, targets) ) = bbdata. terminator ( ) . kind . as_switch ( ) else { continue } ;
100- let Some ( discr) = discr. place ( ) else { continue } ;
101- debug ! ( ?discr, ?bb) ;
102-
103- let discr_ty = discr. ty ( body, tcx) . ty ;
104- let Ok ( discr_layout) = finder. ecx . layout_of ( discr_ty) else { continue } ;
105-
106- let Some ( discr) = finder. map . find ( discr. as_ref ( ) ) else { continue } ;
107- debug ! ( ?discr) ;
108-
109- let cost = CostChecker :: new ( tcx, param_env, None , body) ;
110-
111- let mut state = State :: new ( ConditionSet :: default ( ) , finder. map ) ;
112-
113- let conds = if let Some ( ( value, then, else_) ) = targets. as_static_if ( ) {
114- let Some ( value) = ScalarInt :: try_from_uint ( value, discr_layout. size ) else {
115- continue ;
116- } ;
117- arena. alloc_from_iter ( [
118- Condition { value, polarity : Polarity :: Eq , target : then } ,
119- Condition { value, polarity : Polarity :: Ne , target : else_ } ,
120- ] )
121- } else {
122- arena. alloc_from_iter ( targets. iter ( ) . filter_map ( |( value, target) | {
123- let value = ScalarInt :: try_from_uint ( value, discr_layout. size ) ?;
124- Some ( Condition { value, polarity : Polarity :: Eq , target } )
125- } ) )
126- } ;
127- let conds = ConditionSet ( conds) ;
128- state. insert_value_idx ( discr, conds, finder. map ) ;
129-
130- finder. find_opportunity ( bb, state, cost, 0 ) ;
94+ for bb in body. basic_blocks . indices ( ) {
95+ finder. start_from_switch ( bb) ;
13196 }
13297
13398 let opportunities = finder. opportunities ;
@@ -216,6 +181,46 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
216181 }
217182
218183 /// Recursion entry point to find threading opportunities.
184+ #[ instrument( level = "trace" , skip( self ) ) ]
185+ fn start_from_switch ( & mut self , bb : BasicBlock ) -> Option < !> {
186+ let bbdata = & self . body [ bb] ;
187+ if bbdata. is_cleanup || self . loop_headers . contains ( bb) {
188+ return None ;
189+ }
190+ let ( discr, targets) = bbdata. terminator ( ) . kind . as_switch ( ) ?;
191+ let discr = discr. place ( ) ?;
192+ debug ! ( ?discr, ?bb) ;
193+
194+ let discr_ty = discr. ty ( self . body , self . tcx ) . ty ;
195+ let discr_layout = self . ecx . layout_of ( discr_ty) . ok ( ) ?;
196+
197+ let discr = self . map . find ( discr. as_ref ( ) ) ?;
198+ debug ! ( ?discr) ;
199+
200+ let cost = CostChecker :: new ( self . tcx , self . param_env , None , self . body ) ;
201+ let mut state = State :: new ( ConditionSet :: default ( ) , self . map ) ;
202+
203+ let conds = if let Some ( ( value, then, else_) ) = targets. as_static_if ( ) {
204+ let value = ScalarInt :: try_from_uint ( value, discr_layout. size ) ?;
205+ self . arena . alloc_from_iter ( [
206+ Condition { value, polarity : Polarity :: Eq , target : then } ,
207+ Condition { value, polarity : Polarity :: Ne , target : else_ } ,
208+ ] )
209+ } else {
210+ self . arena . alloc_from_iter ( targets. iter ( ) . filter_map ( |( value, target) | {
211+ let value = ScalarInt :: try_from_uint ( value, discr_layout. size ) ?;
212+ Some ( Condition { value, polarity : Polarity :: Eq , target } )
213+ } ) )
214+ } ;
215+ let conds = ConditionSet ( conds) ;
216+ state. insert_value_idx ( discr, conds, self . map ) ;
217+
218+ self . find_opportunity ( bb, state, cost, 0 ) ;
219+ None
220+ }
221+
222+ /// Recursively walk statements backwards from this bb's terminator to find threading
223+ /// opportunities.
219224 #[ instrument( level = "trace" , skip( self , cost) , ret) ]
220225 fn find_opportunity (
221226 & mut self ,
0 commit comments