@@ -356,6 +356,49 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
356
356
None
357
357
}
358
358
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
+
359
402
#[ instrument( level = "trace" , skip( self ) ) ]
360
403
fn process_operand (
361
404
& mut self ,
@@ -368,40 +411,7 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
368
411
// If we expect `lhs ?= A`, we have an opportunity if we assume `constant == A`.
369
412
Operand :: Constant ( constant) => {
370
413
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) ;
405
415
}
406
416
// Transfer the conditions on the copied rhs.
407
417
Operand :: Move ( rhs) | Operand :: Copy ( rhs) => {
0 commit comments