]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_mir_transform/src/multiple_return_terminators.rs
Rollup merge of #101118 - devnexen:fs_getmode_bsd, r=Mark-Simulacrum
[rust.git] / compiler / rustc_mir_transform / src / 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
4 use crate::{simplify, MirPass};
5 use rustc_index::bit_set::BitSet;
6 use rustc_middle::mir::*;
7 use rustc_middle::ty::TyCtxt;
8
9 pub struct MultipleReturnTerminators;
10
11 impl<'tcx> MirPass<'tcx> for MultipleReturnTerminators {
12     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
13         sess.mir_opt_level() >= 4
14     }
15
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
24             {
25                 bbs_simple_returns.insert(idx);
26             }
27         }
28
29         for bb in bbs {
30             if !tcx.consider_optimizing(|| format!("MultipleReturnTerminators {:?} ", def_id)) {
31                 break;
32             }
33
34             if let TerminatorKind::Goto { target } = bb.terminator().kind {
35                 if bbs_simple_returns.contains(target) {
36                     bb.terminator_mut().kind = TerminatorKind::Return;
37                 }
38             }
39         }
40
41         simplify::remove_dead_blocks(tcx, body)
42     }
43 }