diff options
| author | Ulrik Sverdrup <bluss@users.noreply.github.com> | 2016-12-11 21:54:54 +0100 |
|---|---|---|
| committer | Ulrik Sverdrup <bluss@users.noreply.github.com> | 2016-12-11 22:12:41 +0100 |
| commit | 2b093b702aec27bcc12785a76e38222a04043365 (patch) | |
| tree | 4f9f6967b68f70a9270c2dd9d716a92832a06670 | |
| parent | fd5dc057936f5d84ccd8c1d5965f60e669b589d8 (diff) | |
| download | rust-2b093b702aec27bcc12785a76e38222a04043365.tar.gz rust-2b093b702aec27bcc12785a76e38222a04043365.zip | |
mir: Allow copy-propagation of function arguments
| -rw-r--r-- | src/librustc_mir/transform/copy_prop.rs | 10 | ||||
| -rw-r--r-- | src/test/mir-opt/copy_propagation.rs | 34 |
2 files changed, 40 insertions, 4 deletions
diff --git a/src/librustc_mir/transform/copy_prop.rs b/src/librustc_mir/transform/copy_prop.rs index 8c8c42a1c76..5319f24ec48 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<Action<'tcx>> { // 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 00000000000..26b042d0343 --- /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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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 |
