10
10
11
11
use syntax:: ast:: NodeId ;
12
12
use syntax:: symbol:: InternedString ;
13
- use ty:: Instance ;
13
+ use ty:: { Instance , TyCtxt } ;
14
14
use util:: nodemap:: FxHashMap ;
15
15
use rustc_data_structures:: base_n;
16
16
use rustc_data_structures:: stable_hasher:: { HashStable , StableHasherResult ,
@@ -25,6 +25,21 @@ pub enum MonoItem<'tcx> {
25
25
GlobalAsm ( NodeId ) ,
26
26
}
27
27
28
+ impl < ' tcx > MonoItem < ' tcx > {
29
+ pub fn size_estimate < ' a > ( & self , tcx : & TyCtxt < ' a , ' tcx , ' tcx > ) -> usize {
30
+ match * self {
31
+ MonoItem :: Fn ( instance) => {
32
+ // Estimate the size of a function based on how many statements
33
+ // it contains.
34
+ tcx. instance_def_size_estimate ( instance. def )
35
+ } ,
36
+ // Conservatively estimate the size of a static declaration
37
+ // or assembly to be 1.
38
+ MonoItem :: Static ( _) | MonoItem :: GlobalAsm ( _) => 1 ,
39
+ }
40
+ }
41
+ }
42
+
28
43
impl < ' tcx > HashStable < StableHashingContext < ' tcx > > for MonoItem < ' tcx > {
29
44
fn hash_stable < W : StableHasherResult > ( & self ,
30
45
hcx : & mut StableHashingContext < ' tcx > ,
@@ -52,6 +67,7 @@ pub struct CodegenUnit<'tcx> {
52
67
/// as well as the crate name and disambiguator.
53
68
name : InternedString ,
54
69
items : FxHashMap < MonoItem < ' tcx > , ( Linkage , Visibility ) > ,
70
+ size_estimate : Option < usize > ,
55
71
}
56
72
57
73
#[ derive( Copy , Clone , PartialEq , Eq , Hash , Debug ) ]
@@ -101,6 +117,7 @@ impl<'tcx> CodegenUnit<'tcx> {
101
117
CodegenUnit {
102
118
name : name,
103
119
items : FxHashMap ( ) ,
120
+ size_estimate : None ,
104
121
}
105
122
}
106
123
@@ -131,6 +148,24 @@ impl<'tcx> CodegenUnit<'tcx> {
131
148
let hash = hash & ( ( 1u128 << 80 ) - 1 ) ;
132
149
base_n:: encode ( hash, base_n:: CASE_INSENSITIVE )
133
150
}
151
+
152
+ pub fn estimate_size < ' a > ( & mut self , tcx : & TyCtxt < ' a , ' tcx , ' tcx > ) {
153
+ // Estimate the size of a codegen unit as (approximately) the number of MIR
154
+ // statements it corresponds to.
155
+ self . size_estimate = Some ( self . items . keys ( ) . map ( |mi| mi. size_estimate ( tcx) ) . sum ( ) ) ;
156
+ }
157
+
158
+ pub fn size_estimate ( & self ) -> usize {
159
+ // Should only be called if `estimate_size` has previously been called.
160
+ self . size_estimate . expect ( "estimate_size must be called before getting a size_estimate" )
161
+ }
162
+
163
+ pub fn modify_size_estimate ( & mut self , delta : usize ) {
164
+ assert ! ( self . size_estimate. is_some( ) ) ;
165
+ if let Some ( size_estimate) = self . size_estimate {
166
+ self . size_estimate = Some ( size_estimate + delta) ;
167
+ }
168
+ }
134
169
}
135
170
136
171
impl < ' tcx > HashStable < StableHashingContext < ' tcx > > for CodegenUnit < ' tcx > {
@@ -140,6 +175,8 @@ impl<'tcx> HashStable<StableHashingContext<'tcx>> for CodegenUnit<'tcx> {
140
175
let CodegenUnit {
141
176
ref items,
142
177
name,
178
+ // The size estimate is not relevant to the hash
179
+ size_estimate : _,
143
180
} = * self ;
144
181
145
182
name. hash_stable ( hcx, hasher) ;
0 commit comments