@@ -6,7 +6,7 @@ use rustc_hir::Mutability;
6
6
use rustc_index:: vec:: Idx ;
7
7
use rustc_middle:: mir:: visit:: { MutVisitor , Visitor } ;
8
8
use rustc_middle:: mir:: {
9
- Body , Constant , Local , Location , Operand , Place , PlaceRef , ProjectionElem , Rvalue ,
9
+ BinOp , Body , Constant , Local , Location , Operand , Place , PlaceRef , ProjectionElem , Rvalue ,
10
10
} ;
11
11
use rustc_middle:: ty:: { self , TyCtxt } ;
12
12
use std:: mem;
@@ -66,6 +66,11 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor<'tcx> {
66
66
* rvalue = Rvalue :: Use ( Operand :: Constant ( box constant) ) ;
67
67
}
68
68
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
+
69
74
self . super_rvalue ( rvalue, location)
70
75
}
71
76
}
@@ -81,6 +86,48 @@ impl OptimizationFinder<'b, 'tcx> {
81
86
fn new ( body : & ' b Body < ' tcx > , tcx : TyCtxt < ' tcx > ) -> OptimizationFinder < ' b , ' tcx > {
82
87
OptimizationFinder { body, tcx, optimizations : OptimizationList :: default ( ) }
83
88
}
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
+ }
84
131
}
85
132
86
133
impl Visitor < ' tcx > for OptimizationFinder < ' b , ' tcx > {
@@ -106,6 +153,8 @@ impl Visitor<'tcx> for OptimizationFinder<'b, 'tcx> {
106
153
}
107
154
}
108
155
156
+ self . find_unneeded_equality_comparison ( rvalue, location) ;
157
+
109
158
self . super_rvalue ( rvalue, location)
110
159
}
111
160
}
@@ -114,4 +163,5 @@ impl Visitor<'tcx> for OptimizationFinder<'b, 'tcx> {
114
163
struct OptimizationList < ' tcx > {
115
164
and_stars : FxHashSet < Location > ,
116
165
arrays_lengths : FxHashMap < Location , Constant < ' tcx > > ,
166
+ unneeded_equality_comparison : FxHashMap < Location , Operand < ' tcx > > ,
117
167
}
0 commit comments