diff options
| author | bors <bors@rust-lang.org> | 2018-12-17 06:34:04 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-12-17 06:34:04 +0000 |
| commit | 7fb479c92b6358590a0180b00a416bb055b6548e (patch) | |
| tree | 272694c076471065f563284bd135159440eb1377 /src | |
| parent | 63f8e6e12b3f9655fb58282e7a75f411b7e8b4ee (diff) | |
| parent | 83298a212076e74808198f46bb98467d2cb41ac9 (diff) | |
| download | rust-7fb479c92b6358590a0180b00a416bb055b6548e.tar.gz rust-7fb479c92b6358590a0180b00a416bb055b6548e.zip | |
Auto merge of #56764 - sinkuu:simpcfg_bb0, r=matthewjasper
mir-opt: Make SimplifyCfg collapse goto chains starting from bb0
`SimplifyCfg` pass was not able to collapse goto chains starting from bb0, leaving MIR like this:
```
bb0: {
goto -> bb1;
}
```
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_mir/transform/simplify.rs | 27 | ||||
| -rw-r--r-- | src/test/mir-opt/simplify_cfg.rs | 54 |
2 files changed, 80 insertions, 1 deletions
diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs index f643870dec2..592f721b2f5 100644 --- a/src/librustc_mir/transform/simplify.rs +++ b/src/librustc_mir/transform/simplify.rs @@ -108,10 +108,14 @@ impl<'a, 'tcx: 'a> CfgSimplifier<'a, 'tcx> { pub fn simplify(mut self) { self.strip_nops(); + let mut start = START_BLOCK; + loop { let mut changed = false; - for bb in (0..self.basic_blocks.len()).map(BasicBlock::new) { + self.collapse_goto_chain(&mut start, &mut changed); + + for bb in self.basic_blocks.indices() { if self.pred_count[bb] == 0 { continue } @@ -142,6 +146,27 @@ impl<'a, 'tcx: 'a> CfgSimplifier<'a, 'tcx> { if !changed { break } } + + if start != START_BLOCK { + debug_assert!(self.pred_count[START_BLOCK] == 0); + self.basic_blocks.swap(START_BLOCK, start); + self.pred_count.swap(START_BLOCK, start); + + // pred_count == 1 if the start block has no predecessor _blocks_. + if self.pred_count[START_BLOCK] > 1 { + for (bb, data) in self.basic_blocks.iter_enumerated_mut() { + if self.pred_count[bb] == 0 { + continue; + } + + for target in data.terminator_mut().successors_mut() { + if *target == start { + *target = START_BLOCK; + } + } + } + } + } } // Collapse a goto chain starting from `start` diff --git a/src/test/mir-opt/simplify_cfg.rs b/src/test/mir-opt/simplify_cfg.rs new file mode 100644 index 00000000000..ef843f71581 --- /dev/null +++ b/src/test/mir-opt/simplify_cfg.rs @@ -0,0 +1,54 @@ +// Test that the goto chain starting from bb0 is collapsed. + +fn main() { + loop { + if bar() { + break; + } + } +} + +#[inline(never)] +fn bar() -> bool { + true +} + +// END RUST SOURCE +// START rustc.main.SimplifyCfg-initial.before.mir +// bb0: { +// goto -> bb1; +// } +// bb1: { +// falseUnwind -> [real: bb3, cleanup: bb4]; +// } +// ... +// bb11: { +// ... +// goto -> bb1; +// } +// END rustc.main.SimplifyCfg-initial.before.mir +// START rustc.main.SimplifyCfg-initial.after.mir +// bb0: { +// falseUnwind -> [real: bb1, cleanup: bb2]; +// } +// ... +// bb5: { +// ... +// goto -> bb0; +// } +// END rustc.main.SimplifyCfg-initial.after.mir +// START rustc.main.SimplifyCfg-early-opt.before.mir +// bb0: { +// goto -> bb1; +// } +// bb1: { +// StorageLive(_2); +// _2 = const bar() -> bb3; +// } +// END rustc.main.SimplifyCfg-early-opt.before.mir +// START rustc.main.SimplifyCfg-early-opt.after.mir +// bb0: { +// StorageLive(_2); +// _2 = const bar() -> bb1; +// } +// END rustc.main.SimplifyCfg-early-opt.after.mir |
