Improve SimplifyLocals pass so it can remove unused consts

The `ConstProp` can cause many locals to be initialized to a constant
value and then never read from. `ConstProp` can also evaluate ZSTs into
constant values. Previously, many of these would be removed by other
parts of the MIR optimization pipeline. However, evaluating ZSTs
(especially `()`) into constant values defeated those parts of the
optimizer and so in a2e3ed5c05, I added a
hack to `ConstProp` that skips evaluating ZSTs to avoid that regression.

This commit changes `SimplifyLocals` so that it doesn't consider writes
of const values to a local to be a use of that local. In doing so,
`SimplifyLocals` is able to remove otherwise unused locals left behind
by other optimization passes (`ConstProp` in particular).
This commit is contained in:
Wesley Wiser 2019-10-17 06:46:51 -04:00
parent 4592a9eb3f
commit 2ec73395b9
9 changed files with 155 additions and 39 deletions

View file

@ -25,7 +25,7 @@ pub fn change_loop_body() {
}
#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")]
#[rustc_clean(cfg="cfail2", except="HirBody, mir_built")]
#[rustc_clean(cfg="cfail3")]
pub fn change_loop_body() {
let mut _x = 0;

View file

@ -22,7 +22,7 @@ pub fn change_name() {
#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2",
except="HirBody,mir_built,optimized_mir")]
except="HirBody,mir_built")]
#[rustc_clean(cfg="cfail3")]
pub fn change_name() {
let _y = 2u64;
@ -86,7 +86,7 @@ pub fn change_mutability_of_slot() {
#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2",
except="HirBody,typeck_tables_of,mir_built,optimized_mir")]
except="HirBody,typeck_tables_of,mir_built")]
#[rustc_clean(cfg="cfail3")]
pub fn change_mutability_of_slot() {
let _x: u64 = 0;
@ -182,7 +182,7 @@ pub fn add_initializer() {
#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2",
except="HirBody,typeck_tables_of,mir_built,optimized_mir")]
except="HirBody,typeck_tables_of,mir_built")]
#[rustc_clean(cfg="cfail3")]
pub fn add_initializer() {
let _x: i16 = 3i16;
@ -198,7 +198,7 @@ pub fn change_initializer() {
#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2",
except="HirBody,mir_built,optimized_mir")]
except="HirBody,mir_built")]
#[rustc_clean(cfg="cfail3")]
pub fn change_initializer() {
let _x = 5u16;

View file

@ -25,7 +25,7 @@ pub fn change_loop_body() {
}
#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")]
#[rustc_clean(cfg="cfail2", except="HirBody, mir_built")]
#[rustc_clean(cfg="cfail3")]
pub fn change_loop_body() {
let mut _x = 0;

View file

@ -25,7 +25,7 @@ pub fn change_loop_body() {
}
#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")]
#[rustc_clean(cfg="cfail2", except="HirBody, mir_built")]
#[rustc_clean(cfg="cfail3")]
pub fn change_loop_body() {
let mut _x = 0;

View file

@ -25,7 +25,7 @@ pub fn change_loop_body() {
}
#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")]
#[rustc_clean(cfg="cfail2", except="HirBody, mir_built")]
#[rustc_clean(cfg="cfail3")]
pub fn change_loop_body() {
let mut _x = 0;

View file

@ -0,0 +1,89 @@
// compile-flags: -C overflow-checks=no
fn use_zst(_: ((), ())) { }
struct Temp {
x: u8
}
fn use_u8(_: u8) { }
fn main() {
let ((), ()) = ((), ());
use_zst(((), ()));
use_u8((Temp { x : 40 }).x + 2);
}
// END RUST SOURCE
// START rustc.main.SimplifyLocals.before.mir
// let mut _0: ();
// let mut _1: ((), ());
// let mut _2: ();
// let mut _3: ();
// let _4: ();
// let mut _5: ((), ());
// let mut _6: ();
// let mut _7: ();
// let _8: ();
// let mut _9: u8;
// let mut _10: u8;
// let mut _11: Temp;
// scope 1 {
// }
// bb0: {
// StorageLive(_1);
// StorageLive(_2);
// _2 = const Scalar(<ZST>) : ();
// StorageLive(_3);
// _3 = const Scalar(<ZST>) : ();
// _1 = const Scalar(<ZST>) : ((), ());
// StorageDead(_3);
// StorageDead(_2);
// StorageDead(_1);
// StorageLive(_4);
// StorageLive(_6);
// _6 = const Scalar(<ZST>) : ();
// StorageLive(_7);
// _7 = const Scalar(<ZST>) : ();
// StorageDead(_7);
// StorageDead(_6);
// _4 = const use_zst(const Scalar(<ZST>) : ((), ())) -> bb1;
// }
// bb1: {
// StorageDead(_4);
// StorageLive(_8);
// StorageLive(_10);
// StorageLive(_11);
// _11 = const Scalar(0x28) : Temp;
// _10 = const 40u8;
// StorageDead(_10);
// _8 = const use_u8(const 42u8) -> bb2;
// }
// bb2: {
// StorageDead(_11);
// StorageDead(_8);
// return;
// }
// END rustc.main.SimplifyLocals.before.mir
// START rustc.main.SimplifyLocals.after.mir
// let mut _0: ();
// let _1: ();
// let _2: ();
// scope 1 {
// }
// bb0: {
// StorageLive(_1);
// _1 = const use_zst(const Scalar(<ZST>) : ((), ())) -> bb1;
// }
// bb1: {
// StorageDead(_1);
// StorageLive(_2);
// _2 = const use_u8(const 42u8) -> bb2;
// }
// bb2: {
// StorageDead(_2);
// return;
// }
// END rustc.main.SimplifyLocals.after.mir

View file

@ -1,5 +1,7 @@
// compile-flags: -Zmir-opt-level=0
fn main() {
std::ptr::drop_in_place::<[String]> as unsafe fn(_);
let _fn = std::ptr::drop_in_place::<[String]> as unsafe fn(_);
}
// END RUST SOURCE