11//! This pass replaces a drop of a type that does not need dropping, with a goto
22
33use crate :: transform:: MirPass ;
4- use rustc_middle:: mir:: visit:: Visitor ;
54use rustc_middle:: mir:: * ;
6- use rustc_middle:: ty:: { ParamEnv , TyCtxt } ;
5+ use rustc_middle:: ty:: TyCtxt ;
76
87use super :: simplify:: simplify_cfg;
98
@@ -12,24 +11,26 @@ pub struct RemoveUnneededDrops;
1211impl < ' tcx > MirPass < ' tcx > for RemoveUnneededDrops {
1312 fn run_pass ( & self , tcx : TyCtxt < ' tcx > , body : & mut Body < ' tcx > ) {
1413 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- }
2914
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 } ;
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+ }
3334 }
3435
3536 // if we applied optimizations, we potentially have some cfg to cleanup to
@@ -39,25 +40,3 @@ impl<'tcx> MirPass<'tcx> for RemoveUnneededDrops {
3940 }
4041 }
4142}
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- }
0 commit comments