]>
Commit | Line | Data |
---|---|---|
1b1a35ee XL |
1 | //! This pass replaces a drop of a type that does not need dropping, with a goto |
2 | ||
c295e0f8 | 3 | use crate::MirPass; |
1b1a35ee | 4 | use rustc_middle::mir::*; |
5869c6ff | 5 | use rustc_middle::ty::TyCtxt; |
1b1a35ee XL |
6 | |
7 | use super::simplify::simplify_cfg; | |
8 | ||
9 | pub struct RemoveUnneededDrops; | |
10 | ||
11 | impl<'tcx> MirPass<'tcx> for RemoveUnneededDrops { | |
29967ef6 XL |
12 | fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { |
13 | trace!("Running RemoveUnneededDrops on {:?}", body.source); | |
fc512014 | 14 | |
5869c6ff XL |
15 | let did = body.source.def_id(); |
16 | let param_env = tcx.param_env(did); | |
17 | let mut should_simplify = false; | |
18 | ||
19 | let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut(); | |
20 | for block in basic_blocks { | |
21 | let terminator = block.terminator_mut(); | |
22 | if let TerminatorKind::Drop { place, target, .. } = terminator.kind { | |
23 | let ty = place.ty(local_decls, tcx); | |
24 | if ty.ty.needs_drop(tcx, param_env) { | |
25 | continue; | |
26 | } | |
27 | if !tcx.consider_optimizing(|| format!("RemoveUnneededDrops {:?} ", did)) { | |
28 | continue; | |
29 | } | |
30 | debug!("SUCCESS: replacing `drop` with goto({:?})", target); | |
31 | terminator.kind = TerminatorKind::Goto { target }; | |
32 | should_simplify = true; | |
33 | } | |
1b1a35ee XL |
34 | } |
35 | ||
36 | // if we applied optimizations, we potentially have some cfg to cleanup to | |
37 | // make it easier for further passes | |
38 | if should_simplify { | |
17df50a5 | 39 | simplify_cfg(tcx, body); |
1b1a35ee XL |
40 | } |
41 | } | |
42 | } |