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}