@@ -422,6 +422,84 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
422
422
None
423
423
}
424
424
425
+ #[ instrument( level = "trace" , skip( self ) ) ]
426
+ fn process_assign (
427
+ & mut self ,
428
+ bb : BasicBlock ,
429
+ lhs_place : & Place < ' tcx > ,
430
+ rhs : & Rvalue < ' tcx > ,
431
+ state : & mut State < ConditionSet < ' a > > ,
432
+ ) -> Option < !> {
433
+ let lhs = self . map . find ( lhs_place. as_ref ( ) ) ?;
434
+ match rhs {
435
+ Rvalue :: Use ( operand) => self . process_operand ( bb, lhs, operand, state) ?,
436
+ // Transfer the conditions on the copy rhs.
437
+ Rvalue :: CopyForDeref ( rhs) => {
438
+ self . process_operand ( bb, lhs, & Operand :: Copy ( * rhs) , state) ?
439
+ }
440
+ Rvalue :: Discriminant ( rhs) => {
441
+ let rhs = self . map . find_discr ( rhs. as_ref ( ) ) ?;
442
+ state. insert_place_idx ( rhs, lhs, self . map ) ;
443
+ }
444
+ // If we expect `lhs ?= A`, we have an opportunity if we assume `constant == A`.
445
+ Rvalue :: Aggregate ( box ref kind, ref operands) => {
446
+ let agg_ty = lhs_place. ty ( self . body , self . tcx ) . ty ;
447
+ let lhs = match kind {
448
+ // Do not support unions.
449
+ AggregateKind :: Adt ( .., Some ( _) ) => return None ,
450
+ AggregateKind :: Adt ( _, variant_index, ..) if agg_ty. is_enum ( ) => {
451
+ if let Some ( discr_target) = self . map . apply ( lhs, TrackElem :: Discriminant )
452
+ && let Ok ( discr_value) =
453
+ self . ecx . discriminant_for_variant ( agg_ty, * variant_index)
454
+ {
455
+ self . process_immediate ( bb, discr_target, discr_value, state) ;
456
+ }
457
+ self . map . apply ( lhs, TrackElem :: Variant ( * variant_index) ) ?
458
+ }
459
+ _ => lhs,
460
+ } ;
461
+ for ( field_index, operand) in operands. iter_enumerated ( ) {
462
+ if let Some ( field) = self . map . apply ( lhs, TrackElem :: Field ( field_index) ) {
463
+ self . process_operand ( bb, field, operand, state) ;
464
+ }
465
+ }
466
+ }
467
+ // Transfer the conditions on the copy rhs, after inversing polarity.
468
+ Rvalue :: UnaryOp ( UnOp :: Not , Operand :: Move ( place) | Operand :: Copy ( place) ) => {
469
+ let conditions = state. try_get_idx ( lhs, self . map ) ?;
470
+ let place = self . map . find ( place. as_ref ( ) ) ?;
471
+ let conds = conditions. map ( self . arena , Condition :: inv) ;
472
+ state. insert_value_idx ( place, conds, self . map ) ;
473
+ }
474
+ // We expect `lhs ?= A`. We found `lhs = Eq(rhs, B)`.
475
+ // Create a condition on `rhs ?= B`.
476
+ Rvalue :: BinaryOp (
477
+ op,
478
+ box ( Operand :: Move ( place) | Operand :: Copy ( place) , Operand :: Constant ( value) )
479
+ | box ( Operand :: Constant ( value) , Operand :: Move ( place) | Operand :: Copy ( place) ) ,
480
+ ) => {
481
+ let conditions = state. try_get_idx ( lhs, self . map ) ?;
482
+ let place = self . map . find ( place. as_ref ( ) ) ?;
483
+ let equals = match op {
484
+ BinOp :: Eq => ScalarInt :: TRUE ,
485
+ BinOp :: Ne => ScalarInt :: FALSE ,
486
+ _ => return None ,
487
+ } ;
488
+ let value = value. const_ . normalize ( self . tcx , self . param_env ) . try_to_scalar_int ( ) ?;
489
+ let conds = conditions. map ( self . arena , |c| Condition {
490
+ value,
491
+ polarity : if c. matches ( equals) { Polarity :: Eq } else { Polarity :: Ne } ,
492
+ ..c
493
+ } ) ;
494
+ state. insert_value_idx ( place, conds, self . map ) ;
495
+ }
496
+
497
+ _ => { }
498
+ }
499
+
500
+ None
501
+ }
502
+
425
503
#[ instrument( level = "trace" , skip( self ) ) ]
426
504
fn process_statement (
427
505
& mut self ,
@@ -454,95 +532,7 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
454
532
conditions. iter_matches ( ScalarInt :: TRUE ) . for_each ( register_opportunity) ;
455
533
}
456
534
StatementKind :: Assign ( box ( lhs_place, rhs) ) => {
457
- if let Some ( lhs) = self . map . find ( lhs_place. as_ref ( ) ) {
458
- match rhs {
459
- Rvalue :: Use ( operand) => self . process_operand ( bb, lhs, operand, state) ?,
460
- // Transfer the conditions on the copy rhs.
461
- Rvalue :: CopyForDeref ( rhs) => {
462
- self . process_operand ( bb, lhs, & Operand :: Copy ( * rhs) , state) ?
463
- }
464
- Rvalue :: Discriminant ( rhs) => {
465
- let rhs = self . map . find_discr ( rhs. as_ref ( ) ) ?;
466
- state. insert_place_idx ( rhs, lhs, self . map ) ;
467
- }
468
- // If we expect `lhs ?= A`, we have an opportunity if we assume `constant == A`.
469
- Rvalue :: Aggregate ( box ref kind, ref operands) => {
470
- let agg_ty = lhs_place. ty ( self . body , self . tcx ) . ty ;
471
- let lhs = match kind {
472
- // Do not support unions.
473
- AggregateKind :: Adt ( .., Some ( _) ) => return None ,
474
- AggregateKind :: Adt ( _, variant_index, ..) if agg_ty. is_enum ( ) => {
475
- if let Some ( discr_target) =
476
- self . map . apply ( lhs, TrackElem :: Discriminant )
477
- && let Ok ( discr_value) = self
478
- . ecx
479
- . discriminant_for_variant ( agg_ty, * variant_index)
480
- {
481
- self . process_immediate (
482
- bb,
483
- discr_target,
484
- discr_value,
485
- state,
486
- ) ;
487
- }
488
- self . map . apply ( lhs, TrackElem :: Variant ( * variant_index) ) ?
489
- }
490
- _ => lhs,
491
- } ;
492
- for ( field_index, operand) in operands. iter_enumerated ( ) {
493
- if let Some ( field) =
494
- self . map . apply ( lhs, TrackElem :: Field ( field_index) )
495
- {
496
- self . process_operand ( bb, field, operand, state) ;
497
- }
498
- }
499
- }
500
- // Transfer the conditions on the copy rhs, after inversing polarity.
501
- Rvalue :: UnaryOp ( UnOp :: Not , Operand :: Move ( place) | Operand :: Copy ( place) ) => {
502
- let conditions = state. try_get_idx ( lhs, self . map ) ?;
503
- let place = self . map . find ( place. as_ref ( ) ) ?;
504
- let conds = conditions. map ( self . arena , Condition :: inv) ;
505
- state. insert_value_idx ( place, conds, self . map ) ;
506
- }
507
- // We expect `lhs ?= A`. We found `lhs = Eq(rhs, B)`.
508
- // Create a condition on `rhs ?= B`.
509
- Rvalue :: BinaryOp (
510
- op,
511
- box (
512
- Operand :: Move ( place) | Operand :: Copy ( place) ,
513
- Operand :: Constant ( value) ,
514
- )
515
- | box (
516
- Operand :: Constant ( value) ,
517
- Operand :: Move ( place) | Operand :: Copy ( place) ,
518
- ) ,
519
- ) => {
520
- let conditions = state. try_get_idx ( lhs, self . map ) ?;
521
- let place = self . map . find ( place. as_ref ( ) ) ?;
522
- let equals = match op {
523
- BinOp :: Eq => ScalarInt :: TRUE ,
524
- BinOp :: Ne => ScalarInt :: FALSE ,
525
- _ => return None ,
526
- } ;
527
- let value = value
528
- . const_
529
- . normalize ( self . tcx , self . param_env )
530
- . try_to_scalar_int ( ) ?;
531
- let conds = conditions. map ( self . arena , |c| Condition {
532
- value,
533
- polarity : if c. matches ( equals) {
534
- Polarity :: Eq
535
- } else {
536
- Polarity :: Ne
537
- } ,
538
- ..c
539
- } ) ;
540
- state. insert_value_idx ( place, conds, self . map ) ;
541
- }
542
-
543
- _ => { }
544
- }
545
- }
535
+ self . process_assign ( bb, lhs_place, rhs, state) ?;
546
536
}
547
537
_ => { }
548
538
}
0 commit comments