Skip to content

enhance ConstGoto mir-opt by moving up StorageDead statements #95723

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 16 additions & 9 deletions compiler/rustc_mir_transform/src/const_goto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand All @@ -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,
});
}
}
Expand All @@ -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>>,
}
102 changes: 102 additions & 0 deletions src/test/mir-opt/const_goto_storage.match_nested_if.ConstGoto.diff
Original file line number Diff line number Diff line change
@@ -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
}
}

19 changes: 19 additions & 0 deletions src/test/mir-opt/const_goto_storage.rs
Original file line number Diff line number Diff line change
@@ -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();
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
- }
-
- 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
- }
-
- 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
+ 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 -> bb9; // 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
- }
-
- bb8: {
- StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:45:9: 45:10
- bb2: {
- 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 -> bb9; // 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
- }
-
- 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
- bb3: {
+ _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
Expand Down
Loading