From dc3177775c6accb004a1bde5ea72ba03740952ad Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sat, 17 Oct 2020 02:25:31 +0200 Subject: [PATCH] Remove the old copy propagation pass --- compiler/rustc_mir/src/transform/copy_prop.rs | 384 ------------------ compiler/rustc_mir/src/transform/mod.rs | 4 +- compiler/rustc_mir/src/util/def_use.rs | 158 ------- compiler/rustc_mir/src/util/mod.rs | 1 - src/test/mir-opt/copy_propagation.rs | 12 - ...copy_propagation.test.CopyPropagation.diff | 20 - ...opagation_arg.arg_src.CopyPropagation.diff | 21 - ...y_propagation_arg.baz.CopyPropagation.diff | 18 - ...on_arg.arg_src.DestinationPropagation.diff | 26 ++ ...ation_arg.bar.DestinationPropagation.diff} | 4 +- ...gation_arg.baz.DestinationPropagation.diff | 22 + ...ation_arg.foo.DestinationPropagation.diff} | 16 +- .../{ => dest-prop}/copy_propagation_arg.rs | 10 +- .../mir-opt/early_otherwise_branch_68867.rs | 2 +- ....before-SimplifyBranches-final.after.diff} | 18 +- 15 files changed, 74 insertions(+), 642 deletions(-) delete mode 100644 compiler/rustc_mir/src/transform/copy_prop.rs delete mode 100644 compiler/rustc_mir/src/util/def_use.rs delete mode 100644 src/test/mir-opt/copy_propagation.rs delete mode 100644 src/test/mir-opt/copy_propagation.test.CopyPropagation.diff delete mode 100644 src/test/mir-opt/copy_propagation_arg.arg_src.CopyPropagation.diff delete mode 100644 src/test/mir-opt/copy_propagation_arg.baz.CopyPropagation.diff create mode 100644 src/test/mir-opt/dest-prop/copy_propagation_arg.arg_src.DestinationPropagation.diff rename src/test/mir-opt/{copy_propagation_arg.bar.CopyPropagation.diff => dest-prop/copy_propagation_arg.bar.DestinationPropagation.diff} (94%) create mode 100644 src/test/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.diff rename src/test/mir-opt/{copy_propagation_arg.foo.CopyPropagation.diff => dest-prop/copy_propagation_arg.foo.DestinationPropagation.diff} (65%) rename src/test/mir-opt/{ => dest-prop}/copy_propagation_arg.rs (63%) rename src/test/mir-opt/{early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyBranches-after-copy-prop.after.diff => early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyBranches-final.after.diff} (97%) diff --git a/compiler/rustc_mir/src/transform/copy_prop.rs b/compiler/rustc_mir/src/transform/copy_prop.rs deleted file mode 100644 index 4f44bb7b20476..0000000000000 --- a/compiler/rustc_mir/src/transform/copy_prop.rs +++ /dev/null @@ -1,384 +0,0 @@ -//! Trivial copy propagation pass. -//! -//! This uses def-use analysis to remove values that have exactly one def and one use, which must -//! be an assignment. -//! -//! To give an example, we look for patterns that look like: -//! -//! DEST = SRC -//! ... -//! USE(DEST) -//! -//! where `DEST` and `SRC` are both locals of some form. We replace that with: -//! -//! NOP -//! ... -//! USE(SRC) -//! -//! The assignment `DEST = SRC` must be (a) the only mutation of `DEST` and (b) the only -//! (non-mutating) use of `SRC`. These restrictions are conservative and may be relaxed in the -//! future. - -use crate::transform::MirPass; -use crate::util::def_use::DefUseAnalysis; -use rustc_middle::mir::visit::MutVisitor; -use rustc_middle::mir::{ - Body, Constant, Local, LocalKind, Location, Operand, Place, Rvalue, StatementKind, -}; -use rustc_middle::ty::TyCtxt; - -pub struct CopyPropagation; - -impl<'tcx> MirPass<'tcx> for CopyPropagation { - fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let opts = &tcx.sess.opts.debugging_opts; - // We only run when the MIR optimization level is > 1. - // This avoids a slow pass, and messing up debug info. - // FIXME(76740): This optimization is buggy and can cause unsoundness. - if opts.mir_opt_level <= 1 || !opts.unsound_mir_opts { - return; - } - - let mut def_use_analysis = DefUseAnalysis::new(body); - loop { - def_use_analysis.analyze(body); - - if eliminate_self_assignments(body, &def_use_analysis) { - def_use_analysis.analyze(body); - } - - let mut changed = false; - for dest_local in body.local_decls.indices() { - debug!("considering destination local: {:?}", dest_local); - - let action; - let location; - { - // The destination must have exactly one def. - let dest_use_info = def_use_analysis.local_info(dest_local); - let dest_def_count = dest_use_info.def_count_not_including_drop(); - if dest_def_count == 0 { - debug!(" Can't copy-propagate local: dest {:?} undefined", dest_local); - continue; - } - if dest_def_count > 1 { - debug!( - " Can't copy-propagate local: dest {:?} defined {} times", - dest_local, - dest_use_info.def_count() - ); - continue; - } - if dest_use_info.use_count() == 0 { - debug!(" Can't copy-propagate local: dest {:?} unused", dest_local); - continue; - } - // Conservatively gives up if the dest is an argument, - // because there may be uses of the original argument value. - // Also gives up on the return place, as we cannot propagate into its implicit - // use by `return`. - if matches!( - body.local_kind(dest_local), - LocalKind::Arg | LocalKind::ReturnPointer - ) { - debug!(" Can't copy-propagate local: dest {:?} (argument)", dest_local); - continue; - } - let dest_place_def = dest_use_info.defs_not_including_drop().next().unwrap(); - location = dest_place_def.location; - - let basic_block = &body[location.block]; - let statement_index = location.statement_index; - let statement = match basic_block.statements.get(statement_index) { - Some(statement) => statement, - None => { - debug!(" Can't copy-propagate local: used in terminator"); - continue; - } - }; - - // That use of the source must be an assignment. - match &statement.kind { - StatementKind::Assign(box (place, Rvalue::Use(operand))) => { - if let Some(local) = place.as_local() { - if local == dest_local { - let maybe_action = match operand { - Operand::Copy(src_place) | Operand::Move(src_place) => { - Action::local_copy(&body, &def_use_analysis, *src_place) - } - Operand::Constant(ref src_constant) => { - Action::constant(src_constant) - } - }; - match maybe_action { - Some(this_action) => action = this_action, - None => continue, - } - } else { - debug!( - " Can't copy-propagate local: source use is not an \ - assignment" - ); - continue; - } - } else { - debug!( - " Can't copy-propagate local: source use is not an \ - assignment" - ); - continue; - } - } - _ => { - debug!( - " Can't copy-propagate local: source use is not an \ - assignment" - ); - continue; - } - } - } - - changed = - action.perform(body, &def_use_analysis, dest_local, location, tcx) || changed; - // FIXME(pcwalton): Update the use-def chains to delete the instructions instead of - // regenerating the chains. - break; - } - if !changed { - break; - } - } - } -} - -fn eliminate_self_assignments(body: &mut Body<'_>, def_use_analysis: &DefUseAnalysis) -> bool { - let mut changed = false; - - for dest_local in body.local_decls.indices() { - let dest_use_info = def_use_analysis.local_info(dest_local); - - for def in dest_use_info.defs_not_including_drop() { - let location = def.location; - if let Some(stmt) = body[location.block].statements.get(location.statement_index) { - match &stmt.kind { - StatementKind::Assign(box ( - place, - Rvalue::Use(Operand::Copy(src_place) | Operand::Move(src_place)), - )) => { - if let (Some(local), Some(src_local)) = - (place.as_local(), src_place.as_local()) - { - if local == dest_local && dest_local == src_local { - } else { - continue; - } - } else { - continue; - } - } - _ => { - continue; - } - } - } else { - continue; - } - debug!("deleting a self-assignment for {:?}", dest_local); - body.make_statement_nop(location); - changed = true; - } - } - - changed -} - -enum Action<'tcx> { - PropagateLocalCopy(Local), - PropagateConstant(Constant<'tcx>), -} - -impl<'tcx> Action<'tcx> { - fn local_copy( - body: &Body<'tcx>, - def_use_analysis: &DefUseAnalysis, - src_place: Place<'tcx>, - ) -> Option> { - // The source must be a local. - let src_local = if let Some(local) = src_place.as_local() { - local - } else { - debug!(" Can't copy-propagate local: source is not a local"); - return None; - }; - - // We're trying to copy propagate a local. - // There must be exactly one use of the source used in a statement (not in a terminator). - let src_use_info = def_use_analysis.local_info(src_local); - let src_use_count = src_use_info.use_count(); - if src_use_count == 0 { - debug!(" Can't copy-propagate local: no uses"); - return None; - } - if src_use_count != 1 { - debug!(" Can't copy-propagate local: {} uses", src_use_info.use_count()); - return None; - } - - // Verify that the source doesn't change in between. This is done conservatively for now, - // by ensuring that the source has exactly one mutation. The goal is to prevent things - // like: - // - // DEST = SRC; - // SRC = X; - // USE(DEST); - // - // From being misoptimized into: - // - // SRC = X; - // USE(SRC); - let src_def_count = src_use_info.def_count_not_including_drop(); - // allow function arguments to be propagated - let is_arg = body.local_kind(src_local) == LocalKind::Arg; - if (is_arg && src_def_count != 0) || (!is_arg && src_def_count != 1) { - debug!( - " Can't copy-propagate local: {} defs of src{}", - src_def_count, - if is_arg { " (argument)" } else { "" }, - ); - return None; - } - - Some(Action::PropagateLocalCopy(src_local)) - } - - fn constant(src_constant: &Constant<'tcx>) -> Option> { - Some(Action::PropagateConstant(*src_constant)) - } - - fn perform( - self, - body: &mut Body<'tcx>, - def_use_analysis: &DefUseAnalysis, - dest_local: Local, - location: Location, - tcx: TyCtxt<'tcx>, - ) -> bool { - match self { - Action::PropagateLocalCopy(src_local) => { - // Eliminate the destination and the assignment. - // - // First, remove all markers. - // - // FIXME(pcwalton): Don't do this. Merge live ranges instead. - debug!(" Replacing all uses of {:?} with {:?} (local)", dest_local, src_local); - for place_use in &def_use_analysis.local_info(dest_local).defs_and_uses { - if place_use.context.is_storage_marker() { - body.make_statement_nop(place_use.location) - } - } - for place_use in &def_use_analysis.local_info(src_local).defs_and_uses { - if place_use.context.is_storage_marker() { - body.make_statement_nop(place_use.location) - } - } - - // Replace all uses of the destination local with the source local. - def_use_analysis.replace_all_defs_and_uses_with(dest_local, body, src_local, tcx); - - // Finally, zap the now-useless assignment instruction. - debug!(" Deleting assignment"); - body.make_statement_nop(location); - - true - } - Action::PropagateConstant(src_constant) => { - // First, remove all markers. - // - // FIXME(pcwalton): Don't do this. Merge live ranges instead. - debug!( - " Replacing all uses of {:?} with {:?} (constant)", - dest_local, src_constant - ); - let dest_local_info = def_use_analysis.local_info(dest_local); - for place_use in &dest_local_info.defs_and_uses { - if place_use.context.is_storage_marker() { - body.make_statement_nop(place_use.location) - } - } - - // Replace all uses of the destination local with the constant. - let mut visitor = ConstantPropagationVisitor::new(dest_local, src_constant, tcx); - for dest_place_use in &dest_local_info.defs_and_uses { - visitor.visit_location(body, dest_place_use.location) - } - - // Zap the assignment instruction if we eliminated all the uses. We won't have been - // able to do that if the destination was used in a projection, because projections - // must have places on their LHS. - let use_count = dest_local_info.use_count(); - if visitor.uses_replaced == use_count { - debug!( - " {} of {} use(s) replaced; deleting assignment", - visitor.uses_replaced, use_count - ); - body.make_statement_nop(location); - true - } else if visitor.uses_replaced == 0 { - debug!(" No uses replaced; not deleting assignment"); - false - } else { - debug!( - " {} of {} use(s) replaced; not deleting assignment", - visitor.uses_replaced, use_count - ); - true - } - } - } - } -} - -struct ConstantPropagationVisitor<'tcx> { - dest_local: Local, - constant: Constant<'tcx>, - tcx: TyCtxt<'tcx>, - uses_replaced: usize, -} - -impl<'tcx> ConstantPropagationVisitor<'tcx> { - fn new( - dest_local: Local, - constant: Constant<'tcx>, - tcx: TyCtxt<'tcx>, - ) -> ConstantPropagationVisitor<'tcx> { - ConstantPropagationVisitor { dest_local, constant, tcx, uses_replaced: 0 } - } -} - -impl<'tcx> MutVisitor<'tcx> for ConstantPropagationVisitor<'tcx> { - fn tcx(&self) -> TyCtxt<'tcx> { - self.tcx - } - - fn visit_operand(&mut self, operand: &mut Operand<'tcx>, location: Location) { - self.super_operand(operand, location); - - match operand { - Operand::Copy(place) | Operand::Move(place) => { - if let Some(local) = place.as_local() { - if local == self.dest_local { - } else { - return; - } - } else { - return; - } - } - _ => return, - } - - *operand = Operand::Constant(box self.constant); - self.uses_replaced += 1 - } -} diff --git a/compiler/rustc_mir/src/transform/mod.rs b/compiler/rustc_mir/src/transform/mod.rs index ffb84950fc92c..20b8c90a9dcad 100644 --- a/compiler/rustc_mir/src/transform/mod.rs +++ b/compiler/rustc_mir/src/transform/mod.rs @@ -22,7 +22,6 @@ pub mod check_packed_ref; pub mod check_unsafety; pub mod cleanup_post_borrowck; pub mod const_prop; -pub mod copy_prop; pub mod deaggregator; pub mod dest_prop; pub mod dump_mir; @@ -401,8 +400,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { &simplify_try::SimplifyArmIdentity, &simplify_try::SimplifyBranchSame, &dest_prop::DestinationPropagation, - ©_prop::CopyPropagation, - &simplify_branches::SimplifyBranches::new("after-copy-prop"), + &simplify_branches::SimplifyBranches::new("final"), &remove_noop_landing_pads::RemoveNoopLandingPads, &simplify::SimplifyCfg::new("final"), &nrvo::RenameReturnPlace, diff --git a/compiler/rustc_mir/src/util/def_use.rs b/compiler/rustc_mir/src/util/def_use.rs deleted file mode 100644 index b4448ead8eb81..0000000000000 --- a/compiler/rustc_mir/src/util/def_use.rs +++ /dev/null @@ -1,158 +0,0 @@ -//! Def-use analysis. - -use rustc_index::vec::IndexVec; -use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor}; -use rustc_middle::mir::{Body, Local, Location, VarDebugInfo}; -use rustc_middle::ty::TyCtxt; -use std::mem; - -pub struct DefUseAnalysis { - info: IndexVec, -} - -#[derive(Clone)] -pub struct Info { - // FIXME(eddyb) use smallvec where possible. - pub defs_and_uses: Vec, - var_debug_info_indices: Vec, -} - -#[derive(Clone)] -pub struct Use { - pub context: PlaceContext, - pub location: Location, -} - -impl DefUseAnalysis { - pub fn new(body: &Body<'_>) -> DefUseAnalysis { - DefUseAnalysis { info: IndexVec::from_elem_n(Info::new(), body.local_decls.len()) } - } - - pub fn analyze(&mut self, body: &Body<'_>) { - self.clear(); - - let mut finder = DefUseFinder { - info: mem::take(&mut self.info), - var_debug_info_index: 0, - in_var_debug_info: false, - }; - finder.visit_body(&body); - self.info = finder.info - } - - fn clear(&mut self) { - for info in &mut self.info { - info.clear(); - } - } - - pub fn local_info(&self, local: Local) -> &Info { - &self.info[local] - } - - fn mutate_defs_and_uses( - &self, - local: Local, - body: &mut Body<'tcx>, - new_local: Local, - tcx: TyCtxt<'tcx>, - ) { - let mut visitor = MutateUseVisitor::new(local, new_local, tcx); - let info = &self.info[local]; - for place_use in &info.defs_and_uses { - visitor.visit_location(body, place_use.location) - } - // Update debuginfo as well, alongside defs/uses. - for &i in &info.var_debug_info_indices { - visitor.visit_var_debug_info(&mut body.var_debug_info[i]); - } - } - - // FIXME(pcwalton): this should update the def-use chains. - pub fn replace_all_defs_and_uses_with( - &self, - local: Local, - body: &mut Body<'tcx>, - new_local: Local, - tcx: TyCtxt<'tcx>, - ) { - self.mutate_defs_and_uses(local, body, new_local, tcx) - } -} - -struct DefUseFinder { - info: IndexVec, - var_debug_info_index: usize, - in_var_debug_info: bool, -} - -impl Visitor<'_> for DefUseFinder { - fn visit_local(&mut self, &local: &Local, context: PlaceContext, location: Location) { - let info = &mut self.info[local]; - if self.in_var_debug_info { - info.var_debug_info_indices.push(self.var_debug_info_index); - } else { - info.defs_and_uses.push(Use { context, location }); - } - } - fn visit_var_debug_info(&mut self, var_debug_info: &VarDebugInfo<'tcx>) { - assert!(!self.in_var_debug_info); - self.in_var_debug_info = true; - self.super_var_debug_info(var_debug_info); - self.in_var_debug_info = false; - self.var_debug_info_index += 1; - } -} - -impl Info { - fn new() -> Info { - Info { defs_and_uses: vec![], var_debug_info_indices: vec![] } - } - - fn clear(&mut self) { - self.defs_and_uses.clear(); - self.var_debug_info_indices.clear(); - } - - pub fn def_count(&self) -> usize { - self.defs_and_uses.iter().filter(|place_use| place_use.context.is_mutating_use()).count() - } - - pub fn def_count_not_including_drop(&self) -> usize { - self.defs_not_including_drop().count() - } - - pub fn defs_not_including_drop(&self) -> impl Iterator { - self.defs_and_uses - .iter() - .filter(|place_use| place_use.context.is_mutating_use() && !place_use.context.is_drop()) - } - - pub fn use_count(&self) -> usize { - self.defs_and_uses.iter().filter(|place_use| place_use.context.is_nonmutating_use()).count() - } -} - -struct MutateUseVisitor<'tcx> { - query: Local, - new_local: Local, - tcx: TyCtxt<'tcx>, -} - -impl MutateUseVisitor<'tcx> { - fn new(query: Local, new_local: Local, tcx: TyCtxt<'tcx>) -> MutateUseVisitor<'tcx> { - MutateUseVisitor { query, new_local, tcx } - } -} - -impl MutVisitor<'tcx> for MutateUseVisitor<'tcx> { - fn tcx(&self) -> TyCtxt<'tcx> { - self.tcx - } - - fn visit_local(&mut self, local: &mut Local, _context: PlaceContext, _location: Location) { - if *local == self.query { - *local = self.new_local; - } - } -} diff --git a/compiler/rustc_mir/src/util/mod.rs b/compiler/rustc_mir/src/util/mod.rs index 699f3bcf0146f..7da2f4ffe0889 100644 --- a/compiler/rustc_mir/src/util/mod.rs +++ b/compiler/rustc_mir/src/util/mod.rs @@ -1,6 +1,5 @@ pub mod aggregate; pub mod borrowck_errors; -pub mod def_use; pub mod elaborate_drops; pub mod patch; pub mod storage; diff --git a/src/test/mir-opt/copy_propagation.rs b/src/test/mir-opt/copy_propagation.rs deleted file mode 100644 index 8283ec73d0f07..0000000000000 --- a/src/test/mir-opt/copy_propagation.rs +++ /dev/null @@ -1,12 +0,0 @@ -// compile-flags: -Zunsound-mir-opts -// EMIT_MIR copy_propagation.test.CopyPropagation.diff - -fn test(x: u32) -> u32 { - let y = x; - y -} - -fn main() { - // Make sure the function actually gets instantiated. - test(0); -} diff --git a/src/test/mir-opt/copy_propagation.test.CopyPropagation.diff b/src/test/mir-opt/copy_propagation.test.CopyPropagation.diff deleted file mode 100644 index 152d159063052..0000000000000 --- a/src/test/mir-opt/copy_propagation.test.CopyPropagation.diff +++ /dev/null @@ -1,20 +0,0 @@ -- // MIR for `test` before CopyPropagation -+ // MIR for `test` after CopyPropagation - - fn test(_1: u32) -> u32 { - debug x => _1; // in scope 0 at $DIR/copy_propagation.rs:4:9: 4:10 - let mut _0: u32; // return place in scope 0 at $DIR/copy_propagation.rs:4:20: 4:23 - let _2: u32; // in scope 0 at $DIR/copy_propagation.rs:5:9: 5:10 - scope 1 { - debug y => _0; // in scope 1 at $DIR/copy_propagation.rs:5:9: 5:10 - } - - bb0: { - nop; // scope 0 at $DIR/copy_propagation.rs:5:9: 5:10 - _0 = _1; // scope 0 at $DIR/copy_propagation.rs:5:13: 5:14 - nop; // scope 1 at $DIR/copy_propagation.rs:6:5: 6:6 - nop; // scope 0 at $DIR/copy_propagation.rs:7:1: 7:2 - return; // scope 0 at $DIR/copy_propagation.rs:7:2: 7:2 - } - } - diff --git a/src/test/mir-opt/copy_propagation_arg.arg_src.CopyPropagation.diff b/src/test/mir-opt/copy_propagation_arg.arg_src.CopyPropagation.diff deleted file mode 100644 index 8aab2299d2651..0000000000000 --- a/src/test/mir-opt/copy_propagation_arg.arg_src.CopyPropagation.diff +++ /dev/null @@ -1,21 +0,0 @@ -- // MIR for `arg_src` before CopyPropagation -+ // MIR for `arg_src` after CopyPropagation - - fn arg_src(_1: i32) -> i32 { - debug x => _1; // in scope 0 at $DIR/copy_propagation_arg.rs:27:12: 27:17 - let mut _0: i32; // return place in scope 0 at $DIR/copy_propagation_arg.rs:27:27: 27:30 - let _2: i32; // in scope 0 at $DIR/copy_propagation_arg.rs:28:9: 28:10 - scope 1 { - debug y => _0; // in scope 1 at $DIR/copy_propagation_arg.rs:28:9: 28:10 - } - - bb0: { - nop; // scope 0 at $DIR/copy_propagation_arg.rs:28:9: 28:10 - _0 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:28:13: 28:14 - _1 = const 123_i32; // scope 1 at $DIR/copy_propagation_arg.rs:29:5: 29:12 - nop; // scope 1 at $DIR/copy_propagation_arg.rs:30:5: 30:6 - nop; // scope 0 at $DIR/copy_propagation_arg.rs:31:1: 31:2 - return; // scope 0 at $DIR/copy_propagation_arg.rs:31:2: 31:2 - } - } - diff --git a/src/test/mir-opt/copy_propagation_arg.baz.CopyPropagation.diff b/src/test/mir-opt/copy_propagation_arg.baz.CopyPropagation.diff deleted file mode 100644 index 1ea51fec71069..0000000000000 --- a/src/test/mir-opt/copy_propagation_arg.baz.CopyPropagation.diff +++ /dev/null @@ -1,18 +0,0 @@ -- // MIR for `baz` before CopyPropagation -+ // MIR for `baz` after CopyPropagation - - fn baz(_1: i32) -> () { - debug x => _1; // in scope 0 at $DIR/copy_propagation_arg.rs:21:8: 21:13 - let mut _0: (); // return place in scope 0 at $DIR/copy_propagation_arg.rs:21:20: 21:20 - let mut _2: i32; // in scope 0 at $DIR/copy_propagation_arg.rs:23:9: 23:10 - - bb0: { - nop; // scope 0 at $DIR/copy_propagation_arg.rs:23:9: 23:10 - nop; // scope 0 at $DIR/copy_propagation_arg.rs:23:9: 23:10 - nop; // scope 0 at $DIR/copy_propagation_arg.rs:23:5: 23:10 - nop; // scope 0 at $DIR/copy_propagation_arg.rs:23:9: 23:10 - _0 = const (); // scope 0 at $DIR/copy_propagation_arg.rs:21:20: 24:2 - return; // scope 0 at $DIR/copy_propagation_arg.rs:24:2: 24:2 - } - } - diff --git a/src/test/mir-opt/dest-prop/copy_propagation_arg.arg_src.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/copy_propagation_arg.arg_src.DestinationPropagation.diff new file mode 100644 index 0000000000000..a5d80e7505332 --- /dev/null +++ b/src/test/mir-opt/dest-prop/copy_propagation_arg.arg_src.DestinationPropagation.diff @@ -0,0 +1,26 @@ +- // MIR for `arg_src` before DestinationPropagation ++ // MIR for `arg_src` after DestinationPropagation + + fn arg_src(_1: i32) -> i32 { + debug x => _1; // in scope 0 at $DIR/copy_propagation_arg.rs:27:12: 27:17 + let mut _0: i32; // return place in scope 0 at $DIR/copy_propagation_arg.rs:27:27: 27:30 + let _2: i32; // in scope 0 at $DIR/copy_propagation_arg.rs:28:9: 28:10 + scope 1 { +- debug y => _2; // in scope 1 at $DIR/copy_propagation_arg.rs:28:9: 28:10 ++ debug y => _0; // in scope 1 at $DIR/copy_propagation_arg.rs:28:9: 28:10 + } + + bb0: { +- StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:28:9: 28:10 +- _2 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:28:13: 28:14 ++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:28:9: 28:10 ++ _0 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:28:13: 28:14 + _1 = const 123_i32; // scope 1 at $DIR/copy_propagation_arg.rs:29:5: 29:12 +- _0 = _2; // scope 1 at $DIR/copy_propagation_arg.rs:30:5: 30:6 +- StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:31:1: 31:2 ++ nop; // scope 1 at $DIR/copy_propagation_arg.rs:30:5: 30:6 ++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:31:1: 31:2 + return; // scope 0 at $DIR/copy_propagation_arg.rs:31:2: 31:2 + } + } + diff --git a/src/test/mir-opt/copy_propagation_arg.bar.CopyPropagation.diff b/src/test/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.diff similarity index 94% rename from src/test/mir-opt/copy_propagation_arg.bar.CopyPropagation.diff rename to src/test/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.diff index fb793e53ea8a7..dce8800e986c9 100644 --- a/src/test/mir-opt/copy_propagation_arg.bar.CopyPropagation.diff +++ b/src/test/mir-opt/dest-prop/copy_propagation_arg.bar.DestinationPropagation.diff @@ -1,5 +1,5 @@ -- // MIR for `bar` before CopyPropagation -+ // MIR for `bar` after CopyPropagation +- // MIR for `bar` before DestinationPropagation ++ // MIR for `bar` after DestinationPropagation fn bar(_1: u8) -> () { debug x => _1; // in scope 0 at $DIR/copy_propagation_arg.rs:15:8: 15:13 diff --git a/src/test/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.diff new file mode 100644 index 0000000000000..2f8c76eb65a9d --- /dev/null +++ b/src/test/mir-opt/dest-prop/copy_propagation_arg.baz.DestinationPropagation.diff @@ -0,0 +1,22 @@ +- // MIR for `baz` before DestinationPropagation ++ // MIR for `baz` after DestinationPropagation + + fn baz(_1: i32) -> () { + debug x => _1; // in scope 0 at $DIR/copy_propagation_arg.rs:21:8: 21:13 + let mut _0: (); // return place in scope 0 at $DIR/copy_propagation_arg.rs:21:20: 21:20 + let mut _2: i32; // in scope 0 at $DIR/copy_propagation_arg.rs:23:9: 23:10 + + bb0: { +- StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:23:9: 23:10 +- _2 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:23:9: 23:10 +- _1 = move _2; // scope 0 at $DIR/copy_propagation_arg.rs:23:5: 23:10 +- StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:23:9: 23:10 ++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:23:9: 23:10 ++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:23:9: 23:10 ++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:23:5: 23:10 ++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:23:9: 23:10 + _0 = const (); // scope 0 at $DIR/copy_propagation_arg.rs:21:20: 24:2 + return; // scope 0 at $DIR/copy_propagation_arg.rs:24:2: 24:2 + } + } + diff --git a/src/test/mir-opt/copy_propagation_arg.foo.CopyPropagation.diff b/src/test/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.diff similarity index 65% rename from src/test/mir-opt/copy_propagation_arg.foo.CopyPropagation.diff rename to src/test/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.diff index 48ab37a239c62..2dea530db3d20 100644 --- a/src/test/mir-opt/copy_propagation_arg.foo.CopyPropagation.diff +++ b/src/test/mir-opt/dest-prop/copy_propagation_arg.foo.DestinationPropagation.diff @@ -1,5 +1,5 @@ -- // MIR for `foo` before CopyPropagation -+ // MIR for `foo` after CopyPropagation +- // MIR for `foo` before DestinationPropagation ++ // MIR for `foo` after DestinationPropagation fn foo(_1: u8) -> () { debug x => _1; // in scope 0 at $DIR/copy_propagation_arg.rs:9:8: 9:13 @@ -8,10 +8,12 @@ let mut _3: u8; // in scope 0 at $DIR/copy_propagation_arg.rs:11:15: 11:16 bb0: { - nop; // scope 0 at $DIR/copy_propagation_arg.rs:11:9: 11:17 +- StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:11:9: 11:17 ++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:11:9: 11:17 StorageLive(_3); // scope 0 at $DIR/copy_propagation_arg.rs:11:15: 11:16 _3 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:11:15: 11:16 - _1 = dummy(move _3) -> bb1; // scope 0 at $DIR/copy_propagation_arg.rs:11:9: 11:17 +- _2 = dummy(move _3) -> bb1; // scope 0 at $DIR/copy_propagation_arg.rs:11:9: 11:17 ++ _1 = dummy(move _3) -> bb1; // scope 0 at $DIR/copy_propagation_arg.rs:11:9: 11:17 // mir::Constant // + span: $DIR/copy_propagation_arg.rs:11:9: 11:14 // + literal: Const { ty: fn(u8) -> u8 {dummy}, val: Value(Scalar()) } @@ -19,8 +21,10 @@ bb1: { StorageDead(_3); // scope 0 at $DIR/copy_propagation_arg.rs:11:16: 11:17 - nop; // scope 0 at $DIR/copy_propagation_arg.rs:11:5: 11:17 - nop; // scope 0 at $DIR/copy_propagation_arg.rs:11:16: 11:17 +- _1 = move _2; // scope 0 at $DIR/copy_propagation_arg.rs:11:5: 11:17 +- StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:11:16: 11:17 ++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:11:5: 11:17 ++ nop; // scope 0 at $DIR/copy_propagation_arg.rs:11:16: 11:17 _0 = const (); // scope 0 at $DIR/copy_propagation_arg.rs:9:19: 12:2 return; // scope 0 at $DIR/copy_propagation_arg.rs:12:2: 12:2 } diff --git a/src/test/mir-opt/copy_propagation_arg.rs b/src/test/mir-opt/dest-prop/copy_propagation_arg.rs similarity index 63% rename from src/test/mir-opt/copy_propagation_arg.rs rename to src/test/mir-opt/dest-prop/copy_propagation_arg.rs index 3a00fc58a4ea8..b5188a8b4b260 100644 --- a/src/test/mir-opt/copy_propagation_arg.rs +++ b/src/test/mir-opt/dest-prop/copy_propagation_arg.rs @@ -1,29 +1,29 @@ -// Check that CopyPropagation does not propagate an assignment to a function argument +// Check that DestinationPropagation does not propagate an assignment to a function argument // (doing so can break usages of the original argument value) fn dummy(x: u8) -> u8 { x } -// EMIT_MIR copy_propagation_arg.foo.CopyPropagation.diff +// EMIT_MIR copy_propagation_arg.foo.DestinationPropagation.diff fn foo(mut x: u8) { // calling `dummy` to make an use of `x` that copyprop cannot eliminate x = dummy(x); // this will assign a local to `x` } -// EMIT_MIR copy_propagation_arg.bar.CopyPropagation.diff +// EMIT_MIR copy_propagation_arg.bar.DestinationPropagation.diff fn bar(mut x: u8) { dummy(x); x = 5; } -// EMIT_MIR copy_propagation_arg.baz.CopyPropagation.diff +// EMIT_MIR copy_propagation_arg.baz.DestinationPropagation.diff fn baz(mut x: i32) { // self-assignment to a function argument should be eliminated x = x; } -// EMIT_MIR copy_propagation_arg.arg_src.CopyPropagation.diff +// EMIT_MIR copy_propagation_arg.arg_src.DestinationPropagation.diff fn arg_src(mut x: i32) -> i32 { let y = x; x = 123; // Don't propagate this assignment to `y` diff --git a/src/test/mir-opt/early_otherwise_branch_68867.rs b/src/test/mir-opt/early_otherwise_branch_68867.rs index 98a275c18acdc..b822c58f550b7 100644 --- a/src/test/mir-opt/early_otherwise_branch_68867.rs +++ b/src/test/mir-opt/early_otherwise_branch_68867.rs @@ -12,7 +12,7 @@ pub enum ViewportPercentageLength { } // EMIT_MIR early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff -// EMIT_MIR early_otherwise_branch_68867.try_sum EarlyOtherwiseBranch.before SimplifyBranches-after-copy-prop.after +// EMIT_MIR early_otherwise_branch_68867.try_sum EarlyOtherwiseBranch.before SimplifyBranches-final.after #[no_mangle] pub extern "C" fn try_sum( x: &ViewportPercentageLength, diff --git a/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyBranches-after-copy-prop.after.diff b/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyBranches-final.after.diff similarity index 97% rename from src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyBranches-after-copy-prop.after.diff rename to src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyBranches-final.after.diff index 9a5a309fd272b..f51a08ed73068 100644 --- a/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyBranches-after-copy-prop.after.diff +++ b/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyBranches-final.after.diff @@ -1,5 +1,5 @@ - // MIR for `try_sum` before EarlyOtherwiseBranch -+ // MIR for `try_sum` after SimplifyBranches-after-copy-prop ++ // MIR for `try_sum` after SimplifyBranches-final fn try_sum(_1: &ViewportPercentageLength, _2: &ViewportPercentageLength) -> std::result::Result { debug x => _1; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:18:5: 18:6 @@ -68,21 +68,17 @@ - StorageLive(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:24 - StorageLive(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:15: 22:16 - _5 = _1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:15: 22:16 -- StorageLive(_6); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:18: 22:23 -- _6 = _2; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:18: 22:23 -- (_4.0: &ViewportPercentageLength) = move _5; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:24 -- (_4.1: &ViewportPercentageLength) = move _6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:24 -- StorageDead(_6); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:23: 22:24 -- StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:23: 22:24 + nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6 + nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:24 + nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:15: 22:16 + (_4.0: &ViewportPercentageLength) = _1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:15: 22:16 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:18: 22:23 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:18: 22:23 + StorageLive(_6); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:18: 22:23 + _6 = _2; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:18: 22:23 +- (_4.0: &ViewportPercentageLength) = move _5; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:24 + nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:24 -+ (_4.1: &ViewportPercentageLength) = move _2; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:24 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:23: 22:24 + (_4.1: &ViewportPercentageLength) = move _6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:24 + StorageDead(_6); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:23: 22:24 +- StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:23: 22:24 + nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:23: 22:24 _11 = discriminant((*(_4.0: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:11: 23:18 - switchInt(move _11) -> [0_isize: bb1, 1_isize: bb3, 2_isize: bb4, 3_isize: bb5, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:11: 23:18