1 //! This pass removes jumps to basic blocks containing only a return, and replaces them with a
4 use crate::{simplify, MirPass};
5 use rustc_index::bit_set::BitSet;
6 use rustc_middle::mir::*;
7 use rustc_middle::ty::TyCtxt;
9 pub struct MultipleReturnTerminators;
11 impl<'tcx> MirPass<'tcx> for MultipleReturnTerminators {
12 fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
13 sess.mir_opt_level() >= 4
16 fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
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 def_id = body.source.def_id();
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
25 bbs_simple_returns.insert(idx);
30 if !tcx.consider_optimizing(|| format!("MultipleReturnTerminators {:?} ", def_id)) {
34 if let TerminatorKind::Goto { target } = bb.terminator().kind {
35 if bbs_simple_returns.contains(target) {
36 bb.terminator_mut().kind = TerminatorKind::Return;
41 simplify::remove_dead_blocks(tcx, body)