@@ -356,6 +356,49 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
356356 None
357357 }
358358
359+ /// If we expect `lhs ?= A`, we have an opportunity if we assume `constant == A`.
360+ #[ instrument( level = "trace" , skip( self ) ) ]
361+ fn process_constant (
362+ & mut self ,
363+ bb : BasicBlock ,
364+ lhs : PlaceIndex ,
365+ constant : OpTy < ' tcx > ,
366+ state : & mut State < ConditionSet < ' a > > ,
367+ ) {
368+ self . map . for_each_projection_value (
369+ lhs,
370+ constant,
371+ & mut |elem, op| match elem {
372+ TrackElem :: Field ( idx) => self . ecx . project_field ( op, idx. as_usize ( ) ) . ok ( ) ,
373+ TrackElem :: Variant ( idx) => self . ecx . project_downcast ( op, idx) . ok ( ) ,
374+ TrackElem :: Discriminant => {
375+ let variant = self . ecx . read_discriminant ( op) . ok ( ) ?;
376+ let discr_value =
377+ self . ecx . discriminant_for_variant ( op. layout . ty , variant) . ok ( ) ?;
378+ Some ( discr_value. into ( ) )
379+ }
380+ TrackElem :: DerefLen => {
381+ let op: OpTy < ' _ > = self . ecx . deref_pointer ( op) . ok ( ) ?. into ( ) ;
382+ let len_usize = op. len ( & self . ecx ) . ok ( ) ?;
383+ let layout = self . ecx . layout_of ( self . tcx . types . usize ) . unwrap ( ) ;
384+ Some ( ImmTy :: from_uint ( len_usize, layout) . into ( ) )
385+ }
386+ } ,
387+ & mut |place, op| {
388+ if let Some ( conditions) = state. try_get_idx ( place, self . map )
389+ && let Ok ( imm) = self . ecx . read_immediate_raw ( op)
390+ && let Some ( imm) = imm. right ( )
391+ && let Immediate :: Scalar ( Scalar :: Int ( int) ) = * imm
392+ {
393+ conditions. iter_matches ( int) . for_each ( |c : Condition | {
394+ self . opportunities
395+ . push ( ThreadingOpportunity { chain : vec ! [ bb] , target : c. target } )
396+ } )
397+ }
398+ } ,
399+ ) ;
400+ }
401+
359402 #[ instrument( level = "trace" , skip( self ) ) ]
360403 fn process_operand (
361404 & mut self ,
@@ -368,40 +411,7 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
368411 // If we expect `lhs ?= A`, we have an opportunity if we assume `constant == A`.
369412 Operand :: Constant ( constant) => {
370413 let constant = self . ecx . eval_mir_constant ( & constant. const_ , None , None ) . ok ( ) ?;
371- self . map . for_each_projection_value (
372- lhs,
373- constant,
374- & mut |elem, op| match elem {
375- TrackElem :: Field ( idx) => self . ecx . project_field ( op, idx. as_usize ( ) ) . ok ( ) ,
376- TrackElem :: Variant ( idx) => self . ecx . project_downcast ( op, idx) . ok ( ) ,
377- TrackElem :: Discriminant => {
378- let variant = self . ecx . read_discriminant ( op) . ok ( ) ?;
379- let discr_value =
380- self . ecx . discriminant_for_variant ( op. layout . ty , variant) . ok ( ) ?;
381- Some ( discr_value. into ( ) )
382- }
383- TrackElem :: DerefLen => {
384- let op: OpTy < ' _ > = self . ecx . deref_pointer ( op) . ok ( ) ?. into ( ) ;
385- let len_usize = op. len ( & self . ecx ) . ok ( ) ?;
386- let layout = self . ecx . layout_of ( self . tcx . types . usize ) . unwrap ( ) ;
387- Some ( ImmTy :: from_uint ( len_usize, layout) . into ( ) )
388- }
389- } ,
390- & mut |place, op| {
391- if let Some ( conditions) = state. try_get_idx ( place, self . map )
392- && let Ok ( imm) = self . ecx . read_immediate_raw ( op)
393- && let Some ( imm) = imm. right ( )
394- && let Immediate :: Scalar ( Scalar :: Int ( int) ) = * imm
395- {
396- conditions. iter_matches ( int) . for_each ( |c : Condition | {
397- self . opportunities . push ( ThreadingOpportunity {
398- chain : vec ! [ bb] ,
399- target : c. target ,
400- } )
401- } )
402- }
403- } ,
404- ) ;
414+ self . process_constant ( bb, lhs, constant, state) ;
405415 }
406416 // Transfer the conditions on the copied rhs.
407417 Operand :: Move ( rhs) | Operand :: Copy ( rhs) => {
0 commit comments