@@ -5,7 +5,8 @@ use rustc_middle::mir::*;
5
5
use rustc_middle:: ty:: TyCtxt ;
6
6
use tracing:: { debug, instrument} ;
7
7
8
- use crate :: ssa:: SsaLocals ;
8
+ use crate :: pass_manager as pm;
9
+ use crate :: ssa:: { SsaAnalysis , SsaLocals } ;
9
10
10
11
/// Unify locals that copy each other.
11
12
///
@@ -17,19 +18,39 @@ use crate::ssa::SsaLocals;
17
18
/// where each of the locals is only assigned once.
18
19
///
19
20
/// We want to replace all those locals by `_a`, either copied or moved.
20
- pub ( super ) struct CopyProp ;
21
+ pub ( super ) enum CopyProp {
22
+ Partial ,
23
+ Full ,
24
+ }
21
25
22
26
impl < ' tcx > crate :: MirPass < ' tcx > for CopyProp {
23
- fn is_enabled ( & self , sess : & rustc_session:: Session ) -> bool {
24
- sess. mir_opt_level ( ) >= 1
27
+ fn name ( & self ) -> & ' static str {
28
+ match self {
29
+ CopyProp :: Partial => "CopyProp-partial" ,
30
+ CopyProp :: Full => "CopyProp" ,
31
+ }
32
+ }
33
+
34
+ fn is_enabled ( & self , tcx : TyCtxt < ' tcx > ) -> bool {
35
+ match self {
36
+ CopyProp :: Partial => {
37
+ tcx. sess . mir_opt_level ( ) == 1
38
+ && !pm:: should_run_pass ( tcx, & CopyProp :: Full , pm:: Optimizations :: Allowed )
39
+ }
40
+ CopyProp :: Full => tcx. sess . mir_opt_level ( ) >= 2 ,
41
+ }
25
42
}
26
43
27
44
#[ instrument( level = "trace" , skip( self , tcx, body) ) ]
28
45
fn run_pass ( & self , tcx : TyCtxt < ' tcx > , body : & mut Body < ' tcx > ) {
29
46
debug ! ( def_id = ?body. source. def_id( ) ) ;
30
47
31
48
let typing_env = body. typing_env ( tcx) ;
32
- let ssa = SsaLocals :: new ( tcx, body, typing_env) ;
49
+ let ssa_analysis = match self {
50
+ CopyProp :: Partial => SsaAnalysis :: Partial ,
51
+ CopyProp :: Full => SsaAnalysis :: Full ,
52
+ } ;
53
+ let ssa = SsaLocals :: new ( tcx, body, typing_env, ssa_analysis) ;
33
54
34
55
let fully_moved = fully_moved_locals ( & ssa, body) ;
35
56
debug ! ( ?fully_moved) ;
0 commit comments