Skip to content

Commit 00335ab

Browse files
committed
Convert to a single return terminator in codegen
I also noticed that MultipleReturnTerminators doesn't seem to preserve the SourceInfo quite as well as it could, the tweak to it here might improve debuginfo.
1 parent c4e8ab9 commit 00335ab

File tree

8 files changed

+29
-76
lines changed

8 files changed

+29
-76
lines changed

compiler/rustc_codegen_ssa/src/mir/block.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
361361
}
362362
}
363363

364-
fn codegen_return_terminator(&mut self, bx: &mut Bx) {
364+
pub fn codegen_return_terminator(&mut self, bx: &mut Bx) {
365365
// Call `va_end` if this is the definition of a C-variadic function.
366366
if self.fn_abi.c_variadic {
367367
// The `VaList` "spoofed" argument is just after all the real arguments.
@@ -1296,7 +1296,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
12961296
}
12971297

12981298
mir::TerminatorKind::Return => {
1299-
self.codegen_return_terminator(bx);
1299+
if let Some(return_block) = self.return_block {
1300+
bx.br(return_block);
1301+
} else {
1302+
self.codegen_return_terminator(bx);
1303+
}
13001304
MergingSucc::False
13011305
}
13021306

compiler/rustc_codegen_ssa/src/mir/mod.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
7272
/// Cached unreachable block
7373
unreachable_block: Option<Bx::BasicBlock>,
7474

75+
/// Cached return block
76+
return_block: Option<Bx::BasicBlock>,
77+
7578
/// Cached double unwind guarding block
7679
double_unwind_guard: Option<Bx::BasicBlock>,
7780

@@ -184,6 +187,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
184187
personality_slot: None,
185188
cached_llbbs,
186189
unreachable_block: None,
190+
return_block: None,
187191
double_unwind_guard: None,
188192
cleanup_kinds,
189193
landing_pads: IndexVec::from_elem(None, &mir.basic_blocks),
@@ -256,6 +260,19 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
256260
// Apply debuginfo to the newly allocated locals.
257261
fx.debug_introduce_locals(&mut start_bx);
258262

263+
if mir
264+
.basic_blocks
265+
.iter()
266+
.filter(|block| matches!(block.terminator().kind, mir::TerminatorKind::Return))
267+
.count()
268+
> 1
269+
{
270+
let llbb = Bx::append_block(fx.cx, fx.llfn, "return");
271+
let mut bx = Bx::build(fx.cx, llbb);
272+
fx.codegen_return_terminator(&mut bx);
273+
fx.return_block = Some(llbb);
274+
}
275+
259276
// Codegen the body of each block using reverse postorder
260277
for (bb, _) in traversal::reverse_postorder(&mir) {
261278
fx.codegen_block(bb);

compiler/rustc_mir_transform/src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ mod required_consts;
8686
mod reveal_all;
8787
mod separate_const_switch;
8888
mod shim;
89-
mod single_return_terminator;
9089
// This pass is public to allow external drivers to perform MIR cleanup
9190
pub mod simplify;
9291
mod simplify_branches;
@@ -578,7 +577,6 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
578577
&o1(simplify::SimplifyCfg::new("final")),
579578
&nrvo::RenameReturnPlace,
580579
&simplify::SimplifyLocals::new("final"),
581-
&single_return_terminator::SingleReturnTerminator,
582580
&deduplicate_blocks::DeduplicateBlocks,
583581
// Some cleanup necessary at least for LLVM and potentially other codegen backends.
584582
&add_call_guards::CriticalCallEdges,

compiler/rustc_mir_transform/src/single_return_terminator.rs

Lines changed: 0 additions & 58 deletions
This file was deleted.

tests/mir-opt/inline/inline_generator.main.Inline.diff

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@
111111
+ discriminant(_1) = 0; // scope 6 at $DIR/inline_generator.rs:15:11: 15:39
112112
+ _11 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline_generator.rs:15:11: 15:39
113113
+ discriminant((*_11)) = 3; // scope 6 at $DIR/inline_generator.rs:15:11: 15:39
114-
+ goto -> bb1; // scope 6 at $DIR/inline_generator.rs:15:11: 15:39
114+
+ goto -> bb1; // scope 0 at $DIR/inline_generator.rs:15:11: 15:39
115115
+ }
116116
+
117117
+ bb7: {
@@ -122,7 +122,7 @@
122122
+ discriminant(_1) = 1; // scope 6 at $DIR/inline_generator.rs:15:41: 15:41
123123
+ _12 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline_generator.rs:15:41: 15:41
124124
+ discriminant((*_12)) = 1; // scope 6 at $DIR/inline_generator.rs:15:41: 15:41
125-
+ goto -> bb1; // scope 6 at $DIR/inline_generator.rs:15:41: 15:41
125+
+ goto -> bb1; // scope 0 at $DIR/inline_generator.rs:15:41: 15:41
126126
+ }
127127
+
128128
+ bb8: {

tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@
125125
discriminant(_3) = 1; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
126126
StorageDead(_14); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL
127127
StorageDead(_13); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
128-
- goto -> bb1; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
128+
- goto -> bb1; // scope 0 at $SRC_DIR/core/src/result.rs:LL:COL
129129
+ StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
130130
+ _5 = discriminant(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
131131
+ switchInt(move _5) -> [0: bb1, 1: bb3, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
@@ -147,7 +147,7 @@
147147
discriminant(_3) = 0; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
148148
StorageDead(_12); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL
149149
StorageDead(_11); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
150-
- goto -> bb1; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL
150+
- goto -> bb1; // scope 0 at $SRC_DIR/core/src/result.rs:LL:COL
151151
+ StorageDead(_4); // scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
152152
+ _5 = discriminant(_3); // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
153153
+ switchInt(move _5) -> [0: bb1, 1: bb3, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10

tests/mir-opt/try_identity_e2e.new.PreCodegen.after.mir

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ fn new(_1: Result<T, E>) -> Result<T, E> {
5353
((_0 as Err).0: E) = move _8; // scope 4 at $DIR/try_identity_e2e.rs:+9:45: +9:51
5454
discriminant(_0) = 1; // scope 4 at $DIR/try_identity_e2e.rs:+9:45: +9:51
5555
StorageDead(_2); // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2
56-
goto -> bb6; // scope 0 at $DIR/try_identity_e2e.rs:+12:2: +12:2
56+
return; // scope 0 at $DIR/try_identity_e2e.rs:+12:2: +12:2
5757
}
5858

5959
bb4: {
@@ -66,10 +66,6 @@ fn new(_1: Result<T, E>) -> Result<T, E> {
6666
((_0 as Ok).0: T) = move _7; // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +11:6
6767
discriminant(_0) = 0; // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +11:6
6868
StorageDead(_2); // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2
69-
goto -> bb6; // scope 0 at $DIR/try_identity_e2e.rs:+12:2: +12:2
70-
}
71-
72-
bb6: {
7369
return; // scope 0 at $DIR/try_identity_e2e.rs:+12:2: +12:2
7470
}
7571
}

tests/mir-opt/try_identity_e2e.old.PreCodegen.after.mir

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ fn old(_1: Result<T, E>) -> Result<T, E> {
2323
Deinit(_0); // scope 2 at $DIR/try_identity_e2e.rs:+4:30: +4:36
2424
((_0 as Err).0: E) = move _4; // scope 2 at $DIR/try_identity_e2e.rs:+4:30: +4:36
2525
discriminant(_0) = 1; // scope 2 at $DIR/try_identity_e2e.rs:+4:30: +4:36
26-
goto -> bb4; // scope 0 at $DIR/try_identity_e2e.rs:+7:2: +7:2
26+
return; // scope 0 at $DIR/try_identity_e2e.rs:+7:2: +7:2
2727
}
2828

2929
bb2: {
@@ -35,10 +35,6 @@ fn old(_1: Result<T, E>) -> Result<T, E> {
3535
Deinit(_0); // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +6:6
3636
((_0 as Ok).0: T) = move _3; // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +6:6
3737
discriminant(_0) = 0; // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +6:6
38-
goto -> bb4; // scope 0 at $DIR/try_identity_e2e.rs:+7:2: +7:2
39-
}
40-
41-
bb4: {
4238
return; // scope 0 at $DIR/try_identity_e2e.rs:+7:2: +7:2
4339
}
4440
}

0 commit comments

Comments
 (0)