1
1
//! This pass replaces a drop of a type that does not need dropping, with a goto
2
2
3
3
use crate :: transform:: MirPass ;
4
- use rustc_middle:: mir:: visit:: Visitor ;
5
4
use rustc_middle:: mir:: * ;
6
- use rustc_middle:: ty:: { ParamEnv , TyCtxt } ;
5
+ use rustc_middle:: ty:: TyCtxt ;
7
6
8
7
use super :: simplify:: simplify_cfg;
9
8
@@ -12,24 +11,26 @@ pub struct RemoveUnneededDrops;
12
11
impl < ' tcx > MirPass < ' tcx > for RemoveUnneededDrops {
13
12
fn run_pass ( & self , tcx : TyCtxt < ' tcx > , body : & mut Body < ' tcx > ) {
14
13
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
14
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
+ }
33
34
}
34
35
35
36
// if we applied optimizations, we potentially have some cfg to cleanup to
@@ -39,25 +40,3 @@ impl<'tcx> MirPass<'tcx> for RemoveUnneededDrops {
39
40
}
40
41
}
41
42
}
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