1010
1111use syntax:: ast:: NodeId ;
1212use syntax:: symbol:: InternedString ;
13- use ty:: Instance ;
13+ use ty:: { Instance , TyCtxt } ;
1414use util:: nodemap:: FxHashMap ;
1515use rustc_data_structures:: base_n;
1616use rustc_data_structures:: stable_hasher:: { HashStable , StableHasherResult ,
@@ -25,6 +25,21 @@ pub enum MonoItem<'tcx> {
2525 GlobalAsm ( NodeId ) ,
2626}
2727
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+
2843impl < ' tcx > HashStable < StableHashingContext < ' tcx > > for MonoItem < ' tcx > {
2944 fn hash_stable < W : StableHasherResult > ( & self ,
3045 hcx : & mut StableHashingContext < ' tcx > ,
@@ -52,6 +67,7 @@ pub struct CodegenUnit<'tcx> {
5267 /// as well as the crate name and disambiguator.
5368 name : InternedString ,
5469 items : FxHashMap < MonoItem < ' tcx > , ( Linkage , Visibility ) > ,
70+ size_estimate : Option < usize > ,
5571}
5672
5773#[ derive( Copy , Clone , PartialEq , Eq , Hash , Debug ) ]
@@ -101,6 +117,7 @@ impl<'tcx> CodegenUnit<'tcx> {
101117 CodegenUnit {
102118 name : name,
103119 items : FxHashMap ( ) ,
120+ size_estimate : None ,
104121 }
105122 }
106123
@@ -131,6 +148,24 @@ impl<'tcx> CodegenUnit<'tcx> {
131148 let hash = hash & ( ( 1u128 << 80 ) - 1 ) ;
132149 base_n:: encode ( hash, base_n:: CASE_INSENSITIVE )
133150 }
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+ }
134169}
135170
136171impl < ' tcx > HashStable < StableHashingContext < ' tcx > > for CodegenUnit < ' tcx > {
@@ -140,6 +175,8 @@ impl<'tcx> HashStable<StableHashingContext<'tcx>> for CodegenUnit<'tcx> {
140175 let CodegenUnit {
141176 ref items,
142177 name,
178+ // The size estimate is not relevant to the hash
179+ size_estimate : _,
143180 } = * self ;
144181
145182 name. hash_stable ( hcx, hasher) ;
0 commit comments