Skip to content

Commit 9cba260

Browse files
committed
Auto merge of #74839 - alarsyo:multiple_return_terminators, r=oli-obk
Implement multiple return terminator optimization Closes #72022
2 parents fc42fb8 + 46c0bd3 commit 9cba260

12 files changed

+149
-122
lines changed

compiler/rustc_mir/src/transform/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ pub mod inline;
3333
pub mod instcombine;
3434
pub mod instrument_coverage;
3535
pub mod match_branches;
36+
pub mod multiple_return_terminators;
3637
pub mod no_landing_pads;
3738
pub mod nrvo;
3839
pub mod promote_consts;
@@ -464,6 +465,7 @@ fn run_optimization_passes<'tcx>(
464465
&remove_unneeded_drops::RemoveUnneededDrops,
465466
&match_branches::MatchBranchSimplification,
466467
// inst combine is after MatchBranchSimplification to clean up Ne(_1, false)
468+
&multiple_return_terminators::MultipleReturnTerminators,
467469
&instcombine::InstCombine,
468470
&const_prop::ConstProp,
469471
&simplify_branches::SimplifyBranches::new("after-const-prop"),
@@ -478,6 +480,7 @@ fn run_optimization_passes<'tcx>(
478480
&simplify::SimplifyCfg::new("final"),
479481
&nrvo::RenameReturnPlace,
480482
&simplify::SimplifyLocals,
483+
&multiple_return_terminators::MultipleReturnTerminators,
481484
];
482485

483486
// Optimizations to run even if mir optimizations have been disabled.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//! This pass removes jumps to basic blocks containing only a return, and replaces them with a
2+
//! return instead.
3+
4+
use crate::transform::{simplify, MirPass, MirSource};
5+
use rustc_index::bit_set::BitSet;
6+
use rustc_middle::mir::*;
7+
use rustc_middle::ty::TyCtxt;
8+
9+
pub struct MultipleReturnTerminators;
10+
11+
impl<'tcx> MirPass<'tcx> for MultipleReturnTerminators {
12+
fn run_pass(&self, tcx: TyCtxt<'tcx>, _: MirSource<'tcx>, body: &mut Body<'tcx>) {
13+
if tcx.sess.opts.debugging_opts.mir_opt_level < 3 {
14+
return;
15+
}
16+
17+
// find basic blocks with no statement and a return terminator
18+
let mut bbs_simple_returns = BitSet::new_empty(body.basic_blocks().len());
19+
let bbs = body.basic_blocks_mut();
20+
for idx in bbs.indices() {
21+
if bbs[idx].statements.is_empty()
22+
&& bbs[idx].terminator().kind == TerminatorKind::Return
23+
{
24+
bbs_simple_returns.insert(idx);
25+
}
26+
}
27+
28+
for bb in bbs {
29+
if let TerminatorKind::Goto { target } = bb.terminator().kind {
30+
if bbs_simple_returns.contains(target) {
31+
bb.terminator_mut().kind = TerminatorKind::Return;
32+
}
33+
}
34+
}
35+
36+
simplify::remove_dead_blocks(body)
37+
}
38+
}

src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyBranches-after-copy-prop.after.diff

