]>
Commit | Line | Data |
---|---|---|
1b1a35ee XL |
1 | //! This pass removes jumps to basic blocks containing only a return, and replaces them with a |
2 | //! return instead. | |
3 | ||
29967ef6 | 4 | use crate::transform::{simplify, MirPass}; |
1b1a35ee XL |
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 { | |
29967ef6 | 12 | fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { |
1b1a35ee XL |
13 | if tcx.sess.opts.debugging_opts.mir_opt_level < 3 { |
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 bbs = body.basic_blocks_mut(); | |
20 | for idx in bbs.indices() { | |
21 | if bbs[idx].statements.is_empty() | |
22 | && bbs[idx].terminator().kind == TerminatorKind::Return | |
23 | { | |
24 | bbs_simple_returns.insert(idx); | |
25 | } | |
26 | } | |
27 | ||
28 | for bb in bbs { | |
29 | if let TerminatorKind::Goto { target } = bb.terminator().kind { | |
30 | if bbs_simple_returns.contains(target) { | |
31 | bb.terminator_mut().kind = TerminatorKind::Return; | |
32 | } | |
33 | } | |
34 | } | |
35 | ||
36 | simplify::remove_dead_blocks(body) | |
37 | } | |
38 | } |