Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e482894

Browse files
committed
Apply EarlyOtherwiseBranch even if the types are different when the target values are the same
1 parent 6658b16 commit e482894

5 files changed

+307
-3
lines changed

compiler/rustc_mir_transform/src/early_otherwise_branch.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -334,9 +334,6 @@ fn evaluate_candidate<'tcx>(
334334
return None;
335335
};
336336
let child_ty = child_discr.ty(body.local_decls(), tcx);
337-
if child_ty != parent_ty {
338-
return None;
339-
}
340337
if bbs[child].statements.len() > 1 {
341338
return None;
342339
}
@@ -424,6 +421,9 @@ fn evaluate_candidate<'tcx>(
424421
}
425422
}
426423
if same_target_value.is_none() {
424+
if child_ty != parent_ty {
425+
return None;
426+
}
427427
for (value, child) in targets.iter() {
428428
if !verify_candidate_branch(
429429
&bbs[child],
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
- // MIR for `opt10` before EarlyOtherwiseBranch
2+
+ // MIR for `opt10` after EarlyOtherwiseBranch
3+
4+
fn opt10(_1: E8, _2: E16) -> u32 {
5+
debug x => _1;
6+
debug y => _2;
7+
let mut _0: u32;
8+
let mut _3: (E8, E16);
9+
let mut _4: E8;
10+
let mut _5: E16;
11+
let mut _6: u16;
12+
let mut _7: u16;
13+
let mut _8: u16;
14+
let mut _9: u8;
15+
+ let mut _10: u16;
16+
17+
bb0: {
18+
StorageLive(_3);
19+
StorageLive(_4);
20+
_4 = move _1;
21+
StorageLive(_5);
22+
_5 = move _2;
23+
_3 = (move _4, move _5);
24+
StorageDead(_5);
25+
StorageDead(_4);
26+
_9 = discriminant((_3.0: E8));
27+
- switchInt(move _9) -> [0: bb2, 1: bb3, 2: bb4, otherwise: bb9];
28+
+ StorageLive(_10);
29+
+ _10 = discriminant((_3.1: E16));
30+
+ switchInt(move _10) -> [0: bb6, otherwise: bb1];
31+
}
32+
33+
bb1: {
34+
+ StorageDead(_10);
35+
_0 = const 0_u32;
36+
- goto -> bb8;
37+
+ goto -> bb5;
38+
}
39+
40+
bb2: {
41+
- _6 = discriminant((_3.1: E16));
42+
- switchInt(move _6) -> [0: bb5, otherwise: bb1];
43+
- }
44+
-
45+
- bb3: {
46+
- _7 = discriminant((_3.1: E16));
47+
- switchInt(move _7) -> [0: bb6, otherwise: bb1];
48+
- }
49+
-
50+
- bb4: {
51+
- _8 = discriminant((_3.1: E16));
52+
- switchInt(move _8) -> [0: bb7, otherwise: bb1];
53+
- }
54+
-
55+
- bb5: {
56+
_0 = const 1_u32;
57+
- goto -> bb8;
58+
+ goto -> bb5;
59+
}
60+
61+
- bb6: {
62+
+ bb3: {
63+
_0 = const 2_u32;
64+
- goto -> bb8;
65+
+ goto -> bb5;
66+
}
67+
68+
- bb7: {
69+
+ bb4: {
70+
_0 = const 3_u32;
71+
- goto -> bb8;
72+
+ goto -> bb5;
73+
}
74+
75+
- bb8: {
76+
+ bb5: {
77+
StorageDead(_3);
78+
return;
79+
}
80+
81+
- bb9: {
82+
- unreachable;
83+
+ bb6: {
84+
+ StorageDead(_10);
85+
+ switchInt(_9) -> [0: bb2, 1: bb3, 2: bb4, otherwise: bb1];
86+
}
87+
}
88+
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
- // MIR for `opt8` before EarlyOtherwiseBranch
2+
+ // MIR for `opt8` after EarlyOtherwiseBranch
3+
4+
fn opt8(_1: u32, _2: u64) -> u32 {
5+
debug x => _1;
6+
debug y => _2;
7+
let mut _0: u32;
8+
let mut _3: (u32, u64);
9+
let mut _4: u32;
10+
let mut _5: u64;
11+
12+
bb0: {
13+
StorageLive(_3);
14+
StorageLive(_4);
15+
_4 = _1;
16+
StorageLive(_5);
17+
_5 = _2;
18+
_3 = (move _4, move _5);
19+
StorageDead(_5);
20+
StorageDead(_4);
21+
- switchInt((_3.0: u32)) -> [1: bb2, 2: bb3, 3: bb4, otherwise: bb1];
22+
+ switchInt((_3.1: u64)) -> [10: bb6, otherwise: bb1];
23+
}
24+
25+
bb1: {
26+
_0 = const 0_u32;
27+
- goto -> bb8;
28+
+ goto -> bb5;
29+
}
30+
31+
bb2: {
32+
- switchInt((_3.1: u64)) -> [10: bb5, otherwise: bb1];
33+
+ _0 = const 4_u32;
34+
+ goto -> bb5;
35+
}
36+
37+
bb3: {
38+
- switchInt((_3.1: u64)) -> [10: bb6, otherwise: bb1];
39+
+ _0 = const 5_u32;
40+
+ goto -> bb5;
41+
}
42+
43+
bb4: {
44+
- switchInt((_3.1: u64)) -> [10: bb7, otherwise: bb1];
45+
+ _0 = const 6_u32;
46+
+ goto -> bb5;
47+
}
48+
49+
bb5: {
50+
- _0 = const 4_u32;
51+
- goto -> bb8;
52+
+ StorageDead(_3);
53+
+ return;
54+
}
55+
56+
bb6: {
57+
- _0 = const 5_u32;
58+
- goto -> bb8;
59+
- }
60+
-
61+
- bb7: {
62+
- _0 = const 6_u32;
63+
- goto -> bb8;
64+
- }
65+
-
66+
- bb8: {
67+
- StorageDead(_3);
68+
- return;
69+
+ switchInt((_3.0: u32)) -> [1: bb2, 2: bb3, 3: bb4, otherwise: bb1];
70+
}
71+
}
72+
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
- // MIR for `opt9` before EarlyOtherwiseBranch
2+
+ // MIR for `opt9` after EarlyOtherwiseBranch
3+
4+
fn opt9(_1: E8, _2: E16) -> u32 {
5+
debug x => _1;
6+
debug y => _2;
7+
let mut _0: u32;
8+
let mut _3: (E8, E16);
9+
let mut _4: E8;
10+
let mut _5: E16;
11+
let mut _6: u16;
12+
let mut _7: u16;
13+
let mut _8: u16;
14+
let mut _9: u8;
15+
16+
bb0: {
17+
StorageLive(_3);
18+
StorageLive(_4);
19+
_4 = move _1;
20+
StorageLive(_5);
21+
_5 = move _2;
22+
_3 = (move _4, move _5);
23+
StorageDead(_5);
24+
StorageDead(_4);
25+
_9 = discriminant((_3.0: E8));
26+
switchInt(move _9) -> [0: bb2, 1: bb3, 2: bb4, otherwise: bb9];
27+
}
28+
29+
bb1: {
30+
_0 = const 0_u32;
31+
goto -> bb8;
32+
}
33+
34+
bb2: {
35+
_6 = discriminant((_3.1: E16));
36+
switchInt(move _6) -> [0: bb5, otherwise: bb1];
37+
}
38+
39+
bb3: {
40+
_7 = discriminant((_3.1: E16));
41+
switchInt(move _7) -> [1: bb6, otherwise: bb1];
42+
}
43+
44+
bb4: {
45+
_8 = discriminant((_3.1: E16));
46+
switchInt(move _8) -> [2: bb7, otherwise: bb1];
47+
}
48+
49+
bb5: {
50+
_0 = const 1_u32;
51+
goto -> bb8;
52+
}
53+
54+
bb6: {
55+
_0 = const 2_u32;
56+
goto -> bb8;
57+
}
58+
59+
bb7: {
60+
_0 = const 3_u32;
61+
goto -> bb8;
62+
}
63+
64+
bb8: {
65+
StorageDead(_3);
66+
return;
67+
}
68+
69+
bb9: {
70+
unreachable;
71+
}
72+
}
73+

tests/mir-opt/early_otherwise_branch.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,74 @@ fn opt7(x: Option<u32>, y: Option<u32>) -> u32 {
115115
}
116116
}
117117

118+
// EMIT_MIR early_otherwise_branch.opt8.EarlyOtherwiseBranch.diff
119+
fn opt8(x: u32, y: u64) -> u32 {
120+
// CHECK-LABEL: fn opt8(
121+
// CHECK: bb0: {
122+
// CHECK: switchInt((_{{.*}}: u64)) -> [10: [[SWITCH_BB:bb.*]], otherwise: [[OTHERWISE:bb.*]]];
123+
// CHECK-NEXT: }
124+
// CHECK: [[SWITCH_BB]]:
125+
// CHECK: switchInt((_{{.*}}: u32)) -> [1: bb{{.*}}, 2: bb{{.*}}, 3: bb{{.*}}, otherwise: [[OTHERWISE]]];
126+
// CHECK-NEXT: }
127+
match (x, y) {
128+
(1, 10) => 4,
129+
(2, 10) => 5,
130+
(3, 10) => 6,
131+
_ => 0,
132+
}
133+
}
134+
135+
#[repr(u8)]
136+
enum E8 {
137+
A,
138+
B,
139+
C,
140+
}
141+
142+
#[repr(u16)]
143+
enum E16 {
144+
A,
145+
B,
146+
C,
147+
}
148+
149+
// Can we add a cast instruction for transformation?
150+
// EMIT_MIR early_otherwise_branch.opt9.EarlyOtherwiseBranch.diff
151+
fn opt9(x: E8, y: E16) -> u32 {
152+
// CHECK-LABEL: fn opt9(
153+
// CHECK: bb0: {
154+
// CHECK: [[LOCAL1:_.*]] = discriminant({{.*}});
155+
// CHECK-NOT: discriminant
156+
// CHECK: switchInt(move [[LOCAL1]]) -> [
157+
// CHECK-NEXT: }
158+
match (x, y) {
159+
(E8::A, E16::A) => 1,
160+
(E8::B, E16::B) => 2,
161+
(E8::C, E16::C) => 3,
162+
_ => 0,
163+
}
164+
}
165+
166+
// Since the target values are the same, we can optimize.
167+
// EMIT_MIR early_otherwise_branch.opt10.EarlyOtherwiseBranch.diff
168+
fn opt10(x: E8, y: E16) -> u32 {
169+
// CHECK-LABEL: fn opt10(
170+
// CHECK: bb0: {
171+
// CHECK: [[LOCAL1:_.*]] = discriminant({{.*}});
172+
// CHECK: [[LOCAL2:_.*]] = discriminant({{.*}});
173+
// CHECK: switchInt(move [[LOCAL2]]) -> [0: [[SWITCH_BB:bb.*]], otherwise: [[OTHERWISE:bb.*]]];
174+
// CHECK-NEXT: }
175+
// CHECK: [[SWITCH_BB]]:
176+
// CHECK: switchInt([[LOCAL1]]) -> [0: bb{{.*}}, 1: bb{{.*}}, 2: bb{{.*}}, otherwise: [[OTHERWISE]]];
177+
// CHECK-NEXT: }
178+
match (x, y) {
179+
(E8::A, E16::A) => 1,
180+
(E8::B, E16::A) => 2,
181+
(E8::C, E16::A) => 3,
182+
_ => 0,
183+
}
184+
}
185+
118186
fn main() {
119187
opt1(None, Some(0));
120188
opt2(None, Some(0));
@@ -123,4 +191,7 @@ fn main() {
123191
opt5(0, 0);
124192
opt6(0, 0);
125193
opt7(None, Some(0));
194+
opt8(0, 0);
195+
opt9(E8::A, E16::A);
196+
opt10(E8::A, E16::A);
126197
}

0 commit comments

Comments
 (0)