+18-24
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@
9191
+ StorageLive(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:11: 23:18
9292
+ _35 = Ne(_34, _11); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:11: 23:18
9393
+ StorageDead(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:11: 23:18
94-
+ switchInt(move _35) -> [false: bb8, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:11: 23:18
94+
+ switchInt(move _35) -> [false: bb7, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:11: 23:18
9595
}
9696

9797
bb1: {
@@ -107,10 +107,9 @@
107107
StorageDead(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:27:27: 27:28
108108
- StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:6: 28:7
109109
- StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:1: 29:2
110-
- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:27:14: 27:28
111110
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:6: 28:7
112111
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:1: 29:2
113-
+ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:27:14: 27:28
112+
return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:27:14: 27:28
114113
}
115114

116115
+ bb2: {
@@ -131,7 +130,7 @@
131130
+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50
132131
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50
133132
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50
134-
+ goto -> bb7; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6
133+
+ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6
135134
+ }
136135
+
137136
bb3: {
@@ -154,7 +153,7 @@
154153
+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:49: 24:50
155154
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:49: 24:50
156155
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:49: 24:50
157-
+ goto -> bb7; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6
156+
+ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6
158157
}
159158

160159
bb4: {
@@ -177,7 +176,7 @@
177176
+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56
178177
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56
179178
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56
180-
+ goto -> bb7; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6
179+
+ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6
181180
}
182181

183182
bb5: {
@@ -200,7 +199,7 @@
200199
+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:55: 26:56
201200
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:55: 26:56
202201
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:55: 26:56
203-
+ goto -> bb7; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6
202+
+ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6
204203
}
205204

206205
bb6: {
@@ -221,7 +220,11 @@
221220
- StorageDead(_14); // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50
222221
- StorageDead(_13); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50
223222
- StorageDead(_12); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50
224-
- goto -> bb11; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6
223+
- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6
224+
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:5: 28:7
225+
+ discriminant(_0) = 0; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:5: 28:7
226+
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:6: 28:7
227+
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:1: 29:2
225228
+ return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:2: 29:2
226229
}
227230

@@ -243,15 +246,10 @@
243246
- StorageDead(_19); // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:49: 24:50
244247
- StorageDead(_18); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:49: 24:50
245248
- StorageDead(_17); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:49: 24:50
246-
- goto -> bb11; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6
247-
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:5: 28:7
248-
+ discriminant(_0) = 0; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:5: 28:7
249-
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:6: 28:7
250-
+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:1: 29:2
251-
+ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:2: 29:2
252-
}
253-
254-
bb8: {
249+
- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6
250+
- }
251+
-
252+
- bb8: {
255253
- StorageLive(_22); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19
256254
- _22 = (((*(_4.0: &ViewportPercentageLength)) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19
257255
- StorageLive(_23); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33
@@ -269,7 +267,7 @@
269267
- StorageDead(_24); // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56
270268
- StorageDead(_23); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56
271269
- StorageDead(_22); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56
272-
- goto -> bb11; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6
270+
- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6
273271
- }
274272
-
275273
- bb9: {
@@ -290,19 +288,15 @@
290288
- StorageDead(_29); // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:55: 26:56
291289
- StorageDead(_28); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:55: 26:56
292290
- StorageDead(_27); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:55: 26:56
293-
- goto -> bb11; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6
291+
- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6
294292
- }
295293
-
296294
- bb10: {
297-
- return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:2: 29:2
298-
- }
299-
-
300-
- bb11: {
301295
- ((_0 as Ok).0: ViewportPercentageLength) = move _3; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:5: 28:7
302296
- discriminant(_0) = 0; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:5: 28:7
303297
- StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:6: 28:7
304298
- StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:1: 29:2
305-
- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:2: 29:2
299+
- return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:2: 29:2
306300
+ StorageDead(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:21: 23:30
307301
+ switchInt(_11) -> [0_isize: bb2, 1_isize: bb3, 2_isize: bb4, 3_isize: bb5, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:21: 23:30
308302
}

src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff

+12-19
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
+ StorageLive(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:11: 23:18
7474
+ _35 = Ne(_34, _11); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:11: 23:18
7575
+ StorageDead(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:11: 23:18
76-
+ switchInt(move _35) -> [false: bb8, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:11: 23:18
76+
+ switchInt(move _35) -> [false: bb7, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:11: 23:18
7777
}
7878

7979
bb1: {
@@ -89,8 +89,7 @@
8989
StorageDead(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:27:27: 27:28
9090
StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:6: 28:7
9191
StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:1: 29:2
92-
- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:27:14: 27:28
93-
+ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:27:14: 27:28
92+
return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:27:14: 27:28
9493
}
9594

9695
- bb3: {
@@ -127,8 +126,8 @@
127126
StorageDead(_14); // scope 1 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50
128127
StorageDead(_13); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50
129128
StorageDead(_12); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50
130-
- goto -> bb11; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6
131-
+ goto -> bb7; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6
129+
- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6
130+
+ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6
132131
}
133132

134133
- bb7: {
@@ -150,8 +149,8 @@
150149
StorageDead(_19); // scope 2 at $DIR/early_otherwise_branch_68867.rs:24:49: 24:50
151150
StorageDead(_18); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:49: 24:50
152151
StorageDead(_17); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:49: 24:50
153-
- goto -> bb11; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6
154-
+ goto -> bb7; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6
152+
- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6
153+
+ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6
155154
}
156155

157156
- bb8: {
@@ -173,8 +172,8 @@
173172
StorageDead(_24); // scope 3 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56
174173
StorageDead(_23); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56
175174
StorageDead(_22); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56
176-
- goto -> bb11; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6
177-
+ goto -> bb7; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6
175+
- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6
176+
+ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6
178177
}
179178

180179
- bb9: {
@@ -196,26 +195,20 @@
196195
StorageDead(_29); // scope 4 at $DIR/early_otherwise_branch_68867.rs:26:55: 26:56
197196
StorageDead(_28); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:55: 26:56
198197
StorageDead(_27); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:55: 26:56
199-
- goto -> bb11; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6
200-
+ goto -> bb7; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6
198+
- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6
199+
+ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:8: 28:6
201200
}
202201

203202
- bb10: {
204203
+ bb6: {
205-
return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:2: 29:2
206-
}
207-
208-
- bb11: {
209-
+ bb7: {
210204
((_0 as Ok).0: ViewportPercentageLength) = move _3; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:5: 28:7
211205
discriminant(_0) = 0; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:5: 28:7
212206
StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:6: 28:7
213207
StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:1: 29:2
214-
- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:2: 29:2
215-
+ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:2: 29:2
208+
return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:29:2: 29:2
216209
+ }
217210
+
218-
+ bb8: {
211+
+ bb7: {
219212
+ StorageDead(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:21: 23:30
220213
+ switchInt(_11) -> [0_isize: bb2, 1_isize: bb3, 2_isize: bb4, 3_isize: bb5, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:21: 23:30
221214
}

0 commit comments

Comments
 (0)