@@ -79,6 +79,7 @@ impl<'tcx> crate::MirPass<'tcx> for ReferencePropagation {
7979 #[ instrument( level = "trace" , skip( self , tcx, body) ) ]
8080 fn run_pass ( & self , tcx : TyCtxt < ' tcx > , body : & mut Body < ' tcx > ) {
8181 debug ! ( def_id = ?body. source. def_id( ) ) ;
82+ move_to_copy_pointers ( tcx, body) ;
8283 while propagate_ssa ( tcx, body) { }
8384 }
8485
@@ -87,11 +88,38 @@ impl<'tcx> crate::MirPass<'tcx> for ReferencePropagation {
8788 }
8889}
8990
91+ fn move_to_copy_pointers < ' tcx > ( tcx : TyCtxt < ' tcx > , body : & mut Body < ' tcx > ) {
92+ let mut visitor = MoveToCopyVisitor { tcx, local_decls : & body. local_decls } ;
93+ for ( bb, data) in body. basic_blocks . as_mut_preserves_cfg ( ) . iter_enumerated_mut ( ) {
94+ visitor. visit_basic_block_data ( bb, data) ;
95+ }
96+
97+ struct MoveToCopyVisitor < ' a , ' tcx > {
98+ tcx : TyCtxt < ' tcx > ,
99+ local_decls : & ' a IndexVec < Local , LocalDecl < ' tcx > > ,
100+ }
101+
102+ impl < ' a , ' tcx > MutVisitor < ' tcx > for MoveToCopyVisitor < ' a , ' tcx > {
103+ fn tcx ( & self ) -> TyCtxt < ' tcx > {
104+ self . tcx
105+ }
106+
107+ fn visit_operand ( & mut self , operand : & mut Operand < ' tcx > , loc : Location ) {
108+ if let Operand :: Move ( place) = * operand {
109+ if place. ty ( self . local_decls , self . tcx ) . ty . is_any_ptr ( ) {
110+ * operand = Operand :: Copy ( place) ;
111+ }
112+ }
113+ self . super_operand ( operand, loc) ;
114+ }
115+ }
116+ }
117+
90118fn propagate_ssa < ' tcx > ( tcx : TyCtxt < ' tcx > , body : & mut Body < ' tcx > ) -> bool {
91119 let typing_env = body. typing_env ( tcx) ;
92120 let ssa = SsaLocals :: new ( tcx, body, typing_env) ;
93121
94- let mut replacer = compute_replacement ( tcx, body, & ssa) ;
122+ let mut replacer = compute_replacement ( tcx, body, ssa) ;
95123 debug ! ( ?replacer. targets) ;
96124 debug ! ( ?replacer. allowed_replacements) ;
97125 debug ! ( ?replacer. storage_to_remove) ;
@@ -119,7 +147,7 @@ enum Value<'tcx> {
119147fn compute_replacement < ' tcx > (
120148 tcx : TyCtxt < ' tcx > ,
121149 body : & Body < ' tcx > ,
122- ssa : & SsaLocals ,
150+ ssa : SsaLocals ,
123151) -> Replacer < ' tcx > {
124152 let always_live_locals = always_storage_live_locals ( body) ;
125153
@@ -138,7 +166,7 @@ fn compute_replacement<'tcx>(
138166 // reborrowed references.
139167 let mut storage_to_remove = DenseBitSet :: new_empty ( body. local_decls . len ( ) ) ;
140168
141- let fully_replacable_locals = fully_replacable_locals ( ssa) ;
169+ let fully_replacable_locals = fully_replacable_locals ( & ssa) ;
142170
143171 // Returns true iff we can use `place` as a pointee.
144172 //
0 commit comments