Skip to content

Commit cb2867d

Browse files
committed
fix pre binding false edges
1 parent a954dcc commit cb2867d

File tree

3 files changed

+104
-97
lines changed

3 files changed

+104
-97
lines changed

src/librustc_mir/build/matches/mod.rs

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
5656

5757
// create binding start block for link them by false edges
5858
let candidate_count = arms.iter().fold(0, |ac, c| ac + c.patterns.len());
59-
let binding_start_blocks: Vec<_> = (0..candidate_count + 1)
59+
let pre_binding_blocks: Vec<_> = (0..candidate_count + 1)
6060
.map(|_| self.cfg.start_new_block()).collect();
6161

6262
// assemble a list of candidates: there is one candidate per
@@ -72,23 +72,23 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
7272
arm.patterns.iter()
7373
.map(move |pat| (arm_index, pat, arm.guard.clone()))
7474
})
75-
.zip(binding_start_blocks.iter().zip(binding_start_blocks.iter().skip(1)))
75+
.zip(pre_binding_blocks.iter().zip(pre_binding_blocks.iter().skip(1)))
7676
.map(|((arm_index, pattern, guard),
77-
(binding_start_block, next_candidate_binding_start_block))| {
77+
(pre_binding_block, next_candidate_pre_binding_block))| {
7878
Candidate {
7979
span: pattern.span,
8080
match_pairs: vec![MatchPair::new(discriminant_lvalue.clone(), pattern)],
8181
bindings: vec![],
8282
guard,
8383
arm_index,
84-
binding_start_block: *binding_start_block,
85-
next_candidate_binding_start_block: *next_candidate_binding_start_block,
84+
pre_binding_block: *pre_binding_block,
85+
next_candidate_pre_binding_block: *next_candidate_pre_binding_block,
8686
}
8787
})
8888
.collect();
8989

9090
let outer_source_info = self.source_info(span);
91-
self.cfg.terminate(*binding_start_blocks.last().unwrap(),
91+
self.cfg.terminate(*pre_binding_blocks.last().unwrap(),
9292
outer_source_info, TerminatorKind::Unreachable);
9393

9494
// this will generate code to test discriminant_lvalue and
@@ -165,8 +165,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
165165

166166
// since we don't call `match_candidates`, next fields is unused
167167
arm_index: 0,
168-
binding_start_block: block,
169-
next_candidate_binding_start_block: block
168+
pre_binding_block: block,
169+
next_candidate_pre_binding_block: block
170170
};
171171

172172
// Simplify the candidate. Since the pattern is irrefutable, this should
@@ -298,8 +298,8 @@ pub struct Candidate<'pat, 'tcx:'pat> {
298298
arm_index: usize,
299299

300300
// ...and the blocks for add false edges between candidates
301-
binding_start_block: BasicBlock,
302-
next_candidate_binding_start_block: BasicBlock,
301+
pre_binding_block: BasicBlock,
302+
next_candidate_pre_binding_block: BasicBlock,
303303
}
304304

305305
#[derive(Clone, Debug)]
@@ -723,12 +723,15 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
723723
let candidate_source_info = self.source_info(candidate.span);
724724

725725
self.cfg.terminate(block, candidate_source_info,
726+
TerminatorKind::Goto { target: candidate.pre_binding_block });
727+
728+
block = self.cfg.start_new_block();
729+
self.cfg.terminate(candidate.pre_binding_block, candidate_source_info,
726730
TerminatorKind::FalseEdges {
727-
real_target: candidate.binding_start_block,
731+
real_target: block,
728732
imaginary_targets:
729-
vec![candidate.next_candidate_binding_start_block]});
733+
vec![candidate.next_candidate_pre_binding_block]});
730734

731-
block = candidate.binding_start_block;
732735
self.bind_matched_candidate(block, candidate.bindings);
733736

734737
if let Some(guard) = candidate.guard {
@@ -748,7 +751,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
748751
TerminatorKind::FalseEdges {
749752
real_target: otherwise,
750753
imaginary_targets:
751-
vec![candidate.next_candidate_binding_start_block] });
754+
vec![candidate.next_candidate_pre_binding_block] });
752755
Some(otherwise)
753756
} else {
754757
self.cfg.terminate(block, candidate_source_info,

src/librustc_mir/build/matches/test.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -598,8 +598,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
598598
bindings: candidate.bindings.clone(),
599599
guard: candidate.guard.clone(),
600600
arm_index: candidate.arm_index,
601-
binding_start_block: candidate.binding_start_block,
602-
next_candidate_binding_start_block: candidate.next_candidate_binding_start_block,
601+
pre_binding_block: candidate.pre_binding_block,
602+
next_candidate_pre_binding_block: candidate.next_candidate_pre_binding_block,
603603
}
604604
}
605605

