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, bb) in bbs.iter_enumerated() {
22            if bb.statements.is_empty() && bb.terminator().kind == TerminatorKind::Return {
23                bbs_simple_returns.insert(idx);
24            }
25        }
26
27        for bb in bbs {
28            if let TerminatorKind::Goto { target } = bb.terminator().kind
29                && bbs_simple_returns.contains(target)
30            {
31                bb.terminator_mut().kind = TerminatorKind::Return;
32            }
33        }
34
35        simplify::remove_dead_blocks(body)
36    }
37
38    fn is_required(&self) -> bool {
39        false
40    }
41}