From 309661e84f04bedb247f42331b144a8d5ad9338d Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sun, 31 May 2020 16:22:23 +0200 Subject: [PATCH] InstCombine: Don't optimize `&mut *x` into `x` --- src/librustc_mir/transform/instcombine.rs | 18 ++++++++---------- .../rustc.a.Inline.after.mir | 6 +++++- .../rustc.b.Inline.after.mir | 8 ++++++-- .../rustc.nrvo.RenameReturnPlace.diff | 7 ++++++- 4 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/librustc_mir/transform/instcombine.rs b/src/librustc_mir/transform/instcombine.rs index a016892d982..7967137e01e 100644 --- a/src/librustc_mir/transform/instcombine.rs +++ b/src/librustc_mir/transform/instcombine.rs @@ -1,11 +1,12 @@ //! Performs various peephole optimizations. use crate::transform::{MirPass, MirSource}; -use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_hir::Mutability; use rustc_index::vec::Idx; use rustc_middle::mir::visit::{MutVisitor, Visitor}; use rustc_middle::mir::{ - Body, Constant, Local, Location, Mutability, Operand, Place, PlaceRef, ProjectionElem, Rvalue, + Body, Constant, Local, Location, Operand, Place, PlaceRef, ProjectionElem, Rvalue, }; use rustc_middle::ty::{self, TyCtxt}; use std::mem; @@ -39,7 +40,7 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor<'tcx> { } fn visit_rvalue(&mut self, rvalue: &mut Rvalue<'tcx>, location: Location) { - if let Some(mtbl) = self.optimizations.and_stars.remove(&location) { + if self.optimizations.and_stars.remove(&location) { debug!("replacing `&*`: {:?}", rvalue); let new_place = match rvalue { Rvalue::Ref(_, _, place) => { @@ -57,10 +58,7 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor<'tcx> { } _ => bug!("Detected `&*` but didn't find `&*`!"), }; - *rvalue = Rvalue::Use(match mtbl { - Mutability::Mut => Operand::Move(new_place), - Mutability::Not => Operand::Copy(new_place), - }); + *rvalue = Rvalue::Use(Operand::Copy(new_place)) } if let Some(constant) = self.optimizations.arrays_lengths.remove(&location) { @@ -93,8 +91,8 @@ impl Visitor<'tcx> for OptimizationFinder<'b, 'tcx> { { // The dereferenced place must have type `&_`. let ty = Place::ty_from(local, proj_base, self.body, self.tcx).ty; - if let ty::Ref(_, _, mtbl) = ty.kind { - self.optimizations.and_stars.insert(location, mtbl); + if let ty::Ref(_, _, Mutability::Not) = ty.kind { + self.optimizations.and_stars.insert(location); } } } @@ -114,6 +112,6 @@ impl Visitor<'tcx> for OptimizationFinder<'b, 'tcx> { #[derive(Default)] struct OptimizationList<'tcx> { - and_stars: FxHashMap, + and_stars: FxHashSet, arrays_lengths: FxHashMap>, } diff --git a/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.a.Inline.after.mir b/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.a.Inline.after.mir index 8751469d265..44f412c2e26 100644 --- a/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.a.Inline.after.mir +++ b/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.a.Inline.after.mir @@ -8,6 +8,7 @@ fn a(_1: &mut [T]) -> &mut [T] { let mut _4: &mut [T]; // in scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:6 scope 1 { debug self => _4; // in scope 1 at $SRC_DIR/libcore/convert/mod.rs:LL:COL + let mut _5: &mut [T]; // in scope 1 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15 } bb0: { @@ -15,7 +16,10 @@ fn a(_1: &mut [T]) -> &mut [T] { StorageLive(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15 StorageLive(_4); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:6 _4 = &mut (*_1); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:6 - _3 = move _4; // scope 1 at $SRC_DIR/libcore/convert/mod.rs:LL:COL + StorageLive(_5); // scope 1 at $SRC_DIR/libcore/convert/mod.rs:LL:COL + _5 = &mut (*_4); // scope 1 at $SRC_DIR/libcore/convert/mod.rs:LL:COL + _3 = &mut (*_5); // scope 1 at $SRC_DIR/libcore/convert/mod.rs:LL:COL + StorageDead(_5); // scope 1 at $SRC_DIR/libcore/convert/mod.rs:LL:COL _2 = &mut (*_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15 StorageDead(_4); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:14: 3:15 _0 = &mut (*_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:3:5: 3:15 diff --git a/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.b.Inline.after.mir b/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.b.Inline.after.mir index 743da27a049..48e48f989bd 100644 --- a/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.b.Inline.after.mir +++ b/src/test/mir-opt/inline/issue-58867-inline-as-ref-as-mut/rustc.b.Inline.after.mir @@ -9,6 +9,7 @@ fn b(_1: &mut std::boxed::Box) -> &mut T { scope 1 { debug self => _4; // in scope 1 at $SRC_DIR/liballoc/boxed.rs:LL:COL let mut _5: &mut T; // in scope 1 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15 + let mut _6: &mut T; // in scope 1 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15 } bb0: { @@ -17,8 +18,11 @@ fn b(_1: &mut std::boxed::Box) -> &mut T { StorageLive(_4); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:6 _4 = &mut (*_1); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:6 StorageLive(_5); // scope 1 at $SRC_DIR/liballoc/boxed.rs:LL:COL - _5 = &mut (*(*_4)); // scope 1 at $SRC_DIR/liballoc/boxed.rs:LL:COL - _3 = move _5; // scope 1 at $SRC_DIR/liballoc/boxed.rs:LL:COL + StorageLive(_6); // scope 1 at $SRC_DIR/liballoc/boxed.rs:LL:COL + _6 = &mut (*(*_4)); // scope 1 at $SRC_DIR/liballoc/boxed.rs:LL:COL + _5 = &mut (*_6); // scope 1 at $SRC_DIR/liballoc/boxed.rs:LL:COL + _3 = &mut (*_5); // scope 1 at $SRC_DIR/liballoc/boxed.rs:LL:COL + StorageDead(_6); // scope 1 at $SRC_DIR/liballoc/boxed.rs:LL:COL StorageDead(_5); // scope 1 at $SRC_DIR/liballoc/boxed.rs:LL:COL _2 = &mut (*_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:5: 8:15 StorageDead(_4); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:8:14: 8:15 diff --git a/src/test/mir-opt/nrvo-simple/rustc.nrvo.RenameReturnPlace.diff b/src/test/mir-opt/nrvo-simple/rustc.nrvo.RenameReturnPlace.diff index 79d92897cb5..4511470f3a5 100644 --- a/src/test/mir-opt/nrvo-simple/rustc.nrvo.RenameReturnPlace.diff +++ b/src/test/mir-opt/nrvo-simple/rustc.nrvo.RenameReturnPlace.diff @@ -26,12 +26,17 @@ // + span: $DIR/nrvo-simple.rs:3:20: 3:21 // + literal: Const { ty: u8, val: Value(Scalar(0x00)) } StorageLive(_3); // scope 1 at $DIR/nrvo-simple.rs:4:5: 4:19 + StorageLive(_5); // scope 1 at $DIR/nrvo-simple.rs:4:10: 4:18 + StorageLive(_6); // scope 1 at $DIR/nrvo-simple.rs:4:10: 4:18 - _6 = &mut _2; // scope 1 at $DIR/nrvo-simple.rs:4:10: 4:18 + _6 = &mut _0; // scope 1 at $DIR/nrvo-simple.rs:4:10: 4:18 - _3 = move _1(move _6) -> bb1; // scope 1 at $DIR/nrvo-simple.rs:4:5: 4:19 + _5 = &mut (*_6); // scope 1 at $DIR/nrvo-simple.rs:4:10: 4:18 + _3 = move _1(move _5) -> bb1; // scope 1 at $DIR/nrvo-simple.rs:4:5: 4:19 } bb1: { + StorageDead(_5); // scope 1 at $DIR/nrvo-simple.rs:4:18: 4:19 + StorageDead(_6); // scope 1 at $DIR/nrvo-simple.rs:4:19: 4:20 StorageDead(_3); // scope 1 at $DIR/nrvo-simple.rs:4:19: 4:20 - _0 = _2; // scope 1 at $DIR/nrvo-simple.rs:5:5: 5:8 - StorageDead(_2); // scope 0 at $DIR/nrvo-simple.rs:6:1: 6:2