Skip to content

Commit 201cf3d

Browse files
committed
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.
2 parents ce1a813 + a91b347 commit 201cf3d

5 files changed

+167
-127
lines changed

Diff for: compiler/rustc_mir_transform/src/const_goto.rs

+16-9
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ impl<'tcx> MirPass<'tcx> for ConstGoto {
3939
opt_finder.visit_body(body);
4040
let should_simplify = !opt_finder.optimizations.is_empty();
4141
for opt in opt_finder.optimizations {
42-
let terminator = body.basic_blocks_mut()[opt.bb_with_goto].terminator_mut();
42+
let block = &mut body.basic_blocks_mut()[opt.bb_with_goto];
43+
block.statements.extend(opt.stmts_move_up);
44+
let terminator = block.terminator_mut();
4345
let new_goto = TerminatorKind::Goto { target: opt.target_to_use_in_goto };
4446
debug!("SUCCESS: replacing `{:?}` with `{:?}`", terminator.kind, new_goto);
4547
terminator.kind = new_goto;
@@ -68,12 +70,15 @@ impl<'tcx> Visitor<'tcx> for ConstGotoOptimizationFinder<'_, 'tcx> {
6870
// Now check that the target of this Goto switches on this place.
6971
let target_bb = &self.body.basic_blocks()[target];
7072

71-
// FIXME(simonvandel): We are conservative here when we don't allow
72-
// any statements in the target basic block.
73-
// This could probably be relaxed to allow `StorageDead`s which could be
74-
// copied to the predecessor of this block.
75-
if !target_bb.statements.is_empty() {
76-
None?
73+
// The `StorageDead(..)` statement does not affect the functionality of mir.
74+
// We can move this part of the statement up to the predecessor.
75+
let mut stmts_move_up = Vec::new();
76+
for stmt in &target_bb.statements {
77+
if let StatementKind::StorageDead(..) = stmt.kind {
78+
stmts_move_up.push(stmt.clone())
79+
} else {
80+
None?;
81+
}
7782
}
7883

7984
let target_bb_terminator = target_bb.terminator();
@@ -87,6 +92,7 @@ impl<'tcx> Visitor<'tcx> for ConstGotoOptimizationFinder<'_, 'tcx> {
8792
self.optimizations.push(OptimizationToApply {
8893
bb_with_goto: location.block,
8994
target_to_use_in_goto,
95+
stmts_move_up,
9096
});
9197
}
9298
}
@@ -97,14 +103,15 @@ impl<'tcx> Visitor<'tcx> for ConstGotoOptimizationFinder<'_, 'tcx> {
97103
}
98104
}
99105

100-
struct OptimizationToApply {
106+
struct OptimizationToApply<'tcx> {
101107
bb_with_goto: BasicBlock,
102108
target_to_use_in_goto: BasicBlock,
109+
stmts_move_up: Vec<Statement<'tcx>>,
103110
}
104111

105112
pub struct ConstGotoOptimizationFinder<'a, 'tcx> {
106113
tcx: TyCtxt<'tcx>,
107114
body: &'a Body<'tcx>,
108115
param_env: ParamEnv<'tcx>,
109-
optimizations: Vec<OptimizationToApply>,
116+
optimizations: Vec<OptimizationToApply<'tcx>>,
110117
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
- // MIR for `match_nested_if` before ConstGoto
2+
+ // MIR for `match_nested_if` after ConstGoto
3+
4+
fn match_nested_if() -> bool {
5+
let mut _0: bool; // return place in scope 0 at $DIR/const_goto_storage.rs:2:25: 2:29
6+
let _1: bool; // in scope 0 at $DIR/const_goto_storage.rs:3:9: 3:12
7+
- let mut _2: (); // in scope 0 at $DIR/const_goto_storage.rs:3:21: 3:23
8+
- let mut _3: bool; // in scope 0 at $DIR/const_goto_storage.rs:4:15: 8:10
9+
- let mut _4: bool; // in scope 0 at $DIR/const_goto_storage.rs:4:18: 4:76
10+
- let mut _5: bool; // in scope 0 at $DIR/const_goto_storage.rs:4:21: 4:52
11+
- let mut _6: bool; // in scope 0 at $DIR/const_goto_storage.rs:4:24: 4:28
12+
+ let mut _2: bool; // in scope 0 at $DIR/const_goto_storage.rs:4:24: 4:28
13+
scope 1 {
14+
debug val => _1; // in scope 1 at $DIR/const_goto_storage.rs:3:9: 3:12
15+
}
16+
17+
bb0: {
18+
StorageLive(_1); // scope 0 at $DIR/const_goto_storage.rs:3:9: 3:12
19+
- StorageLive(_2); // scope 0 at $DIR/const_goto_storage.rs:3:21: 3:23
20+
- StorageLive(_3); // scope 0 at $DIR/const_goto_storage.rs:4:15: 8:10
21+
- StorageLive(_4); // scope 0 at $DIR/const_goto_storage.rs:4:18: 4:76
22+
- StorageLive(_5); // scope 0 at $DIR/const_goto_storage.rs:4:21: 4:52
23+
- StorageLive(_6); // scope 0 at $DIR/const_goto_storage.rs:4:24: 4:28
24+
- _6 = const true; // scope 0 at $DIR/const_goto_storage.rs:4:24: 4:28
25+
- switchInt(move _6) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/const_goto_storage.rs:4:24: 4:28
26+
+ StorageLive(_2); // scope 0 at $DIR/const_goto_storage.rs:4:24: 4:28
27+
+ _2 = const true; // scope 0 at $DIR/const_goto_storage.rs:4:24: 4:28
28+
+ switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/const_goto_storage.rs:4:24: 4:28
29+
}
30+
31+
bb1: {
32+
- _5 = const true; // scope 0 at $DIR/const_goto_storage.rs:4:31: 4:35
33+
- goto -> bb3; // scope 0 at $DIR/const_goto_storage.rs:4:21: 4:52
34+
- }
35+
-
36+
- bb2: {
37+
- _5 = const false; // scope 0 at $DIR/const_goto_storage.rs:4:45: 4:50
38+
- goto -> bb3; // scope 0 at $DIR/const_goto_storage.rs:4:21: 4:52
39+
- }
40+
-
41+
- bb3: {
42+
- StorageDead(_6); // scope 0 at $DIR/const_goto_storage.rs:4:51: 4:52
43+
- switchInt(move _5) -> [false: bb5, otherwise: bb4]; // scope 0 at $DIR/const_goto_storage.rs:4:21: 4:52
44+
- }
45+
-
46+
- bb4: {
47+
- _4 = const true; // scope 0 at $DIR/const_goto_storage.rs:4:55: 4:59
48+
- goto -> bb6; // scope 0 at $DIR/const_goto_storage.rs:4:18: 4:76
49+
- }
50+
-
51+
- bb5: {
52+
- _4 = const false; // scope 0 at $DIR/const_goto_storage.rs:4:69: 4:74
53+
- goto -> bb6; // scope 0 at $DIR/const_goto_storage.rs:4:18: 4:76
54+
- }
55+
-
56+
- bb6: {
57+
- StorageDead(_5); // scope 0 at $DIR/const_goto_storage.rs:4:75: 4:76
58+
- switchInt(move _4) -> [false: bb8, otherwise: bb7]; // scope 0 at $DIR/const_goto_storage.rs:4:18: 4:76
59+
- }
60+
-
61+
- bb7: {
62+
- _3 = const true; // scope 0 at $DIR/const_goto_storage.rs:5:13: 5:17
63+
- goto -> bb9; // scope 0 at $DIR/const_goto_storage.rs:4:15: 8:10
64+
- }
65+
-
66+
- bb8: {
67+
- _3 = const false; // scope 0 at $DIR/const_goto_storage.rs:7:13: 7:18
68+
- goto -> bb9; // scope 0 at $DIR/const_goto_storage.rs:4:15: 8:10
69+
- }
70+
-
71+
- bb9: {
72+
- switchInt(move _3) -> [false: bb11, otherwise: bb10]; // scope 0 at $DIR/const_goto_storage.rs:4:15: 8:10
73+
- }
74+
-
75+
- bb10: {
76+
- StorageDead(_4); // scope 0 at $DIR/const_goto_storage.rs:8:9: 8:10
77+
- StorageDead(_3); // scope 0 at $DIR/const_goto_storage.rs:8:9: 8:10
78+
+ StorageDead(_2); // scope 0 at $DIR/const_goto_storage.rs:4:51: 4:52
79+
_1 = const true; // scope 0 at $DIR/const_goto_storage.rs:10:17: 10:21
80+
- goto -> bb12; // scope 0 at $DIR/const_goto_storage.rs:10:17: 10:21
81+
+ goto -> bb3; // scope 0 at $DIR/const_goto_storage.rs:10:17: 10:21
82+
}
83+
84+
- bb11: {
85+
- StorageDead(_4); // scope 0 at $DIR/const_goto_storage.rs:8:9: 8:10
86+
- StorageDead(_3); // scope 0 at $DIR/const_goto_storage.rs:8:9: 8:10
87+
+ bb2: {
88+
+ StorageDead(_2); // scope 0 at $DIR/const_goto_storage.rs:4:51: 4:52
89+
_1 = const false; // scope 0 at $DIR/const_goto_storage.rs:12:14: 12:19
90+
- goto -> bb12; // scope 0 at $DIR/const_goto_storage.rs:12:14: 12:19
91+
+ goto -> bb3; // scope 0 at $DIR/const_goto_storage.rs:12:14: 12:19
92+
}
93+
94+
- bb12: {
95+
- StorageDead(_2); // scope 0 at $DIR/const_goto_storage.rs:13:6: 13:7
96+
+ bb3: {
97+
_0 = _1; // scope 1 at $DIR/const_goto_storage.rs:14:5: 14:8
98+
StorageDead(_1); // scope 0 at $DIR/const_goto_storage.rs:15:1: 15:2
99+
return; // scope 0 at $DIR/const_goto_storage.rs:15:2: 15:2
100+
}
101+
}
102+

Diff for: src/test/mir-opt/const_goto_storage.rs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// EMIT_MIR const_goto_storage.match_nested_if.ConstGoto.diff
2+
fn match_nested_if() -> bool {
3+
let val = match () {
4+
() if if if if true { true } else { false } { true } else { false } {
5+
true
6+
} else {
7+
false
8+
} =>
9+
{
10+
true
11+
}
12+
_ => false,
13+
};
14+
val
15+
}
16+
17+
fn main() {
18+
let _ = match_nested_if();
19+
}

Diff for: src/test/mir-opt/matches_reduce_branches.match_nested_if.MatchBranchSimplification.32bit.diff

+15-59
Original file line numberDiff line numberDiff line change
@@ -4,80 +4,36 @@
44
fn match_nested_if() -> bool {
55
let mut _0: bool; // return place in scope 0 at $DIR/matches_reduce_branches.rs:39:25: 39:29
66
let _1: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:40:9: 40:12
7-
let mut _2: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:41:18: 41:76
8-
let mut _3: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:41:21: 41:52
9-
let mut _4: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
10-
+ let mut _5: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
11-
+ let mut _6: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:41:21: 41:52
12-
+ let mut _7: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:41:18: 41:76
7+
let mut _2: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
8+
+ let mut _3: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
139
scope 1 {
1410
debug val => _1; // in scope 1 at $DIR/matches_reduce_branches.rs:40:9: 40:12
1511
}
1612

1713
bb0: {
1814
StorageLive(_1); // scope 0 at $DIR/matches_reduce_branches.rs:40:9: 40:12
19-
StorageLive(_2); // scope 0 at $DIR/matches_reduce_branches.rs:41:18: 41:76
20-
StorageLive(_3); // scope 0 at $DIR/matches_reduce_branches.rs:41:21: 41:52
21-
StorageLive(_4); // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
22-
_4 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
23-
- switchInt(move _4) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
15+
StorageLive(_2); // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
16+
_2 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
17+
- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
2418
- }
2519
-
2620
- bb1: {
27-
- _3 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:41:31: 41:35
28-
- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:41:21: 41:52
29-
- }
30-
-
31-
- bb2: {
32-
- _3 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:41:45: 41:50
33-
- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:41:21: 41:52
34-
- }
35-
-
36-
- bb3: {
37-
+ StorageLive(_5); // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
38-
+ _5 = move _4; // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
39-
+ _3 = Ne(_5, const false); // scope 0 at $DIR/matches_reduce_branches.rs:41:45: 41:50
40-
+ StorageDead(_5); // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
41-
StorageDead(_4); // scope 0 at $DIR/matches_reduce_branches.rs:41:51: 41:52
42-
- switchInt(move _3) -> [false: bb5, otherwise: bb4]; // scope 0 at $DIR/matches_reduce_branches.rs:41:21: 41:52
43-
- }
44-
-
45-
- bb4: {
46-
- _2 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:41:55: 41:59
47-
- goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:41:18: 41:76
48-
- }
49-
-
50-
- bb5: {
51-
- _2 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:41:69: 41:74
52-
- goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:41:18: 41:76
53-
- }
54-
-
55-
- bb6: {
56-
+ StorageLive(_6); // scope 0 at $DIR/matches_reduce_branches.rs:41:21: 41:52
57-
+ _6 = move _3; // scope 0 at $DIR/matches_reduce_branches.rs:41:21: 41:52
58-
+ _2 = Ne(_6, const false); // scope 0 at $DIR/matches_reduce_branches.rs:41:69: 41:74
59-
+ StorageDead(_6); // scope 0 at $DIR/matches_reduce_branches.rs:41:21: 41:52
60-
StorageDead(_3); // scope 0 at $DIR/matches_reduce_branches.rs:41:75: 41:76
61-
- switchInt(move _2) -> [false: bb8, otherwise: bb7]; // scope 0 at $DIR/matches_reduce_branches.rs:41:18: 41:76
62-
- }
63-
-
64-
- bb7: {
65-
+ StorageLive(_7); // scope 0 at $DIR/matches_reduce_branches.rs:41:18: 41:76
66-
+ _7 = move _2; // scope 0 at $DIR/matches_reduce_branches.rs:41:18: 41:76
67-
StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:45:9: 45:10
21+
+ StorageLive(_3); // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
22+
+ _3 = move _2; // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
23+
StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:41:51: 41:52
6824
- _1 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:47:13: 47:17
69-
- goto -> bb9; // scope 0 at $DIR/matches_reduce_branches.rs:47:13: 47:17
25+
- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:47:13: 47:17
7026
- }
7127
-
72-
- bb8: {
73-
- StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:45:9: 45:10
28+
- bb2: {
29+
- StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:41:51: 41:52
7430
- _1 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:49:14: 49:19
75-
- goto -> bb9; // scope 0 at $DIR/matches_reduce_branches.rs:49:14: 49:19
31+
- goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:49:14: 49:19
7632
- }
7733
-
78-
- bb9: {
79-
+ _1 = Ne(_7, const false); // scope 0 at $DIR/matches_reduce_branches.rs:49:14: 49:19
80-
+ StorageDead(_7); // scope 0 at $DIR/matches_reduce_branches.rs:41:18: 41:76
34+
- bb3: {
35+
+ _1 = Ne(_3, const false); // scope 0 at $DIR/matches_reduce_branches.rs:49:14: 49:19
36+
+ StorageDead(_3); // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
8137
_0 = _1; // scope 1 at $DIR/matches_reduce_branches.rs:51:5: 51:8
8238
StorageDead(_1); // scope 0 at $DIR/matches_reduce_branches.rs:52:1: 52:2
8339
return; // scope 0 at $DIR/matches_reduce_branches.rs:52:2: 52:2

0 commit comments

Comments
 (0)