Skip to content

Commit 7fb479c

Browse files
committed
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; } ```
2 parents 63f8e6e + 83298a2 commit 7fb479c

File tree

2 files changed

+80
-1
lines changed

2 files changed

+80
-1
lines changed

src/librustc_mir/transform/simplify.rs

+26-1
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,14 @@ impl<'a, 'tcx: 'a> CfgSimplifier<'a, 'tcx> {
108108
pub fn simplify(mut self) {
109109
self.strip_nops();
110110

111+
let mut start = START_BLOCK;
112+
111113
loop {
112114
let mut changed = false;
113115

114-
for bb in (0..self.basic_blocks.len()).map(BasicBlock::new) {
116+
self.collapse_goto_chain(&mut start, &mut changed);
117+
118+
for bb in self.basic_blocks.indices() {
115119
if self.pred_count[bb] == 0 {
116120
continue
117121
}
@@ -142,6 +146,27 @@ impl<'a, 'tcx: 'a> CfgSimplifier<'a, 'tcx> {
142146

143147
if !changed { break }
144148
}
149+
150+
if start != START_BLOCK {
151+
debug_assert!(self.pred_count[START_BLOCK] == 0);
152+
self.basic_blocks.swap(START_BLOCK, start);
153+
self.pred_count.swap(START_BLOCK, start);
154+
155+
// pred_count == 1 if the start block has no predecessor _blocks_.
156+
if self.pred_count[START_BLOCK] > 1 {
157+
for (bb, data) in self.basic_blocks.iter_enumerated_mut() {
158+
if self.pred_count[bb] == 0 {
159+
continue;
160+
}
161+
162+
for target in data.terminator_mut().successors_mut() {
163+
if *target == start {
164+
*target = START_BLOCK;
165+
}
166+
}
167+
}
168+
}
169+
}
145170
}
146171

147172
// Collapse a goto chain starting from `start`

src/test/mir-opt/simplify_cfg.rs

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Test that the goto chain starting from bb0 is collapsed.
2+
3+
fn main() {
4+
loop {
5+
if bar() {
6+
break;
7+
}
8+
}
9+
}
10+
11+
#[inline(never)]
12+
fn bar() -> bool {
13+
true
14+
}
15+
16+
// END RUST SOURCE
17+
// START rustc.main.SimplifyCfg-initial.before.mir
18+
// bb0: {
19+
// goto -> bb1;
20+
// }
21+
// bb1: {
22+
// falseUnwind -> [real: bb3, cleanup: bb4];
23+
// }
24+
// ...
25+
// bb11: {
26+
// ...
27+
// goto -> bb1;
28+
// }
29+
// END rustc.main.SimplifyCfg-initial.before.mir
30+
// START rustc.main.SimplifyCfg-initial.after.mir
31+
// bb0: {
32+
// falseUnwind -> [real: bb1, cleanup: bb2];
33+
// }
34+
// ...
35+
// bb5: {
36+
// ...
37+
// goto -> bb0;
38+
// }
39+
// END rustc.main.SimplifyCfg-initial.after.mir
40+
// START rustc.main.SimplifyCfg-early-opt.before.mir
41+
// bb0: {
42+
// goto -> bb1;
43+
// }
44+
// bb1: {
45+
// StorageLive(_2);
46+
// _2 = const bar() -> bb3;
47+
// }
48+
// END rustc.main.SimplifyCfg-early-opt.before.mir
49+
// START rustc.main.SimplifyCfg-early-opt.after.mir
50+
// bb0: {
51+
// StorageLive(_2);
52+
// _2 = const bar() -> bb1;
53+
// }
54+
// END rustc.main.SimplifyCfg-early-opt.after.mir

0 commit comments

Comments
 (0)