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