Skip to content

Commit 3e5aae3

Browse files
committed
const_goto, permite StorageDead statements
1 parent 902e590 commit 3e5aae3

6 files changed

+277
-149
lines changed

compiler/rustc_mir_transform/src/const_goto.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@ impl<'tcx> MirPass<'tcx> for ConstGoto {
4343
let new_goto = TerminatorKind::Goto { target: opt.target_to_use_in_goto };
4444
debug!("SUCCESS: replacing `{:?}` with `{:?}`", terminator.kind, new_goto);
4545
terminator.kind = new_goto;
46+
47+
let bridge_bb_statement = &body.basic_blocks()[opt.bridge_bb].statements;
48+
if !bridge_bb_statement.is_empty() {
49+
let storagedeads = bridge_bb_statement.clone();
50+
body.basic_blocks_mut()[opt.bb_with_goto].statements.extend(storagedeads);
51+
debug!("SUCCESS: extending terminator's basic block with briding basic block.");
52+
}
4653
}
4754

4855
// if we applied optimizations, we potentially have some cfg to cleanup to
@@ -67,12 +74,13 @@ impl<'tcx> Visitor<'tcx> for ConstGotoOptimizationFinder<'_, 'tcx> {
6774
// We found a constant being assigned to `place`.
6875
// Now check that the target of this Goto switches on this place.
6976
let target_bb = &self.body.basic_blocks()[target];
70-
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() {
77+
let target_bb_statements = &target_bb.statements;
78+
if !target_bb_statements.is_empty()
79+
&& !target_bb_statements.iter().all(|statement| match statement.kind {
80+
StatementKind::StorageDead(_) => true,
81+
_ => false,
82+
})
83+
{
7684
None?
7785
}
7886

@@ -86,6 +94,7 @@ impl<'tcx> Visitor<'tcx> for ConstGotoOptimizationFinder<'_, 'tcx> {
8694
let target_to_use_in_goto = targets.target_for_value(const_value);
8795
self.optimizations.push(OptimizationToApply {
8896
bb_with_goto: location.block,
97+
bridge_bb: target,
8998
target_to_use_in_goto,
9099
});
91100
}
@@ -99,6 +108,7 @@ impl<'tcx> Visitor<'tcx> for ConstGotoOptimizationFinder<'_, 'tcx> {
99108

100109
struct OptimizationToApply {
101110
bb_with_goto: BasicBlock,
111+
bridge_bb: BasicBlock,
102112
target_to_use_in_goto: BasicBlock,
103113
}
104114

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
- // MIR for `match_nested_if` before MatchBranchSimplification
2+
+ // MIR for `match_nested_if` after MatchBranchSimplification
3+
4+
fn match_nested_if() -> bool {
5+
let mut _0: bool; // return place in scope 0 at $DIR/const_goto.rs:16:25: 16:29
6+
let _1: bool; // in scope 0 at $DIR/const_goto.rs:17:9: 17:12
7+
let mut _2: bool; // in scope 0 at $DIR/const_goto.rs:18:24: 18:28
8+
+ let mut _3: bool; // in scope 0 at $DIR/const_goto.rs:18:24: 18:28
9+
scope 1 {
10+
debug val => _1; // in scope 1 at $DIR/const_goto.rs:17:9: 17:12
11+
}
12+
13+
bb0: {
14+
StorageLive(_1); // scope 0 at $DIR/const_goto.rs:17:9: 17:12
15+
StorageLive(_2); // scope 0 at $DIR/const_goto.rs:18:24: 18:28
16+
_2 = const true; // scope 0 at $DIR/const_goto.rs:18:24: 18:28
17+
- switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/const_goto.rs:18:24: 18:28
18+
- }
19+
-
20+
- bb1: {
21+
+ StorageLive(_3); // scope 0 at $DIR/const_goto.rs:18:24: 18:28
22+
+ _3 = move _2; // scope 0 at $DIR/const_goto.rs:18:24: 18:28
23+
StorageDead(_2); // scope 0 at $DIR/const_goto.rs:18:51: 18:52
24+
- _1 = const true; // scope 0 at $DIR/const_goto.rs:24:13: 24:17
25+
- goto -> bb3; // scope 0 at $DIR/const_goto.rs:24:13: 24:17
26+
- }
27+
-
28+
- bb2: {
29+
- StorageDead(_2); // scope 0 at $DIR/const_goto.rs:18:51: 18:52
30+
- _1 = const false; // scope 0 at $DIR/const_goto.rs:26:14: 26:19
31+
- goto -> bb3; // scope 0 at $DIR/const_goto.rs:26:14: 26:19
32+
- }
33+
-
34+
- bb3: {
35+
+ _1 = Ne(_3, const false); // scope 0 at $DIR/const_goto.rs:26:14: 26:19
36+
+ StorageDead(_3); // scope 0 at $DIR/const_goto.rs:18:24: 18:28
37+
_0 = _1; // scope 1 at $DIR/const_goto.rs:28:5: 28:8
38+
StorageDead(_1); // scope 0 at $DIR/const_goto.rs:29:1: 29:2
39+
return; // scope 0 at $DIR/const_goto.rs:29:2: 29:2
40+
}
41+
}
42+

src/test/mir-opt/const_goto.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,24 @@ pub enum Foo {
1111
fn issue_77355_opt(num: Foo) -> u64 {
1212
if matches!(num, Foo::B | Foo::C) { 23 } else { 42 }
1313
}
14+
15+
// EMIT_MIR const_goto.match_nested_if.MatchBranchSimplification.diff
16+
fn match_nested_if() -> bool {
17+
let val = match () {
18+
() if if if if true { true } else { false } { true } else { false } {
19+
true
20+
} else {
21+
false
22+
} =>
23+
{
24+
true
25+
}
26+
_ => false,
27+
};
28+
val
29+
}
30+
1431
fn main() {
1532
issue_77355_opt(Foo::A);
33+
let _ = match_nested_if();
1634
}

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

Lines changed: 98 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,114 @@
11
- // MIR for `match_nested_if` before MatchBranchSimplification
22
+ // MIR for `match_nested_if` after MatchBranchSimplification
33

4-
fn match_nested_if() -> bool {
5-
let mut _0: bool; // return place in scope 0 at $DIR/matches_reduce_branches.rs:39:25: 39:29
6-
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
4+
fn match_nested_if(_1: bool, _2: bool) -> bool {
5+
debug flag0 => _1; // in scope 0 at $DIR/matches_reduce_branches.rs:39:20: 39:25
6+
debug flag1 => _2; // in scope 0 at $DIR/matches_reduce_branches.rs:39:33: 39:38
7+
let mut _0: bool; // return place in scope 0 at $DIR/matches_reduce_branches.rs:39:49: 39:53
8+
let _3: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:40:9: 40:12
9+
let mut _4: (); // in scope 0 at $DIR/matches_reduce_branches.rs:40:21: 40:23
10+
let mut _5: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:41:15: 45:10
11+
let mut _6: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:41:18: 41:78
12+
let mut _7: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:41:21: 41:53
13+
let mut _8: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
14+
let mut _9: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:42:13: 42:18
15+
let mut _10: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:42:21: 42:26
16+
let mut _11: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:44:13: 44:18
17+
let mut _12: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:44:21: 44:26
18+
+ let mut _13: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:41:15: 45:10
1319
scope 1 {
14-
debug val => _1; // in scope 1 at $DIR/matches_reduce_branches.rs:40:9: 40:12
20+
debug val => _3; // in scope 1 at $DIR/matches_reduce_branches.rs:40:9: 40:12
1521
}
1622

1723
bb0: {
18-
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
24-
- }
25-
-
26-
- 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
24+
StorageLive(_3); // scope 0 at $DIR/matches_reduce_branches.rs:40:9: 40:12
25+
StorageLive(_4); // scope 0 at $DIR/matches_reduce_branches.rs:40:21: 40:23
26+
StorageLive(_5); // scope 0 at $DIR/matches_reduce_branches.rs:41:15: 45:10
27+
StorageLive(_6); // scope 0 at $DIR/matches_reduce_branches.rs:41:18: 41:78
28+
StorageLive(_7); // scope 0 at $DIR/matches_reduce_branches.rs:41:21: 41:53
29+
StorageLive(_8); // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
30+
_8 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
31+
switchInt(move _8) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:41:24: 41:28
32+
}
33+
34+
bb1: {
35+
_7 = _1; // scope 0 at $DIR/matches_reduce_branches.rs:41:31: 41:36
36+
goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:41:21: 41:53
37+
}
38+
39+
bb2: {
40+
_7 = _2; // scope 0 at $DIR/matches_reduce_branches.rs:41:46: 41:51
41+
goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:41:21: 41:53
42+
}
43+
44+
bb3: {
45+
StorageDead(_8); // scope 0 at $DIR/matches_reduce_branches.rs:41:52: 41:53
46+
switchInt(move _7) -> [false: bb5, otherwise: bb4]; // scope 0 at $DIR/matches_reduce_branches.rs:41:21: 41:53
47+
}
48+
49+
bb4: {
50+
_6 = _2; // scope 0 at $DIR/matches_reduce_branches.rs:41:56: 41:61
51+
goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:41:18: 41:78
52+
}
53+
54+
bb5: {
55+
_6 = _1; // scope 0 at $DIR/matches_reduce_branches.rs:41:71: 41:76
56+
goto -> bb6; // scope 0 at $DIR/matches_reduce_branches.rs:41:18: 41:78
57+
}
58+
59+
bb6: {
60+
StorageDead(_7); // scope 0 at $DIR/matches_reduce_branches.rs:41:77: 41:78
61+
switchInt(move _6) -> [false: bb8, otherwise: bb7]; // scope 0 at $DIR/matches_reduce_branches.rs:41:18: 41:78
62+
}
63+
64+
bb7: {
65+
StorageLive(_9); // scope 0 at $DIR/matches_reduce_branches.rs:42:13: 42:18
66+
_9 = _1; // scope 0 at $DIR/matches_reduce_branches.rs:42:13: 42:18
67+
StorageLive(_10); // scope 0 at $DIR/matches_reduce_branches.rs:42:21: 42:26
68+
_10 = _2; // scope 0 at $DIR/matches_reduce_branches.rs:42:21: 42:26
69+
_5 = BitAnd(move _9, move _10); // scope 0 at $DIR/matches_reduce_branches.rs:42:13: 42:26
70+
StorageDead(_10); // scope 0 at $DIR/matches_reduce_branches.rs:42:25: 42:26
71+
StorageDead(_9); // scope 0 at $DIR/matches_reduce_branches.rs:42:25: 42:26
72+
goto -> bb9; // scope 0 at $DIR/matches_reduce_branches.rs:41:15: 45:10
73+
}
74+
75+
bb8: {
76+
StorageLive(_11); // scope 0 at $DIR/matches_reduce_branches.rs:44:13: 44:18
77+
_11 = _1; // scope 0 at $DIR/matches_reduce_branches.rs:44:13: 44:18
78+
StorageLive(_12); // scope 0 at $DIR/matches_reduce_branches.rs:44:21: 44:26
79+
_12 = _2; // scope 0 at $DIR/matches_reduce_branches.rs:44:21: 44:26
80+
_5 = BitOr(move _11, move _12); // scope 0 at $DIR/matches_reduce_branches.rs:44:13: 44:26
81+
StorageDead(_12); // scope 0 at $DIR/matches_reduce_branches.rs:44:25: 44:26
82+
StorageDead(_11); // scope 0 at $DIR/matches_reduce_branches.rs:44:25: 44:26
83+
goto -> bb9; // scope 0 at $DIR/matches_reduce_branches.rs:41:15: 45:10
84+
}
85+
86+
bb9: {
87+
- switchInt(move _5) -> [false: bb11, otherwise: bb10]; // scope 0 at $DIR/matches_reduce_branches.rs:41:15: 45:10
6288
- }
6389
-
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
68-
- _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
90+
- bb10: {
91+
+ StorageLive(_13); // scope 0 at $DIR/matches_reduce_branches.rs:41:15: 45:10
92+
+ _13 = move _5; // scope 0 at $DIR/matches_reduce_branches.rs:41:15: 45:10
93+
StorageDead(_6); // scope 0 at $DIR/matches_reduce_branches.rs:45:9: 45:10
94+
StorageDead(_5); // scope 0 at $DIR/matches_reduce_branches.rs:45:9: 45:10
95+
- _3 = const true; // scope 0 at $DIR/matches_reduce_branches.rs:47:13: 47:17
96+
- goto -> bb12; // scope 0 at $DIR/matches_reduce_branches.rs:47:13: 47:17
7097
- }
7198
-
72-
- bb8: {
73-
- StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:45:9: 45:10
74-
- _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
99+
- bb11: {
100+
- StorageDead(_6); // scope 0 at $DIR/matches_reduce_branches.rs:45:9: 45:10
101+
- StorageDead(_5); // scope 0 at $DIR/matches_reduce_branches.rs:45:9: 45:10
102+
- _3 = const false; // scope 0 at $DIR/matches_reduce_branches.rs:49:14: 49:19
103+
- goto -> bb12; // scope 0 at $DIR/matches_reduce_branches.rs:49:14: 49:19
76104
- }
77105
-
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
81-
_0 = _1; // scope 1 at $DIR/matches_reduce_branches.rs:51:5: 51:8
82-
StorageDead(_1); // scope 0 at $DIR/matches_reduce_branches.rs:52:1: 52:2
106+
- bb12: {
107+
+ _3 = Ne(_13, const false); // scope 0 at $DIR/matches_reduce_branches.rs:49:14: 49:19
108+
+ StorageDead(_13); // scope 0 at $DIR/matches_reduce_branches.rs:41:15: 45:10
109+
StorageDead(_4); // scope 0 at $DIR/matches_reduce_branches.rs:50:6: 50:7
110+
_0 = _3; // scope 1 at $DIR/matches_reduce_branches.rs:51:5: 51:8
111+
StorageDead(_3); // scope 0 at $DIR/matches_reduce_branches.rs:52:1: 52:2
83112
return; // scope 0 at $DIR/matches_reduce_branches.rs:52:2: 52:2
84113
}
85114
}

0 commit comments

Comments
 (0)