rustc_mir_transform/multiple_return_terminators.rs
1//! This pass removes jumps to basic blocks containing only a return, and replaces them with a
2//! return instead.
3
4use rustc_index::bit_set::DenseBitSet;
5use rustc_middle::mir::*;
6use rustc_middle::ty::TyCtxt;
7
8use crate::simplify;
9
10pub(super) struct MultipleReturnTerminators;
11
12impl<'tcx> crate::MirPass<'tcx> for MultipleReturnTerminators {
13 fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
14 sess.mir_opt_level() >= 4
15 }
16
17 fn run_pass(&self, _: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
18 // find basic blocks with no statement and a return terminator
19 let mut bbs_simple_returns = DenseBitSet::new_empty(body.basic_blocks.len());
20 let bbs = body.basic_blocks_mut();
21 for idx in bbs.indices() {
22 if bbs[idx].statements.is_empty()
23 && bbs[idx].terminator().kind == TerminatorKind::Return
24 {
25 bbs_simple_returns.insert(idx);
26 }
27 }
28
29 for bb in bbs {
30 if let TerminatorKind::Goto { target } = bb.terminator().kind {
31 if bbs_simple_returns.contains(target) {
32 bb.terminator_mut().kind = TerminatorKind::Return;
33 }
34 }
35 }
36
37 simplify::remove_dead_blocks(body)
38 }
39
40 fn is_required(&self) -> bool {
41 false
42 }
43}