Auto merge of #95723 - SparrowLii:const_goto, r=fee1-dead

enhance `ConstGoto` mir-opt by moving up `StorageDead` statements

From the `FIXME` in the implementation of `ConstGoto` miropt. We can move `StorageDead` statements up to the predecessor. This can expand the scope of application of this opt.
This commit is contained in:
bors 2022-04-06 10:08:08 +00:00
commit 201cf3dba3
5 changed files with 167 additions and 127 deletions

View File

@ -39,7 +39,9 @@ impl<'tcx> MirPass<'tcx> for ConstGoto {
opt_finder.visit_body(body);
let should_simplify = !opt_finder.optimizations.is_empty();
for opt in opt_finder.optimizations {
let terminator = body.basic_blocks_mut()[opt.bb_with_goto].terminator_mut();
let block = &mut body.basic_blocks_mut()[opt.bb_with_goto];
block.statements.extend(opt.stmts_move_up);
let terminator = block.terminator_mut();
let new_goto = TerminatorKind::Goto { target: opt.target_to_use_in_goto };
debug!("SUCCESS: replacing `{:?}` with `{:?}`", terminator.kind, new_goto);
terminator.kind = new_goto;
@ -68,12 +70,15 @@ impl<'tcx> Visitor<'tcx> for ConstGotoOptimizationFinder<'_, 'tcx> {
// Now check that the target of this Goto switches on this place.
let target_bb = &self.body.basic_blocks()[target];
// FIXME(simonvandel): We are conservative here when we don't allow
// any statements in the target basic block.
// This could probably be relaxed to allow `StorageDead`s which could be
// copied to the predecessor of this block.
if !target_bb.statements.is_empty() {
None?
// The `StorageDead(..)` statement does not affect the functionality of mir.
// We can move this part of the statement up to the predecessor.
let mut stmts_move_up = Vec::new();
for stmt in &target_bb.statements {
if let StatementKind::StorageDead(..) = stmt.kind {
stmts_move_up.push(stmt.clone())
} else {
None?;
}
}
let target_bb_terminator = target_bb.terminator();
@ -87,6 +92,7 @@ impl<'tcx> Visitor<'tcx> for ConstGotoOptimizationFinder<'_, 'tcx> {
self.optimizations.push(OptimizationToApply {
bb_with_goto: location.block,
target_to_use_in_goto,
stmts_move_up,
});
}
}
@ -97,14 +103,15 @@ impl<'tcx> Visitor<'tcx> for ConstGotoOptimizationFinder<'_, 'tcx> {
}
}
struct OptimizationToApply {
struct OptimizationToApply<'tcx> {
bb_with_goto: BasicBlock,
target_to_use_in_goto: BasicBlock,
stmts_move_up: Vec<Statement<'tcx>>,
}
pub struct ConstGotoOptimizationFinder<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
body: &'a Body<'tcx>,
param_env: ParamEnv<'tcx>,
optimizations: Vec<OptimizationToApply>,
optimizations: Vec<OptimizationToApply<'tcx>>,
}

View File

@ -0,0 +1,102 @@
- // MIR for `match_nested_if` before ConstGoto
+ // MIR for `match_nested_if` after ConstGoto
fn match_nested_if() -> bool {
let mut _0: bool; // return place in scope 0 at $DIR/const_goto_storage.rs:2:25: 2:29
let _1: bool; // in scope 0 at $DIR/const_goto_storage.rs:3:9: 3:12
- let mut _2: (); // in scope 0 at $DIR/const_goto_storage.rs:3:21: 3:23
- let mut _3: bool; // in scope 0 at $DIR/const_goto_storage.rs:4:15: 8:10
- let mut _4: bool; // in scope 0 at $DIR/const_goto_storage.rs:4:18: 4:76
- let mut _5: bool; // in scope 0 at $DIR/const_goto_storage.rs:4:21: 4:52
- let mut _6: bool; // in scope 0 at $DIR/const_goto_storage.rs:4:24: 4:28
+ let mut _2: bool; // in scope 0 at $DIR/const_goto_storage.rs:4:24: 4:28
scope 1 {
debug val => _1; // in scope 1 at $DIR/const_goto_storage.rs:3:9: 3:12
}
bb0: {
StorageLive(_1); // scope 0 at $DIR/const_goto_storage.rs:3:9: 3:12
- StorageLive(_2); // scope 0 at $DIR/const_goto_storage.rs:3:21: 3:23
- StorageLive(_3); // scope 0 at $DIR/const_goto_storage.rs:4:15: 8:10
- StorageLive(_4); // scope 0 at $DIR/const_goto_storage.rs:4:18: 4:76
- StorageLive(_5); // scope 0 at $DIR/const_goto_storage.rs:4:21: 4:52
- StorageLive(_6); // scope 0 at $DIR/const_goto_storage.rs:4:24: 4:28
- _6 = const true; // scope 0 at $DIR/const_goto_storage.rs:4:24: 4:28
- switchInt(move _6) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/const_goto_storage.rs:4:24: 4:28
+ StorageLive(_2); // scope 0 at $DIR/const_goto_storage.rs:4:24: 4:28
+ _2 = const true; // scope 0 at $DIR/const_goto_storage.rs:4:24: 4:28
+ switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/const_goto_storage.rs:4:24: 4:28
}
bb1: {
- _5 = const true; // scope 0 at $DIR/const_goto_storage.rs:4:31: 4:35
- goto -> bb3; // scope 0 at $DIR/const_goto_storage.rs:4:21: 4:52
- }
-
- bb2: {
- _5 = const false; // scope 0 at $DIR/const_goto_storage.rs:4:45: 4:50
- goto -> bb3; // scope 0 at $DIR/const_goto_storage.rs:4:21: 4:52
- }
-
- bb3: {
- StorageDead(_6); // scope 0 at $DIR/const_goto_storage.rs:4:51: 4:52
- switchInt(move _5) -> [false: bb5, otherwise: bb4]; // scope 0 at $DIR/const_goto_storage.rs:4:21: 4:52
- }
-
- bb4: {
- _4 = const true; // scope 0 at $DIR/const_goto_storage.rs:4:55: 4:59
- goto -> bb6; // scope 0 at $DIR/const_goto_storage.rs:4:18: 4:76
- }
-
- bb5: {
- _4 = const false; // scope 0 at $DIR/const_goto_storage.rs:4:69: 4:74
- goto -> bb6; // scope 0 at $DIR/const_goto_storage.rs:4:18: 4:76
- }
-
- bb6: {
- StorageDead(_5); // scope 0 at $DIR/const_goto_storage.rs:4:75: 4:76
- switchInt(move _4) -> [false: bb8, otherwise: bb7]; // scope 0 at $DIR/const_goto_storage.rs:4:18: 4:76
- }
-
- bb7: {
- _3 = const true; // scope 0 at $DIR/const_goto_storage.rs:5:13: 5:17
- goto -> bb9; // scope 0 at $DIR/const_goto_storage.rs:4:15: 8:10
- }
-
- bb8: {
- _3 = const false; // scope 0 at $DIR/const_goto_storage.rs:7:13: 7:18
- goto -> bb9; // scope 0 at $DIR/const_goto_storage.rs:4:15: 8:10
- }
-
- bb9: {
- switchInt(move _3) -> [false: bb11, otherwise: bb10]; // scope 0 at $DIR/const_goto_storage.rs:4:15: 8:10
- }
-
- bb10: {
- StorageDead(_4); // scope 0 at $DIR/const_goto_storage.rs:8:9: 8:10
- StorageDead(_3); // scope 0 at $DIR/const_goto_storage.rs:8:9: 8:10
+ StorageDead(_2); // scope 0 at $DIR/const_goto_storage.rs:4:51: 4:52
_1 = const true; // scope 0 at $DIR/const_goto_storage.rs:10:17: 10:21
- goto -> bb12; // scope 0 at $DIR/const_goto_storage.rs:10:17: 10:21
+ goto -> bb3; // scope 0 at $DIR/const_goto_storage.rs:10:17: 10:21
}
- bb11: {
- StorageDead(_4); // scope 0 at $DIR/const_goto_storage.rs:8:9: 8:10
- StorageDead(_3); // scope 0 at $DIR/const_goto_storage.rs:8:9: 8:10
+ bb2: {
+ StorageDead(_2); // scope 0 at $DIR/const_goto_storage.rs:4:51: 4:52
_1 = const false; // scope 0 at $DIR/const_goto_storage.rs:12:14: 12:19
- goto -> bb12; // scope 0 at $DIR/const_goto_storage.rs:12:14: 12:19
+ goto -> bb3; // scope 0 at $DIR/const_goto_storage.rs:12:14: 12:19
}
- bb12: {
- StorageDead(_2); // scope 0 at $DIR/const_goto_storage.rs:13:6: 13:7
+ bb3: {
_0 = _1; // scope 1 at $DIR/const_goto_storage.rs:14:5: 14:8
StorageDead(_1); // scope 0 at $DIR/const_goto_storage.rs:15:1: 15:2
return; // scope 0 at $DIR/const_goto_storage.rs:15:2: 15:2
}
}

View File

@ -0,0 +1,19 @@
// EMIT_MIR const_goto_storage.match_nested_if.ConstGoto.diff
fn match_nested_if() -> bool {
let val = match () {
() if if if if true { true } else { false } { true } else { false } {
true
} else {
false
} =>
{
true
}
_ => false,
};
val
}
fn main() {
let _ = match_nested_if();
}

View File

@ -4,80 +4,36 @@
fn match_nested_if() -> bool {
let mut _0: bool; // return place in scope 0 at $DIR/matches_reduce_branches.rs:39:25: 39:29
let _1: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:40:9: 40:12
let mut _2: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:41:18: 41:76
let mut _3: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:41:21: 41:52
let mut _4: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
+ let mut _5: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
+ let mut _6: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:41:21: 41:52
+ let mut _7: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:41:18: 41:76
let mut _2: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
+ let mut _3: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
scope 1 {
debug val => _1; // in scope 1 at $DIR/matches_reduce_branches.rs:40:9: 40:12
}
bb0: {
StorageLive(_1); // scope 0 at $DIR/matches_reduce_branches.rs:40:9: 40:12
StorageLive(_2); // scope 0 at $DIR/matches_reduce_branches.rs:41:18: 41:76
StorageLive(_3); // scope 0 at $DIR/matches_reduce_branches.rs:41:21: 41:52
StorageLive(_4); // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
_4 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
- switchInt(move _4) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
StorageLive(_2); // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
_2 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
- }
-
- bb1: {
- _3 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:41:31: 41:35
- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:41:21: 41:52
+ StorageLive(_3); // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
+ _3 = move _2; // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:41:51: 41:52
- _1 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:47:13: 47:17
- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:47:13: 47:17
- }
-
- bb2: {
- _3 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:41:45: 41:50
- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:41:21: 41:52
- StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:41:51: 41:52
- _1 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:49:14: 49:19
- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:49:14: 49:19
- }
-
- bb3: {
+ StorageLive(_5); // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
+ _5 = move _4; // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
+ _3 = Ne(_5, const false); // scope 0 at $DIR/matches_reduce_branches.rs:41:45: 41:50
+ StorageDead(_5); // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
StorageDead(_4); // scope 0 at $DIR/matches_reduce_branches.rs:41:51: 41:52
- switchInt(move _3) -> [false: bb5, otherwise: bb4]; // scope 0 at $DIR/matches_reduce_branches.rs:41:21: 41:52
- }
-
- bb4: {
- _2 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:41:55: 41:59
- goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:41:18: 41:76
- }
-
- bb5: {
- _2 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:41:69: 41:74
- goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:41:18: 41:76
- }
-
- bb6: {
+ StorageLive(_6); // scope 0 at $DIR/matches_reduce_branches.rs:41:21: 41:52
+ _6 = move _3; // scope 0 at $DIR/matches_reduce_branches.rs:41:21: 41:52
+ _2 = Ne(_6, const false); // scope 0 at $DIR/matches_reduce_branches.rs:41:69: 41:74
+ StorageDead(_6); // scope 0 at $DIR/matches_reduce_branches.rs:41:21: 41:52
StorageDead(_3); // scope 0 at $DIR/matches_reduce_branches.rs:41:75: 41:76
- switchInt(move _2) -> [false: bb8, otherwise: bb7]; // scope 0 at $DIR/matches_reduce_branches.rs:41:18: 41:76
- }
-
- bb7: {
+ StorageLive(_7); // scope 0 at $DIR/matches_reduce_branches.rs:41:18: 41:76
+ _7 = move _2; // scope 0 at $DIR/matches_reduce_branches.rs:41:18: 41:76
StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:45:9: 45:10
- _1 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:47:13: 47:17
- goto -> bb9; // scope 0 at $DIR/matches_reduce_branches.rs:47:13: 47:17
- }
-
- bb8: {
- StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:45:9: 45:10
- _1 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:49:14: 49:19
- goto -> bb9; // scope 0 at $DIR/matches_reduce_branches.rs:49:14: 49:19
- }
-
- bb9: {
+ _1 = Ne(_7, const false); // scope 0 at $DIR/matches_reduce_branches.rs:49:14: 49:19
+ StorageDead(_7); // scope 0 at $DIR/matches_reduce_branches.rs:41:18: 41:76
+ _1 = Ne(_3, const false); // scope 0 at $DIR/matches_reduce_branches.rs:49:14: 49:19
+ StorageDead(_3); // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
_0 = _1; // scope 1 at $DIR/matches_reduce_branches.rs:51:5: 51:8
StorageDead(_1); // scope 0 at $DIR/matches_reduce_branches.rs:52:1: 52:2
return; // scope 0 at $DIR/matches_reduce_branches.rs:52:2: 52:2

View File

@ -4,80 +4,36 @@
fn match_nested_if() -> bool {
let mut _0: bool; // return place in scope 0 at $DIR/matches_reduce_branches.rs:39:25: 39:29
let _1: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:40:9: 40:12
let mut _2: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:41:18: 41:76
let mut _3: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:41:21: 41:52
let mut _4: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
+ let mut _5: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
+ let mut _6: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:41:21: 41:52
+ let mut _7: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:41:18: 41:76
let mut _2: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
+ let mut _3: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
scope 1 {
debug val => _1; // in scope 1 at $DIR/matches_reduce_branches.rs:40:9: 40:12
}
bb0: {
StorageLive(_1); // scope 0 at $DIR/matches_reduce_branches.rs:40:9: 40:12
StorageLive(_2); // scope 0 at $DIR/matches_reduce_branches.rs:41:18: 41:76
StorageLive(_3); // scope 0 at $DIR/matches_reduce_branches.rs:41:21: 41:52
StorageLive(_4); // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
_4 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
- switchInt(move _4) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
StorageLive(_2); // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
_2 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
- }
-
- bb1: {
- _3 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:41:31: 41:35
- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:41:21: 41:52
+ StorageLive(_3); // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
+ _3 = move _2; // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:41:51: 41:52
- _1 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:47:13: 47:17
- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:47:13: 47:17
- }
-
- bb2: {
- _3 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:41:45: 41:50
- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:41:21: 41:52
- StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:41:51: 41:52
- _1 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:49:14: 49:19
- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:49:14: 49:19
- }
-
- bb3: {
+ StorageLive(_5); // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
+ _5 = move _4; // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
+ _3 = Ne(_5, const false); // scope 0 at $DIR/matches_reduce_branches.rs:41:45: 41:50
+ StorageDead(_5); // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
StorageDead(_4); // scope 0 at $DIR/matches_reduce_branches.rs:41:51: 41:52
- switchInt(move _3) -> [false: bb5, otherwise: bb4]; // scope 0 at $DIR/matches_reduce_branches.rs:41:21: 41:52
- }
-
- bb4: {
- _2 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:41:55: 41:59
- goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:41:18: 41:76
- }
-
- bb5: {
- _2 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:41:69: 41:74
- goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:41:18: 41:76
- }
-
- bb6: {
+ StorageLive(_6); // scope 0 at $DIR/matches_reduce_branches.rs:41:21: 41:52
+ _6 = move _3; // scope 0 at $DIR/matches_reduce_branches.rs:41:21: 41:52
+ _2 = Ne(_6, const false); // scope 0 at $DIR/matches_reduce_branches.rs:41:69: 41:74
+ StorageDead(_6); // scope 0 at $DIR/matches_reduce_branches.rs:41:21: 41:52
StorageDead(_3); // scope 0 at $DIR/matches_reduce_branches.rs:41:75: 41:76
- switchInt(move _2) -> [false: bb8, otherwise: bb7]; // scope 0 at $DIR/matches_reduce_branches.rs:41:18: 41:76
- }
-
- bb7: {
+ StorageLive(_7); // scope 0 at $DIR/matches_reduce_branches.rs:41:18: 41:76
+ _7 = move _2; // scope 0 at $DIR/matches_reduce_branches.rs:41:18: 41:76
StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:45:9: 45:10
- _1 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:47:13: 47:17
- goto -> bb9; // scope 0 at $DIR/matches_reduce_branches.rs:47:13: 47:17
- }
-
- bb8: {
- StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:45:9: 45:10
- _1 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:49:14: 49:19
- goto -> bb9; // scope 0 at $DIR/matches_reduce_branches.rs:49:14: 49:19
- }
-
- bb9: {
+ _1 = Ne(_7, const false); // scope 0 at $DIR/matches_reduce_branches.rs:49:14: 49:19
+ StorageDead(_7); // scope 0 at $DIR/matches_reduce_branches.rs:41:18: 41:76
+ _1 = Ne(_3, const false); // scope 0 at $DIR/matches_reduce_branches.rs:49:14: 49:19
+ StorageDead(_3); // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
_0 = _1; // scope 1 at $DIR/matches_reduce_branches.rs:51:5: 51:8
StorageDead(_1); // scope 0 at $DIR/matches_reduce_branches.rs:52:1: 52:2
return; // scope 0 at $DIR/matches_reduce_branches.rs:52:2: 52:2