From 2b093b702aec27bcc12785a76e38222a04043365 Mon Sep 17 00:00:00 2001 From: Ulrik Sverdrup Date: Sun, 11 Dec 2016 21:54:54 +0100 Subject: [PATCH] mir: Allow copy-propagation of function arguments --- src/librustc_mir/transform/copy_prop.rs | 10 +++++--- src/test/mir-opt/copy_propagation.rs | 34 +++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 src/test/mir-opt/copy_propagation.rs diff --git a/src/librustc_mir/transform/copy_prop.rs b/src/librustc_mir/transform/copy_prop.rs index 8c8c42a1c7687..5319f24ec48e6 100644 --- a/src/librustc_mir/transform/copy_prop.rs +++ b/src/librustc_mir/transform/copy_prop.rs @@ -30,7 +30,7 @@ //! future. use def_use::DefUseAnalysis; -use rustc::mir::{Constant, Local, Location, Lvalue, Mir, Operand, Rvalue, StatementKind}; +use rustc::mir::{Constant, Local, LocalKind, Location, Lvalue, Mir, Operand, Rvalue, StatementKind}; use rustc::mir::transform::{MirPass, MirSource, Pass}; use rustc::mir::visit::MutVisitor; use rustc::ty::TyCtxt; @@ -123,7 +123,7 @@ impl<'tcx> MirPass<'tcx> for CopyPropagation { local == dest_local => { let maybe_action = match *operand { Operand::Consume(ref src_lvalue) => { - Action::local_copy(&def_use_analysis, src_lvalue) + Action::local_copy(&mir, &def_use_analysis, src_lvalue) } Operand::Constant(ref src_constant) => { Action::constant(src_constant) @@ -160,7 +160,7 @@ enum Action<'tcx> { } impl<'tcx> Action<'tcx> { - fn local_copy(def_use_analysis: &DefUseAnalysis, src_lvalue: &Lvalue<'tcx>) + fn local_copy(mir: &Mir<'tcx>, def_use_analysis: &DefUseAnalysis, src_lvalue: &Lvalue<'tcx>) -> Option> { // The source must be a local. let src_local = if let Lvalue::Local(local) = *src_lvalue { @@ -196,7 +196,9 @@ impl<'tcx> Action<'tcx> { // SRC = X; // USE(SRC); let src_def_count = src_use_info.def_count_not_including_drop(); - if src_def_count != 1 { + // allow function arguments to be propagated + if src_def_count > 1 || + (src_def_count == 0 && mir.local_kind(src_local) != LocalKind::Arg) { debug!(" Can't copy-propagate local: {} defs of src", src_use_info.def_count_not_including_drop()); return None diff --git a/src/test/mir-opt/copy_propagation.rs b/src/test/mir-opt/copy_propagation.rs new file mode 100644 index 0000000000000..26b042d0343f0 --- /dev/null +++ b/src/test/mir-opt/copy_propagation.rs @@ -0,0 +1,34 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn test(x: u32) -> u32 { + let y = x; + y +} + +fn main() { } + +// END RUST SOURCE +// START rustc.node4.CopyPropagation.before.mir +// bb0: { +// _2 = _1; +// _4 = _2; +// _3 = _4; +// _5 = _3; +// _0 = _5; +// return; +// } +// END rustc.node4.CopyPropagation.before.mir +// START rustc.node4.CopyPropagation.after.mir +// bb0: { +// _0 = _1; +// return; +// } +// END rustc.node4.CopyPropagation.after.mir