]> git.proxmox.com Git - rustc.git/blob - compiler/rustc_mir/src/transform/remove_unneeded_drops.rs
New upstream version 1.50.0+dfsg1
[rustc.git] / compiler / rustc_mir / src / transform / remove_unneeded_drops.rs
1 //! This pass replaces a drop of a type that does not need dropping, with a goto
2
3 use crate::transform::MirPass;
4 use rustc_middle::mir::visit::Visitor;
5 use rustc_middle::mir::*;
6 use rustc_middle::ty::{ParamEnv, TyCtxt};
7
8 use super::simplify::simplify_cfg;
9
10 pub struct RemoveUnneededDrops;
11
12 impl<'tcx> MirPass<'tcx> for RemoveUnneededDrops {
13 fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
14 trace!("Running RemoveUnneededDrops on {:?}", body.source);
15 let mut opt_finder = RemoveUnneededDropsOptimizationFinder {
16 tcx,
17 body,
18 param_env: tcx.param_env(body.source.def_id()),
19 optimizations: vec![],
20 };
21 opt_finder.visit_body(body);
22 let should_simplify = !opt_finder.optimizations.is_empty();
23 for (loc, target) in opt_finder.optimizations {
24 if !tcx
25 .consider_optimizing(|| format!("RemoveUnneededDrops {:?} ", body.source.def_id()))
26 {
27 break;
28 }
29
30 let terminator = body.basic_blocks_mut()[loc.block].terminator_mut();
31 debug!("SUCCESS: replacing `drop` with goto({:?})", target);
32 terminator.kind = TerminatorKind::Goto { target };
33 }
34
35 // if we applied optimizations, we potentially have some cfg to cleanup to
36 // make it easier for further passes
37 if should_simplify {
38 simplify_cfg(body);
39 }
40 }
41 }
42
43 impl<'a, 'tcx> Visitor<'tcx> for RemoveUnneededDropsOptimizationFinder<'a, 'tcx> {
44 fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) {
45 match terminator.kind {
46 TerminatorKind::Drop { place, target, .. } => {
47 let ty = place.ty(self.body, self.tcx);
48 let needs_drop = ty.ty.needs_drop(self.tcx, self.param_env);
49 if !needs_drop {
50 self.optimizations.push((location, target));
51 }
52 }
53 _ => {}
54 }
55 self.super_terminator(terminator, location);
56 }
57 }
58 pub struct RemoveUnneededDropsOptimizationFinder<'a, 'tcx> {
59 tcx: TyCtxt<'tcx>,
60 body: &'a Body<'tcx>,
61 optimizations: Vec<(Location, BasicBlock)>,
62 param_env: ParamEnv<'tcx>,
63 }