fix pre binding false edges
This commit is contained in:
parent
a954dcc72e
commit
cb2867da88
@ -56,7 +56,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
|
||||
// create binding start block for link them by false edges
|
||||
let candidate_count = arms.iter().fold(0, |ac, c| ac + c.patterns.len());
|
||||
let binding_start_blocks: Vec<_> = (0..candidate_count + 1)
|
||||
let pre_binding_blocks: Vec<_> = (0..candidate_count + 1)
|
||||
.map(|_| self.cfg.start_new_block()).collect();
|
||||
|
||||
// assemble a list of candidates: there is one candidate per
|
||||
@ -72,23 +72,23 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
arm.patterns.iter()
|
||||
.map(move |pat| (arm_index, pat, arm.guard.clone()))
|
||||
})
|
||||
.zip(binding_start_blocks.iter().zip(binding_start_blocks.iter().skip(1)))
|
||||
.zip(pre_binding_blocks.iter().zip(pre_binding_blocks.iter().skip(1)))
|
||||
.map(|((arm_index, pattern, guard),
|
||||
(binding_start_block, next_candidate_binding_start_block))| {
|
||||
(pre_binding_block, next_candidate_pre_binding_block))| {
|
||||
Candidate {
|
||||
span: pattern.span,
|
||||
match_pairs: vec![MatchPair::new(discriminant_lvalue.clone(), pattern)],
|
||||
bindings: vec![],
|
||||
guard,
|
||||
arm_index,
|
||||
binding_start_block: *binding_start_block,
|
||||
next_candidate_binding_start_block: *next_candidate_binding_start_block,
|
||||
pre_binding_block: *pre_binding_block,
|
||||
next_candidate_pre_binding_block: *next_candidate_pre_binding_block,
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
let outer_source_info = self.source_info(span);
|
||||
self.cfg.terminate(*binding_start_blocks.last().unwrap(),
|
||||
self.cfg.terminate(*pre_binding_blocks.last().unwrap(),
|
||||
outer_source_info, TerminatorKind::Unreachable);
|
||||
|
||||
// this will generate code to test discriminant_lvalue and
|
||||
@ -165,8 +165,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
|
||||
// since we don't call `match_candidates`, next fields is unused
|
||||
arm_index: 0,
|
||||
binding_start_block: block,
|
||||
next_candidate_binding_start_block: block
|
||||
pre_binding_block: block,
|
||||
next_candidate_pre_binding_block: block
|
||||
};
|
||||
|
||||
// Simplify the candidate. Since the pattern is irrefutable, this should
|
||||
@ -298,8 +298,8 @@ pub struct Candidate<'pat, 'tcx:'pat> {
|
||||
arm_index: usize,
|
||||
|
||||
// ...and the blocks for add false edges between candidates
|
||||
binding_start_block: BasicBlock,
|
||||
next_candidate_binding_start_block: BasicBlock,
|
||||
pre_binding_block: BasicBlock,
|
||||
next_candidate_pre_binding_block: BasicBlock,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@ -723,12 +723,15 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
let candidate_source_info = self.source_info(candidate.span);
|
||||
|
||||
self.cfg.terminate(block, candidate_source_info,
|
||||
TerminatorKind::FalseEdges {
|
||||
real_target: candidate.binding_start_block,
|
||||
imaginary_targets:
|
||||
vec![candidate.next_candidate_binding_start_block]});
|
||||
TerminatorKind::Goto { target: candidate.pre_binding_block });
|
||||
|
||||
block = self.cfg.start_new_block();
|
||||
self.cfg.terminate(candidate.pre_binding_block, candidate_source_info,
|
||||
TerminatorKind::FalseEdges {
|
||||
real_target: block,
|
||||
imaginary_targets:
|
||||
vec![candidate.next_candidate_pre_binding_block]});
|
||||
|
||||
block = candidate.binding_start_block;
|
||||
self.bind_matched_candidate(block, candidate.bindings);
|
||||
|
||||
if let Some(guard) = candidate.guard {
|
||||
@ -748,7 +751,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
TerminatorKind::FalseEdges {
|
||||
real_target: otherwise,
|
||||
imaginary_targets:
|
||||
vec![candidate.next_candidate_binding_start_block] });
|
||||
vec![candidate.next_candidate_pre_binding_block] });
|
||||
Some(otherwise)
|
||||
} else {
|
||||
self.cfg.terminate(block, candidate_source_info,
|
||||
|
@ -598,8 +598,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
bindings: candidate.bindings.clone(),
|
||||
guard: candidate.guard.clone(),
|
||||
arm_index: candidate.arm_index,
|
||||
binding_start_block: candidate.binding_start_block,
|
||||
next_candidate_binding_start_block: candidate.next_candidate_binding_start_block,
|
||||
pre_binding_block: candidate.pre_binding_block,
|
||||
next_candidate_pre_binding_block: candidate.next_candidate_pre_binding_block,
|
||||
}
|
||||
}
|
||||
|
||||
@ -661,8 +661,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
bindings: candidate.bindings.clone(),
|
||||
guard: candidate.guard.clone(),
|
||||
arm_index: candidate.arm_index,
|
||||
binding_start_block: candidate.binding_start_block,
|
||||
next_candidate_binding_start_block: candidate.next_candidate_binding_start_block,
|
||||
pre_binding_block: candidate.pre_binding_block,
|
||||
next_candidate_pre_binding_block: candidate.next_candidate_pre_binding_block,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ fn main() {
|
||||
// ...
|
||||
// _2 = std::option::Option<i32>::Some(const 42i32,);
|
||||
// _5 = discriminant(_2);
|
||||
// switchInt(_5) -> [0isize: bb6, otherwise: bb7];
|
||||
// switchInt(_5) -> [0isize: bb5, otherwise: bb3];
|
||||
// }
|
||||
// bb1: { // arm1
|
||||
// StorageLive(_7);
|
||||
@ -52,13 +52,35 @@ fn main() {
|
||||
// ...
|
||||
// goto -> bb11;
|
||||
// }
|
||||
// bb2: { // binding1 guard
|
||||
// bb2: { // binding3(empty) and arm3
|
||||
// _1 = const 3i32;
|
||||
// goto -> bb11;
|
||||
// }
|
||||
// bb3: {
|
||||
// falseEdges -> [real: bb7, imaginary: bb4]; //pre_binding1
|
||||
// }
|
||||
// bb4: {
|
||||
// falseEdges -> [real: bb10, imaginary: bb5]; //pre_binding2
|
||||
// }
|
||||
// bb5: {
|
||||
// falseEdges -> [real: bb2, imaginary: bb6]; //pre_binding3
|
||||
// }
|
||||
// bb6: {
|
||||
// unreachable;
|
||||
// }
|
||||
// bb7: { // binding1 and guard
|
||||
// StorageLive(_3);
|
||||
// _3 = ((_2 as Some).0: i32);
|
||||
// StorageLive(_6);
|
||||
// _6 = const guard() -> bb8;
|
||||
// }
|
||||
// bb3: { // binding2 & arm2
|
||||
// bb8: { // end of guard
|
||||
// switchInt(_6) -> [0u8: bb9, otherwise: bb1];
|
||||
// }
|
||||
// bb9: { // to pre_binding2
|
||||
// falseEdges -> [real: bb4, imaginary: bb4];
|
||||
// }
|
||||
// bb10: { // binding2 and arm2
|
||||
// StorageLive(_4);
|
||||
// _4 = ((_2 as Some).0: i32);
|
||||
// StorageLive(_8);
|
||||
@ -67,28 +89,6 @@ fn main() {
|
||||
// StorageDead(_8);
|
||||
// goto -> bb11;
|
||||
// }
|
||||
// bb4: { // binding3(empty) arm3
|
||||
// _1 = const 3i32;
|
||||
// goto -> bb11;
|
||||
// }
|
||||
// bb5: {
|
||||
// unreachable;
|
||||
// }
|
||||
// bb6: {
|
||||
// falseEdges -> [real: bb4, imaginary: bb5]; // from before_binding3 to unreachable
|
||||
// }
|
||||
// bb7: {
|
||||
// falseEdges -> [real: bb2, imaginary: bb3]; // from before_binding1 to binding2
|
||||
// }
|
||||
// bb8: {
|
||||
// switchInt(_6) -> [0u8: bb9, otherwise: bb1]; // end of guard
|
||||
// }
|
||||
// bb9: {
|
||||
// falseEdges -> [real: bb10, imaginary: bb3]; // after_guard to binding2
|
||||
// }
|
||||
// bb10: {
|
||||
// falseEdges -> [real: bb3, imaginary: bb4]; // from before_binding2 to binding3
|
||||
// }
|
||||
// bb11: {
|
||||
// ...
|
||||
// return;
|
||||
@ -102,68 +102,72 @@ fn main() {
|
||||
// ...
|
||||
// _2 = std::option::Option<i32>::Some(const 1i32,);
|
||||
// _7 = discriminant(_2);
|
||||
// switchInt(_7) -> [1isize: bb8, otherwise: bb11];
|
||||
// switchInt(_7) -> [1isize: bb3, otherwise: bb4];
|
||||
// }
|
||||
// bb1: { // arm1
|
||||
// _1 = const 1i32;
|
||||
// goto -> bb15;
|
||||
// goto -> bb16;
|
||||
// }
|
||||
// bb2: { // arm3
|
||||
// _1 = const 3i32;
|
||||
// goto -> bb15;
|
||||
// goto -> bb16;
|
||||
// }
|
||||
// bb3: { // binding1: Some(w) if guard() =>
|
||||
// StorageLive(_3);
|
||||
// _3 = ((_2 as Some).0: i32);
|
||||
// StorageLive(_8);
|
||||
// _8 = const guard() -> bb9;
|
||||
// }
|
||||
// bb4: { // binding2 & arm2
|
||||
// StorageLive(_4);
|
||||
// _4 = _2;
|
||||
// _1 = const 2i32;
|
||||
// goto -> bb15;
|
||||
// }
|
||||
// bb5: { // binding3: Some(y) if guard2(y) =>
|
||||
// StorageLive(_5);
|
||||
// _5 = ((_2 as Some).0: i32);
|
||||
// StorageLive(_10);
|
||||
// StorageLive(_11);
|
||||
// _11 = _5;
|
||||
// _10 = const guard2(_11) -> bb12;
|
||||
// }
|
||||
// bb6: { // binding4 & arm4
|
||||
// StorageLive(_6);
|
||||
// _6 = _2;
|
||||
// _1 = const 4i32;
|
||||
// goto -> bb15;
|
||||
// }
|
||||
// bb7: {
|
||||
// unreachable;
|
||||
// }
|
||||
// bb8: {
|
||||
// falseEdges -> [real: bb3, imaginary: bb4]; // from before_binding1 to binding2
|
||||
// }
|
||||
// bb9: {
|
||||
// switchInt(_8) -> [0u8: bb10, otherwise: bb1]; // end of gurard
|
||||
// }
|
||||
// bb10: {
|
||||
// falseEdges -> [real: bb11, imaginary: bb4]; // after guard to binding2
|
||||
// }
|
||||
// bb11: {
|
||||
// falseEdges -> [real: bb4, imaginary: bb5]; // from before_binding2 to binding3
|
||||
// }
|
||||
// bb12: {
|
||||
//
|
||||
// bb3: {
|
||||
// falseEdges -> [real: bb8, imaginary: bb4]; //pre_binding1
|
||||
// }
|
||||
// bb4: {
|
||||
// falseEdges -> [real: bb11, imaginary: bb5]; //pre_binding2
|
||||
// }
|
||||
// bb5: {
|
||||
// falseEdges -> [real: bb12, imaginary: bb6]; //pre_binding3
|
||||
// }
|
||||
// bb6: {
|
||||
// falseEdges -> [real: bb15, imaginary: bb7]; //pre_binding4
|
||||
// }
|
||||
// bb7: {
|
||||
// unreachable;
|
||||
// }
|
||||
// bb8: { // binding1: Some(w) if guard()
|
||||
// StorageLive(_3);
|
||||
// _3 = ((_2 as Some).0: i32);
|
||||
// StorageLive(_8);
|
||||
// _8 = const guard() -> bb9;
|
||||
// }
|
||||
// bb9: { //end of guard
|
||||
// switchInt(_8) -> [0u8: bb10, otherwise: bb1];
|
||||
// }
|
||||
// bb10: { // to pre_binding2
|
||||
// falseEdges -> [real: bb4, imaginary: bb4];
|
||||
// }
|
||||
// bb11: { // binding2 & arm2
|
||||
// StorageLive(_4);
|
||||
// _4 = _2;
|
||||
// _1 = const 2i32;
|
||||
// goto -> bb16;
|
||||
// }
|
||||
// bb12: { // binding3: Some(y) if guard2(y)
|
||||
// StorageLive(_5);
|
||||
// _5 = ((_2 as Some).0: i32);
|
||||
// StorageLive(_10);
|
||||
// StorageLive(_11);
|
||||
// _11 = _5;
|
||||
// _10 = const guard2(_11) -> bb13;
|
||||
// }
|
||||
// bb13: { // end of guard2
|
||||
// StorageDead(_11);
|
||||
// switchInt(_10) -> [0u8: bb13, otherwise: bb2]; // end of guard2
|
||||
// }
|
||||
// bb13: {
|
||||
// falseEdges -> [real: bb14, imaginary: bb6]; // after guard2 to binding4
|
||||
// }
|
||||
// bb14: {
|
||||
// falseEdges -> [real: bb6, imaginary: bb7]; // from befor binding4 to unreachable
|
||||
// }
|
||||
// bb15: {
|
||||
// switchInt(_10) -> [0u8: bb14, otherwise: bb2];
|
||||
// }
|
||||
// bb14: { // to pre_binding4
|
||||
// falseEdges -> [real: bb6, imaginary: bb6];
|
||||
// }
|
||||
// bb15: { // binding4 & arm4
|
||||
// StorageLive(_6);
|
||||
// _6 = _2;
|
||||
// _1 = const 4i32;
|
||||
// goto -> bb16;
|
||||
// }
|
||||
// bb16: {
|
||||
// ...
|
||||
// return;
|
||||
// }
|
||||
|
Loading…
Reference in New Issue
Block a user