Rollup merge of #46462 - sinkuu:copyprop_reg2, r=arielb1

Fix CopyPropagation regression (2)

Remaining part of MIR copyprop regression by (I think) #45380, which I missed in #45753.

```rust
fn foo(mut x: i32) -> i32 {
    let y = x;
    x = 123; // `x` is assigned only once in MIR, but cannot be propagated to `y`
    y
}
```

So any assignment to an argument cannot be propagated.
This commit is contained in:
Corey Farwell 2017-12-03 17:43:48 -05:00 committed by GitHub
commit 94dbbacd45
2 changed files with 57 additions and 30 deletions

View file

@ -239,10 +239,13 @@ impl<'tcx> Action<'tcx> {
// USE(SRC);
let src_def_count = src_use_info.def_count_not_including_drop();
// 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());
let is_arg = mir.local_kind(src_local) == LocalKind::Arg;
if (is_arg && src_def_count != 0) || (!is_arg && src_def_count != 1) {
debug!(
" Can't copy-propagate local: {} defs of src{}",
src_def_count,
if is_arg { " (argument)" } else { "" },
);
return None
}

View file

@ -30,42 +30,43 @@ fn baz(mut x: i32) {
x = x;
}
fn arg_src(mut x: i32) -> i32 {
let y = x;
x = 123; // Don't propagate this assignment to `y`
y
}
fn main() {
// Make sure the function actually gets instantiated.
foo(0);
bar(0);
baz(0);
arg_src(0);
}
// END RUST SOURCE
// START rustc.foo.CopyPropagation.before.mir
// bb0: {
// StorageLive(_2);
// StorageLive(_3);
// ...
// _3 = _1;
// _2 = const dummy(move _3) -> bb1;
// }
// bb1: {
// StorageDead(_3);
// ...
// _1 = move _2;
// StorageDead(_2);
// _0 = ();
// return;
// ...
// }
// END rustc.foo.CopyPropagation.before.mir
// START rustc.foo.CopyPropagation.after.mir
// bb0: {
// StorageLive(_2);
// nop;
// nop;
// _2 = const dummy(move _1) -> bb1;
// ...
// _3 = _1;
// _2 = const dummy(move _3) -> bb1;
// }
// bb1: {
// nop;
// ...
// _1 = move _2;
// StorageDead(_2);
// _0 = ();
// return;
// ...
// }
// END rustc.foo.CopyPropagation.after.mir
// START rustc.bar.CopyPropagation.before.mir
@ -83,15 +84,14 @@ fn main() {
// END rustc.bar.CopyPropagation.before.mir
// START rustc.bar.CopyPropagation.after.mir
// bb0: {
// nop;
// nop;
// _2 = const dummy(move _1) -> bb1;
// ...
// _3 = _1;
// _2 = const dummy(move _3) -> bb1;
// }
// bb1: {
// nop;
// ...
// _1 = const 5u8;
// _0 = ();
// return;
// ...
// }
// END rustc.bar.CopyPropagation.after.mir
// START rustc.baz.CopyPropagation.before.mir
@ -106,11 +106,35 @@ fn main() {
// END rustc.baz.CopyPropagation.before.mir
// START rustc.baz.CopyPropagation.after.mir
// bb0: {
// nop;
// nop;
// nop;
// nop;
// _0 = ();
// return;
// ...
// _2 = _1;
// _1 = move _2;
// ...
// }
// END rustc.baz.CopyPropagation.after.mir
// START rustc.arg_src.CopyPropagation.before.mir
// bb0: {
// ...
// _3 = _1;
// _2 = move _3;
// ...
// _1 = const 123i32;
// ...
// _4 = _2;
// _0 = move _4;
// ...
// return;
// }
// END rustc.arg_src.CopyPropagation.before.mir
// START rustc.arg_src.CopyPropagation.after.mir
// bb0: {
// ...
// _3 = _1;
// ...
// _1 = const 123i32;
// ...
// _0 = move _3;
// ...
// return;
// }
// END rustc.arg_src.CopyPropagation.after.mir