|
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