11//! Performs various peephole optimizations.
22
33use crate :: transform:: { MirPass , MirSource } ;
4- use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
4+ use rustc_data_structures:: fx:: FxHashMap ;
55use rustc_index:: vec:: Idx ;
66use rustc_middle:: mir:: visit:: { MutVisitor , Visitor } ;
77use rustc_middle:: mir:: {
8- Body , Constant , Local , Location , Operand , Place , PlaceRef , ProjectionElem , Rvalue ,
8+ Body , Constant , Local , Location , Mutability , Operand , Place , PlaceRef , ProjectionElem , Rvalue ,
99} ;
1010use rustc_middle:: ty:: { self , TyCtxt } ;
1111use std:: mem;
@@ -39,7 +39,7 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor<'tcx> {
3939 }
4040
4141 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) {
4343 debug ! ( "replacing `&*`: {:?}" , rvalue) ;
4444 let new_place = match rvalue {
4545 Rvalue :: Ref ( _, _, place) => {
@@ -57,7 +57,10 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor<'tcx> {
5757 }
5858 _ => bug ! ( "Detected `&*` but didn't find `&*`!" ) ,
5959 } ;
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+ } ) ;
6164 }
6265
6366 if let Some ( constant) = self . optimizations . arrays_lengths . remove ( & location) {
@@ -88,8 +91,10 @@ impl Visitor<'tcx> for OptimizationFinder<'b, 'tcx> {
8891 if let PlaceRef { local, projection : & [ ref proj_base @ .., ProjectionElem :: Deref ] } =
8992 place. as_ref ( )
9093 {
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) ;
9398 }
9499 }
95100 }
@@ -109,6 +114,6 @@ impl Visitor<'tcx> for OptimizationFinder<'b, 'tcx> {
109114
110115#[ derive( Default ) ]
111116struct OptimizationList < ' tcx > {
112- and_stars : FxHashSet < Location > ,
117+ and_stars : FxHashMap < Location , Mutability > ,
113118 arrays_lengths : FxHashMap < Location , Constant < ' tcx > > ,
114119}
0 commit comments