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