|
30 | 30 | //! future. |
31 | 31 |
|
32 | 32 | use def_use::DefUseAnalysis; |
33 | | -use rustc::mir::{Constant, Local, Location, Lvalue, Mir, Operand, Rvalue, StatementKind}; |
| 33 | +use rustc::mir::{Constant, Local, LocalKind, Location, Lvalue, Mir, Operand, Rvalue, StatementKind}; |
34 | 34 | use rustc::mir::transform::{MirPass, MirSource, Pass}; |
35 | 35 | use rustc::mir::visit::MutVisitor; |
36 | 36 | use rustc::ty::TyCtxt; |
@@ -123,7 +123,7 @@ impl<'tcx> MirPass<'tcx> for CopyPropagation { |
123 | 123 | local == dest_local => { |
124 | 124 | let maybe_action = match *operand { |
125 | 125 | Operand::Consume(ref src_lvalue) => { |
126 | | - Action::local_copy(&def_use_analysis, src_lvalue) |
| 126 | + Action::local_copy(&mir, &def_use_analysis, src_lvalue) |
127 | 127 | } |
128 | 128 | Operand::Constant(ref src_constant) => { |
129 | 129 | Action::constant(src_constant) |
@@ -160,7 +160,7 @@ enum Action<'tcx> { |
160 | 160 | } |
161 | 161 |
|
162 | 162 | impl<'tcx> Action<'tcx> { |
163 | | - fn local_copy(def_use_analysis: &DefUseAnalysis, src_lvalue: &Lvalue<'tcx>) |
| 163 | + fn local_copy(mir: &Mir<'tcx>, def_use_analysis: &DefUseAnalysis, src_lvalue: &Lvalue<'tcx>) |
164 | 164 | -> Option<Action<'tcx>> { |
165 | 165 | // The source must be a local. |
166 | 166 | let src_local = if let Lvalue::Local(local) = *src_lvalue { |
@@ -196,7 +196,9 @@ impl<'tcx> Action<'tcx> { |
196 | 196 | // SRC = X; |
197 | 197 | // USE(SRC); |
198 | 198 | let src_def_count = src_use_info.def_count_not_including_drop(); |
199 | | - if src_def_count != 1 { |
| 199 | + // allow function arguments to be propagated |
| 200 | + if src_def_count > 1 || |
| 201 | + (src_def_count == 0 && mir.local_kind(src_local) != LocalKind::Arg) { |
200 | 202 | debug!(" Can't copy-propagate local: {} defs of src", |
201 | 203 | src_use_info.def_count_not_including_drop()); |
202 | 204 | return None |
|
0 commit comments