1
1
//! Performs various peephole optimizations.
2
2
3
3
use crate :: transform:: { MirPass , MirSource } ;
4
- use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
4
+ use rustc_data_structures:: fx:: FxHashMap ;
5
5
use rustc_index:: vec:: Idx ;
6
6
use rustc_middle:: mir:: visit:: { MutVisitor , Visitor } ;
7
7
use rustc_middle:: mir:: {
8
- Body , Constant , Local , Location , Operand , Place , PlaceRef , ProjectionElem , Rvalue ,
8
+ Body , Constant , Local , Location , Mutability , Operand , Place , PlaceRef , ProjectionElem , Rvalue ,
9
9
} ;
10
10
use rustc_middle:: ty:: { self , TyCtxt } ;
11
11
use std:: mem;
@@ -39,7 +39,7 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor<'tcx> {
39
39
}
40
40
41
41
fn visit_rvalue ( & mut self , rvalue : & mut Rvalue < ' tcx > , location : Location ) {
42
- if self . optimizations . and_stars . remove ( & location) {
42
+ if let Some ( mtbl ) = self . optimizations . and_stars . remove ( & location) {
43
43
debug ! ( "replacing `&*`: {:?}" , rvalue) ;
44
44
let new_place = match rvalue {
45
45
Rvalue :: Ref ( _, _, place) => {
@@ -57,7 +57,10 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor<'tcx> {
57
57
}
58
58
_ => bug ! ( "Detected `&*` but didn't find `&*`!" ) ,
59
59
} ;
60
- * rvalue = Rvalue :: Use ( Operand :: Copy ( new_place) )
60
+ * rvalue = Rvalue :: Use ( match mtbl {
61
+ Mutability :: Mut => Operand :: Move ( new_place) ,
62
+ Mutability :: Not => Operand :: Copy ( new_place) ,
63
+ } ) ;
61
64
}
62
65
63
66
if let Some ( constant) = self . optimizations . arrays_lengths . remove ( & location) {
@@ -88,8 +91,10 @@ impl Visitor<'tcx> for OptimizationFinder<'b, 'tcx> {
88
91
if let PlaceRef { local, projection : & [ ref proj_base @ .., ProjectionElem :: Deref ] } =
89
92
place. as_ref ( )
90
93
{
91
- if Place :: ty_from ( local, proj_base, self . body , self . tcx ) . ty . is_region_ptr ( ) {
92
- self . optimizations . and_stars . insert ( location) ;
94
+ // The dereferenced place must have type `&_`.
95
+ let ty = Place :: ty_from ( local, proj_base, self . body , self . tcx ) . ty ;
96
+ if let ty:: Ref ( _, _, mtbl) = ty. kind {
97
+ self . optimizations . and_stars . insert ( location, mtbl) ;
93
98
}
94
99
}
95
100
}
@@ -109,6 +114,6 @@ impl Visitor<'tcx> for OptimizationFinder<'b, 'tcx> {
109
114
110
115
#[ derive( Default ) ]
111
116
struct OptimizationList < ' tcx > {
112
- and_stars : FxHashSet < Location > ,
117
+ and_stars : FxHashMap < Location , Mutability > ,
113
118
arrays_lengths : FxHashMap < Location , Constant < ' tcx > > ,
114
119
}
0 commit comments