]> git.proxmox.com Git - rustc.git/blob - compiler/rustc_mir/src/transform/multiple_return_terminators.rs
New upstream version 1.52.0~beta.3+dfsg1
[rustc.git] / compiler / rustc_mir / src / 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
4 use crate::transform::{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 run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
13 if tcx.sess.mir_opt_level() < 4 {
14 return;
15 }
16
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(body)
42 }
43 }