@@ -6,7 +6,7 @@ use rustc_hir::Mutability;
66use rustc_index:: vec:: Idx ;
77use rustc_middle:: mir:: visit:: { MutVisitor , Visitor } ;
88use rustc_middle:: mir:: {
9- Body , Constant , Local , Location , Operand , Place , PlaceRef , ProjectionElem , Rvalue ,
9+ BinOp , Body , Constant , Local , Location , Operand , Place , PlaceRef , ProjectionElem , Rvalue ,
1010} ;
1111use rustc_middle:: ty:: { self , TyCtxt } ;
1212use std:: mem;
@@ -66,6 +66,11 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor<'tcx> {
6666 * rvalue = Rvalue :: Use ( Operand :: Constant ( box constant) ) ;
6767 }
6868
69+ if let Some ( operand) = self . optimizations . unneeded_equality_comparison . remove ( & location) {
70+ debug ! ( "replacing {:?} with {:?}" , rvalue, operand) ;
71+ * rvalue = Rvalue :: Use ( operand) ;
72+ }
73+
6974 self . super_rvalue ( rvalue, location)
7075 }
7176}
@@ -81,6 +86,48 @@ impl OptimizationFinder<'b, 'tcx> {
8186 fn new ( body : & ' b Body < ' tcx > , tcx : TyCtxt < ' tcx > ) -> OptimizationFinder < ' b , ' tcx > {
8287 OptimizationFinder { body, tcx, optimizations : OptimizationList :: default ( ) }
8388 }
89+
90+ fn find_unneeded_equality_comparison ( & mut self , rvalue : & Rvalue < ' tcx > , location : Location ) {
91+ // find Ne(_place, false) or Ne(false, _place)
92+ // or Eq(_place, true) or Eq(true, _place)
93+ if let Rvalue :: BinaryOp ( op, l, r) = rvalue {
94+ let const_to_find = if * op == BinOp :: Ne {
95+ false
96+ } else if * op == BinOp :: Eq {
97+ true
98+ } else {
99+ return ;
100+ } ;
101+ // (const, _place)
102+ if let Some ( o) = self . find_operand_in_equality_comparison_pattern ( l, r, const_to_find) {
103+ self . optimizations . unneeded_equality_comparison . insert ( location, o. clone ( ) ) ;
104+ }
105+ // (_place, const)
106+ else if let Some ( o) =
107+ self . find_operand_in_equality_comparison_pattern ( r, l, const_to_find)
108+ {
109+ self . optimizations . unneeded_equality_comparison . insert ( location, o. clone ( ) ) ;
110+ }
111+ }
112+ }
113+
114+ fn find_operand_in_equality_comparison_pattern (
115+ & self ,
116+ l : & Operand < ' tcx > ,
117+ r : & ' a Operand < ' tcx > ,
118+ const_to_find : bool ,
119+ ) -> Option < & ' a Operand < ' tcx > > {
120+ let const_ = l. constant ( ) ?;
121+ if const_. literal . ty == self . tcx . types . bool
122+ && const_. literal . val . try_to_bool ( ) == Some ( const_to_find)
123+ {
124+ if r. place ( ) . is_some ( ) {
125+ return Some ( r) ;
126+ }
127+ }
128+
129+ return None ;
130+ }
84131}
85132
86133impl Visitor < ' tcx > for OptimizationFinder < ' b , ' tcx > {
@@ -106,6 +153,8 @@ impl Visitor<'tcx> for OptimizationFinder<'b, 'tcx> {
106153 }
107154 }
108155
156+ self . find_unneeded_equality_comparison ( rvalue, location) ;
157+
109158 self . super_rvalue ( rvalue, location)
110159 }
111160}
@@ -114,4 +163,5 @@ impl Visitor<'tcx> for OptimizationFinder<'b, 'tcx> {
114163struct OptimizationList < ' tcx > {
115164 and_stars : FxHashSet < Location > ,
116165 arrays_lengths : FxHashMap < Location , Constant < ' tcx > > ,
166+ unneeded_equality_comparison : FxHashMap < Location , Operand < ' tcx > > ,
117167}
0 commit comments