@@ -661,8 +661,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
661661
bindings: candidate.bindings.clone(),
662662
guard: candidate.guard.clone(),
663663
arm_index: candidate.arm_index,
664-
binding_start_block: candidate.binding_start_block,
665-
next_candidate_binding_start_block: candidate.next_candidate_binding_start_block,
664+
pre_binding_block: candidate.pre_binding_block,
665+
next_candidate_pre_binding_block: candidate.next_candidate_pre_binding_block,
666666
}
667667
}
668668

src/test/mir-opt/match_false_edges.rs

Lines changed: 83 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ fn main() {
4343
// ...
4444
// _2 = std::option::Option<i32>::Some(const 42i32,);
4545
// _5 = discriminant(_2);
46-
// switchInt(_5) -> [0isize: bb6, otherwise: bb7];
46+
// switchInt(_5) -> [0isize: bb5, otherwise: bb3];
4747
// }
4848
// bb1: { // arm1
4949
// StorageLive(_7);
@@ -52,13 +52,35 @@ fn main() {
5252
// ...
5353
// goto -> bb11;
5454
// }
55-
// bb2: { // binding1 guard
55+
// bb2: { // binding3(empty) and arm3
56+
// _1 = const 3i32;
57+
// goto -> bb11;
58+
// }
59+
// bb3: {
60+
// falseEdges -> [real: bb7, imaginary: bb4]; //pre_binding1
61+
// }
62+
// bb4: {
63+
// falseEdges -> [real: bb10, imaginary: bb5]; //pre_binding2
64+
// }
65+
// bb5: {
66+
// falseEdges -> [real: bb2, imaginary: bb6]; //pre_binding3
67+
// }
68+
// bb6: {
69+
// unreachable;
70+
// }
71+
// bb7: { // binding1 and guard
5672
// StorageLive(_3);
5773
// _3 = ((_2 as Some).0: i32);
5874
// StorageLive(_6);
5975
// _6 = const guard() -> bb8;
6076
// }
61-
// bb3: { // binding2 & arm2
77+
// bb8: { // end of guard
78+
// switchInt(_6) -> [0u8: bb9, otherwise: bb1];
79+
// }
80+
// bb9: { // to pre_binding2
81+
// falseEdges -> [real: bb4, imaginary: bb4];
82+
// }
83+
// bb10: { // binding2 and arm2
6284
// StorageLive(_4);
6385
// _4 = ((_2 as Some).0: i32);
6486
// StorageLive(_8);
@@ -67,28 +89,6 @@ fn main() {
6789
// StorageDead(_8);
6890
// goto -> bb11;
6991
// }
70-
// bb4: { // binding3(empty) arm3
71-
// _1 = const 3i32;
72-
// goto -> bb11;
73-
// }
74-
// bb5: {
75-
// unreachable;
76-
// }
77-
// bb6: {
78-
// falseEdges -> [real: bb4, imaginary: bb5]; // from before_binding3 to unreachable
79-
// }
80-
// bb7: {
81-
// falseEdges -> [real: bb2, imaginary: bb3]; // from before_binding1 to binding2
82-
// }
83-
// bb8: {
84-
// switchInt(_6) -> [0u8: bb9, otherwise: bb1]; // end of guard
85-
// }
86-
// bb9: {
87-
// falseEdges -> [real: bb10, imaginary: bb3]; // after_guard to binding2
88-
// }
89-
// bb10: {
90-
// falseEdges -> [real: bb3, imaginary: bb4]; // from before_binding2 to binding3
91-
// }
9292
// bb11: {
9393
// ...
9494
// return;
@@ -102,68 +102,72 @@ fn main() {
102102
// ...
103103
// _2 = std::option::Option<i32>::Some(const 1i32,);
104104
// _7 = discriminant(_2);
105-
// switchInt(_7) -> [1isize: bb8, otherwise: bb11];
105+
// switchInt(_7) -> [1isize: bb3, otherwise: bb4];
106106
// }
107107
// bb1: { // arm1
108108
// _1 = const 1i32;
109-
// goto -> bb15;
109+
// goto -> bb16;
110110
// }
111111
// bb2: { // arm3
112112
// _1 = const 3i32;
113-
// goto -> bb15;
114-
// }
115-
// bb3: { // binding1: Some(w) if guard() =>
116-
// StorageLive(_3);
117-
// _3 = ((_2 as Some).0: i32);
118-
// StorageLive(_8);
119-
// _8 = const guard() -> bb9;
120-
// }
121-
// bb4: { // binding2 & arm2
122-
// StorageLive(_4);
123-
// _4 = _2;
124-
// _1 = const 2i32;
125-
// goto -> bb15;
126-
// }
127-
// bb5: { // binding3: Some(y) if guard2(y) =>
128-
// StorageLive(_5);
129-
// _5 = ((_2 as Some).0: i32);
130-
// StorageLive(_10);
131-
// StorageLive(_11);
132-
// _11 = _5;
133-
// _10 = const guard2(_11) -> bb12;
134-
// }
135-
// bb6: { // binding4 & arm4
136-
// StorageLive(_6);
137-
// _6 = _2;
138-
// _1 = const 4i32;
139-
// goto -> bb15;
140-
// }
141-
// bb7: {
142-
// unreachable;
113+
// goto -> bb16;
143114
// }
144-
// bb8: {
145-
// falseEdges -> [real: bb3, imaginary: bb4]; // from before_binding1 to binding2
146-
// }
147-
// bb9: {
148-
// switchInt(_8) -> [0u8: bb10, otherwise: bb1]; // end of gurard
149-
// }
150-
// bb10: {
151-
// falseEdges -> [real: bb11, imaginary: bb4]; // after guard to binding2
152-
// }
153-
// bb11: {
154-
// falseEdges -> [real: bb4, imaginary: bb5]; // from before_binding2 to binding3
155-
// }
156-
// bb12: {
115+
//
116+
// bb3: {
117+
// falseEdges -> [real: bb8, imaginary: bb4]; //pre_binding1
118+
// }
119+
// bb4: {
120+
// falseEdges -> [real: bb11, imaginary: bb5]; //pre_binding2
121+
// }
122+
// bb5: {
123+
// falseEdges -> [real: bb12, imaginary: bb6]; //pre_binding3
124+
// }
125+
// bb6: {
126+
// falseEdges -> [real: bb15, imaginary: bb7]; //pre_binding4
127+
// }
128+
// bb7: {
129+
// unreachable;
130+
// }
131+
// bb8: { // binding1: Some(w) if guard()
132+
// StorageLive(_3);
133+
// _3 = ((_2 as Some).0: i32);
134+
// StorageLive(_8);
135+
// _8 = const guard() -> bb9;
136+
// }
137+
// bb9: { //end of guard
138+
// switchInt(_8) -> [0u8: bb10, otherwise: bb1];
139+
// }
140+
// bb10: { // to pre_binding2
141+
// falseEdges -> [real: bb4, imaginary: bb4];
142+
// }
143+
// bb11: { // binding2 & arm2
144+
// StorageLive(_4);
145+
// _4 = _2;
146+
// _1 = const 2i32;
147+
// goto -> bb16;
148+
// }
149+
// bb12: { // binding3: Some(y) if guard2(y)
150+
// StorageLive(_5);
151+
// _5 = ((_2 as Some).0: i32);
152+
// StorageLive(_10);
153+
// StorageLive(_11);
154+
// _11 = _5;
155+
// _10 = const guard2(_11) -> bb13;
156+
// }
157+
// bb13: { // end of guard2
157158
// StorageDead(_11);
158-
// switchInt(_10) -> [0u8: bb13, otherwise: bb2]; // end of guard2
159-
// }
160-
// bb13: {
161-
// falseEdges -> [real: bb14, imaginary: bb6]; // after guard2 to binding4
162-
// }
163-
// bb14: {
164-
// falseEdges -> [real: bb6, imaginary: bb7]; // from befor binding4 to unreachable
165-
// }
166-
// bb15: {
159+
// switchInt(_10) -> [0u8: bb14, otherwise: bb2];
160+
// }
161+
// bb14: { // to pre_binding4
162+
// falseEdges -> [real: bb6, imaginary: bb6];
163+
// }
164+
// bb15: { // binding4 & arm4
165+
// StorageLive(_6);
166+
// _6 = _2;
167+
// _1 = const 4i32;
168+
// goto -> bb16;
169+
// }
170+
// bb16: {
167171
// ...
168172
// return;
169173
// }

0 commit comments

Comments
 (0)