8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
+ use build;
12
+ use rustc:: hir:: def_id:: { CrateNum , DefId , LOCAL_CRATE } ;
11
13
use rustc:: mir:: Mir ;
12
- use rustc:: mir:: transform:: { MirPassIndex , MirSuite , MirSource } ;
13
- use rustc:: ty:: TyCtxt ;
14
+ use rustc:: mir:: transform:: { MirPassIndex , MirSuite , MirSource ,
15
+ MIR_CONST , MIR_VALIDATED , MIR_OPTIMIZED } ;
16
+ use rustc:: ty:: { self , TyCtxt } ;
14
17
use rustc:: ty:: maps:: Providers ;
18
+ use rustc:: ty:: steal:: Steal ;
19
+ use rustc:: hir;
20
+ use rustc:: hir:: intravisit:: { self , Visitor , NestedVisitorMap } ;
21
+ use rustc:: util:: nodemap:: DefIdSet ;
22
+ use std:: rc:: Rc ;
23
+ use syntax:: ast;
24
+ use syntax_pos:: { DUMMY_SP , Span } ;
25
+ use transform;
15
26
16
27
pub mod simplify_branches;
17
28
pub mod simplify;
@@ -30,14 +41,96 @@ pub mod inline;
30
41
pub ( crate ) fn provide ( providers : & mut Providers ) {
31
42
self :: qualify_consts:: provide ( providers) ;
32
43
* providers = Providers {
44
+ mir_keys,
45
+ mir_const,
46
+ mir_validated,
47
+ optimized_mir,
48
+ is_mir_available,
33
49
..* providers
34
50
} ;
35
51
}
36
52
37
- pub ( crate ) fn run_suite < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
38
- source : MirSource ,
39
- suite : MirSuite ,
40
- mir : & mut Mir < ' tcx > )
53
+ fn is_mir_available < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , def_id : DefId ) -> bool {
54
+ tcx. mir_keys ( def_id. krate ) . contains ( & def_id)
55
+ }
56
+
57
+ /// Finds the full set of def-ids within the current crate that have
58
+ /// MIR associated with them.
59
+ fn mir_keys < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , krate : CrateNum )
60
+ -> Rc < DefIdSet > {
61
+ assert_eq ! ( krate, LOCAL_CRATE ) ;
62
+
63
+ let mut set = DefIdSet ( ) ;
64
+
65
+ // All body-owners have MIR associated with them.
66
+ set. extend ( tcx. body_owners ( ) ) ;
67
+
68
+ // Additionally, tuple struct/variant constructors have MIR, but
69
+ // they don't have a BodyId, so we need to build them separately.
70
+ struct GatherCtors < ' a , ' tcx : ' a > {
71
+ tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
72
+ set : & ' a mut DefIdSet ,
73
+ }
74
+ impl < ' a , ' tcx > Visitor < ' tcx > for GatherCtors < ' a , ' tcx > {
75
+ fn visit_variant_data ( & mut self ,
76
+ v : & ' tcx hir:: VariantData ,
77
+ _: ast:: Name ,
78
+ _: & ' tcx hir:: Generics ,
79
+ _: ast:: NodeId ,
80
+ _: Span ) {
81
+ if let hir:: VariantData :: Tuple ( _, node_id) = * v {
82
+ self . set . insert ( self . tcx . hir . local_def_id ( node_id) ) ;
83
+ }
84
+ intravisit:: walk_struct_def ( self , v)
85
+ }
86
+ fn nested_visit_map < ' b > ( & ' b mut self ) -> NestedVisitorMap < ' b , ' tcx > {
87
+ NestedVisitorMap :: None
88
+ }
89
+ }
90
+ tcx. hir . krate ( ) . visit_all_item_likes ( & mut GatherCtors {
91
+ tcx : tcx,
92
+ set : & mut set,
93
+ } . as_deep_visitor ( ) ) ;
94
+
95
+ Rc :: new ( set)
96
+ }
97
+
98
+ fn mir_const < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , def_id : DefId ) -> & ' tcx Steal < Mir < ' tcx > > {
99
+ let mut mir = build:: mir_build ( tcx, def_id) ;
100
+ let source = MirSource :: from_local_def_id ( tcx, def_id) ;
101
+ transform:: run_suite ( tcx, source, MIR_CONST , & mut mir) ;
102
+ tcx. alloc_steal_mir ( mir)
103
+ }
104
+
105
+ fn mir_validated < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , def_id : DefId ) -> & ' tcx Steal < Mir < ' tcx > > {
106
+ let source = MirSource :: from_local_def_id ( tcx, def_id) ;
107
+ if let MirSource :: Const ( _) = source {
108
+ // Ensure that we compute the `mir_const_qualif` for constants at
109
+ // this point, before we steal the mir-const result. We don't
110
+ // directly need the result or `mir_const_qualif`, so we can just force it.
111
+ ty:: queries:: mir_const_qualif:: force ( tcx, DUMMY_SP , def_id) ;
112
+ }
113
+
114
+ let mut mir = tcx. mir_const ( def_id) . steal ( ) ;
115
+ transform:: run_suite ( tcx, source, MIR_VALIDATED , & mut mir) ;
116
+ tcx. alloc_steal_mir ( mir)
117
+ }
118
+
119
+ fn optimized_mir < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , def_id : DefId ) -> & ' tcx Mir < ' tcx > {
120
+ // Borrowck uses `mir_validated`, so we have to force it to
121
+ // execute before we can steal.
122
+ ty:: queries:: borrowck:: force ( tcx, DUMMY_SP , def_id) ;
123
+
124
+ let mut mir = tcx. mir_validated ( def_id) . steal ( ) ;
125
+ let source = MirSource :: from_local_def_id ( tcx, def_id) ;
126
+ transform:: run_suite ( tcx, source, MIR_OPTIMIZED , & mut mir) ;
127
+ tcx. alloc_mir ( mir)
128
+ }
129
+
130
+ fn run_suite < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
131
+ source : MirSource ,
132
+ suite : MirSuite ,
133
+ mir : & mut Mir < ' tcx > )
41
134
{
42
135
let passes = tcx. mir_passes . passes ( suite) ;
43
136
0 commit comments