|
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; |
@@ -122,7 +122,7 @@ impl<'tcx> MirPass<'tcx> for CopyPropagation { |
122 | 122 | local == dest_local => { |
123 | 123 | let maybe_action = match *operand { |
124 | 124 | Operand::Consume(ref src_lvalue) => { |
125 | | - Action::local_copy(&def_use_analysis, src_lvalue) |
| 125 | + Action::local_copy(&mir, &def_use_analysis, src_lvalue) |
126 | 126 | } |
127 | 127 | Operand::Constant(ref src_constant) => { |
128 | 128 | Action::constant(src_constant) |
@@ -159,7 +159,7 @@ enum Action<'tcx> { |
159 | 159 | } |
160 | 160 |
|
161 | 161 | impl<'tcx> Action<'tcx> { |
162 | | - fn local_copy(def_use_analysis: &DefUseAnalysis, src_lvalue: &Lvalue<'tcx>) |
| 162 | + fn local_copy(mir: &Mir<'tcx>, def_use_analysis: &DefUseAnalysis, src_lvalue: &Lvalue<'tcx>) |
163 | 163 | -> Option<Action<'tcx>> { |
164 | 164 | // The source must be a local. |
165 | 165 | let src_local = if let Lvalue::Local(local) = *src_lvalue { |
@@ -195,7 +195,9 @@ impl<'tcx> Action<'tcx> { |
195 | 195 | // SRC = X; |
196 | 196 | // USE(SRC); |
197 | 197 | let src_def_count = src_use_info.def_count_not_including_drop(); |
198 | | - if src_def_count != 1 { |
| 198 | + // allow function arguments to be propagated |
| 199 | + if src_def_count > 1 || |
| 200 | + (src_def_count == 0 && mir.local_kind(src_local) != LocalKind::Arg) { |
199 | 201 | debug!(" Can't copy-propagate local: {} defs of src", |
200 | 202 | src_use_info.def_count_not_including_drop()); |
201 | 203 | return None |
|
0 commit comments