diff --git a/src/librustc_mir/transform/simplify_cfg.rs b/src/librustc_mir/transform/simplify_cfg.rs index 8e1b7b44976..ca8556496fa 100644 --- a/src/librustc_mir/transform/simplify_cfg.rs +++ b/src/librustc_mir/transform/simplify_cfg.rs @@ -50,6 +50,7 @@ impl<'a> SimplifyCfg<'a> { impl<'l, 'tcx> MirPass<'tcx> for SimplifyCfg<'l> { fn run_pass<'a>(&mut self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, _src: MirSource, mir: &mut Mir<'tcx>) { + debug!("SimplifyCfg({:?}) - simplifying {:?}", self.label, mir); CfgSimplifier::new(mir).simplify(); remove_dead_blocks(mir); @@ -78,6 +79,8 @@ impl<'a, 'tcx: 'a> CfgSimplifier<'a, 'tcx> { // we can't use mir.predecessors() here because that counts // dead blocks, which we don't want to. + pred_count[START_BLOCK] = 1; + for (_, data) in traversal::preorder(mir) { if let Some(ref term) = data.terminator { for &tgt in term.successors().iter() { @@ -157,8 +160,16 @@ impl<'a, 'tcx: 'a> CfgSimplifier<'a, 'tcx> { debug!("collapsing goto chain from {:?} to {:?}", *start, target); *changed |= *start != target; - self.pred_count[target] += 1; - self.pred_count[*start] -= 1; + + if self.pred_count[*start] == 1 { + // This is the last reference to *start, so the pred-count to + // to target is moved into the current block. + self.pred_count[*start] = 0; + } else { + self.pred_count[target] += 1; + self.pred_count[*start] -= 1; + } + *start = target; } diff --git a/src/test/mir-opt/deaggregator_test.rs b/src/test/mir-opt/deaggregator_test.rs index 3304a66773a..f136d74fa51 100644 --- a/src/test/mir-opt/deaggregator_test.rs +++ b/src/test/mir-opt/deaggregator_test.rs @@ -26,7 +26,7 @@ fn main() {} // _2 = _1; // _3 = _2; // _0 = Baz { x: _3, y: const F32(0), z: const false }; -// goto -> bb1; +// return; // } // END rustc.node13.Deaggregator.before.mir // START rustc.node13.Deaggregator.after.mir @@ -36,6 +36,6 @@ fn main() {} // (_0.0: usize) = _3; // (_0.1: f32) = const F32(0); // (_0.2: bool) = const false; -// goto -> bb1; +// return; // } // END rustc.node13.Deaggregator.after.mir diff --git a/src/test/mir-opt/deaggregator_test_enum.rs b/src/test/mir-opt/deaggregator_test_enum.rs index a6f12886f55..25fa0e90835 100644 --- a/src/test/mir-opt/deaggregator_test_enum.rs +++ b/src/test/mir-opt/deaggregator_test_enum.rs @@ -31,7 +31,7 @@ fn main() { // _2 = _1; // _3 = _2; // _0 = Baz::Foo { x: _3 }; -// goto -> bb1; +// return; // } // END rustc.node10.Deaggregator.before.mir // START rustc.node10.Deaggregator.after.mir @@ -40,6 +40,6 @@ fn main() { // _3 = _2; // ((_0 as Foo).0: usize) = _3; // discriminant(_0) = 1; -// goto -> bb1; +// return; // } // END rustc.node10.Deaggregator.after.mir diff --git a/src/test/mir-opt/storage_ranges.rs b/src/test/mir-opt/storage_ranges.rs index 3885b233fd2..933bfa8df2e 100644 --- a/src/test/mir-opt/storage_ranges.rs +++ b/src/test/mir-opt/storage_ranges.rs @@ -38,10 +38,6 @@ fn main() { // _0 = (); // StorageDead(_6); // StorageDead(_1); -// goto -> bb1; -// } -// -// bb1: { // return; // } // END rustc.node4.TypeckMir.before.mir