@@ -2,15 +2,15 @@ use crate::rmeta::table::{FixedSizeEncoding, TableBuilder};
22use crate :: rmeta:: * ;
33
44use rustc_data_structures:: fingerprint:: { Fingerprint , FingerprintEncoder } ;
5- use rustc_data_structures:: fx:: { FxHashMap , FxHashSet , FxIndexSet } ;
5+ use rustc_data_structures:: fx:: { FxHashMap , FxIndexSet } ;
66use rustc_data_structures:: stable_hasher:: StableHasher ;
7- use rustc_data_structures:: sync:: { join, Lrc } ;
7+ use rustc_data_structures:: sync:: { join, par_iter , Lrc , ParallelIterator } ;
88use rustc_hir as hir;
99use rustc_hir:: def:: { CtorOf , DefKind } ;
1010use rustc_hir:: def_id:: { CrateNum , DefId , DefIndex , LocalDefId , CRATE_DEF_INDEX , LOCAL_CRATE } ;
1111use rustc_hir:: definitions:: DefPathData ;
1212use rustc_hir:: intravisit:: { self , NestedVisitorMap , Visitor } ;
13- use rustc_hir:: itemlikevisit:: { ItemLikeVisitor , ParItemLikeVisitor } ;
13+ use rustc_hir:: itemlikevisit:: ItemLikeVisitor ;
1414use rustc_hir:: lang_items;
1515use rustc_hir:: { AnonConst , GenericParamKind } ;
1616use rustc_index:: bit_set:: GrowableBitSet ;
@@ -65,11 +65,6 @@ pub(super) struct EncodeContext<'a, 'tcx> {
6565 required_source_files : Option < GrowableBitSet < usize > > ,
6666 is_proc_macro : bool ,
6767 hygiene_ctxt : & ' a HygieneEncodeContext ,
68-
69- // Determines if MIR used for code generation will be included in the crate
70- // metadata. When emitting only metadata (e.g., cargo check), we can avoid
71- // generating optimized MIR altogether.
72- emit_codegen_mir : bool ,
7368}
7469
7570/// If the current crate is a proc-macro, returns early with `Lazy:empty()`.
@@ -580,6 +575,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
580575 // Encode the items.
581576 i = self . position ( ) ;
582577 self . encode_def_ids ( ) ;
578+ self . encode_mir ( ) ;
583579 self . encode_info_for_items ( ) ;
584580 let item_bytes = self . position ( ) - i;
585581
@@ -919,11 +915,6 @@ impl EncodeContext<'a, 'tcx> {
919915 self . encode_generics ( def_id) ;
920916 self . encode_explicit_predicates ( def_id) ;
921917 self . encode_inferred_outlives ( def_id) ;
922- let opt_mir = tcx. sess . opts . debugging_opts . always_encode_mir || self . emit_codegen_mir ;
923- if opt_mir {
924- self . encode_optimized_mir ( def_id. expect_local ( ) ) ;
925- }
926- self . encode_mir_for_ctfe ( def_id. expect_local ( ) ) ;
927918 }
928919
929920 fn encode_info_for_mod ( & mut self , id : hir:: HirId , md : & hir:: Mod < ' _ > ) {
@@ -1009,11 +1000,6 @@ impl EncodeContext<'a, 'tcx> {
10091000 self . encode_generics ( def_id) ;
10101001 self . encode_explicit_predicates ( def_id) ;
10111002 self . encode_inferred_outlives ( def_id) ;
1012- let opt_mir = tcx. sess . opts . debugging_opts . always_encode_mir || self . emit_codegen_mir ;
1013- if opt_mir {
1014- self . encode_optimized_mir ( def_id. expect_local ( ) ) ;
1015- }
1016- self . encode_mir_for_ctfe ( def_id. expect_local ( ) ) ;
10171003 }
10181004
10191005 fn encode_generics ( & mut self , def_id : DefId ) {
@@ -1119,34 +1105,6 @@ impl EncodeContext<'a, 'tcx> {
11191105 self . encode_generics ( def_id) ;
11201106 self . encode_explicit_predicates ( def_id) ;
11211107 self . encode_inferred_outlives ( def_id) ;
1122-
1123- // This should be kept in sync with `PrefetchVisitor.visit_trait_item`.
1124- match trait_item. kind {
1125- ty:: AssocKind :: Type => { }
1126- ty:: AssocKind :: Const => {
1127- if self . tcx . mir_keys ( LOCAL_CRATE ) . contains ( & def_id. expect_local ( ) ) {
1128- self . encode_mir_for_ctfe ( def_id. expect_local ( ) ) ;
1129- self . encode_promoted_mir ( def_id. expect_local ( ) ) ;
1130- }
1131- }
1132- ty:: AssocKind :: Fn => {
1133- let opt_mir =
1134- tcx. sess . opts . debugging_opts . always_encode_mir || self . emit_codegen_mir ;
1135- if opt_mir {
1136- if self . tcx . mir_keys ( LOCAL_CRATE ) . contains ( & def_id. expect_local ( ) ) {
1137- self . encode_optimized_mir ( def_id. expect_local ( ) ) ;
1138- self . encode_promoted_mir ( def_id. expect_local ( ) ) ;
1139- }
1140- }
1141- }
1142- }
1143- }
1144-
1145- fn should_encode_fn_opt_mir ( & self , def_id : DefId ) -> bool {
1146- self . tcx . sess . opts . debugging_opts . always_encode_mir
1147- || ( self . emit_codegen_mir
1148- && ( self . tcx . generics_of ( def_id) . requires_monomorphization ( self . tcx )
1149- || self . tcx . codegen_fn_attrs ( def_id) . requests_inline ( ) ) )
11501108 }
11511109
11521110 fn encode_info_for_impl_item ( & mut self , def_id : DefId ) {
@@ -1208,27 +1166,6 @@ impl EncodeContext<'a, 'tcx> {
12081166 self . encode_generics ( def_id) ;
12091167 self . encode_explicit_predicates ( def_id) ;
12101168 self . encode_inferred_outlives ( def_id) ;
1211-
1212- // The following part should be kept in sync with `PrefetchVisitor.visit_impl_item`.
1213-
1214- let ( mir, mir_const) = match ast_item. kind {
1215- hir:: ImplItemKind :: Const ( ..) => ( false , true ) ,
1216- hir:: ImplItemKind :: Fn ( ref sig, _) => {
1217- let opt_mir = self . should_encode_fn_opt_mir ( def_id) ;
1218- let is_const_fn = sig. header . constness == hir:: Constness :: Const ;
1219- ( opt_mir, is_const_fn)
1220- }
1221- hir:: ImplItemKind :: TyAlias ( ..) => ( false , false ) ,
1222- } ;
1223- if mir {
1224- self . encode_optimized_mir ( def_id. expect_local ( ) ) ;
1225- }
1226- if mir || mir_const {
1227- self . encode_promoted_mir ( def_id. expect_local ( ) ) ;
1228- }
1229- if mir_const {
1230- self . encode_mir_for_ctfe ( def_id. expect_local ( ) ) ;
1231- }
12321169 }
12331170
12341171 fn encode_fn_param_names_for_body ( & mut self , body_id : hir:: BodyId ) -> Lazy < [ Ident ] > {
@@ -1239,36 +1176,37 @@ impl EncodeContext<'a, 'tcx> {
12391176 self . lazy ( param_names. iter ( ) )
12401177 }
12411178
1242- fn encode_mir_for_ctfe ( & mut self , def_id : LocalDefId ) {
1243- debug ! ( "EntryBuilder::encode_mir_for_ctfe({:?})" , def_id) ;
1244- record ! ( self . tables. mir_for_ctfe[ def_id. to_def_id( ) ] <- self . tcx. mir_for_ctfe( def_id) ) ;
1245-
1246- let unused = self . tcx . unused_generic_params ( def_id) ;
1247- if !unused. is_empty ( ) {
1248- record ! ( self . tables. unused_generic_params[ def_id. to_def_id( ) ] <- unused) ;
1179+ fn encode_mir ( & mut self ) {
1180+ if self . is_proc_macro {
1181+ return ;
12491182 }
1183+ for & def_id in self . tcx . mir_keys ( LOCAL_CRATE ) . iter ( ) {
1184+ let ( encode_const, encode_opt) = should_encode_mir ( self . tcx , def_id) ;
1185+ if !encode_const && !encode_opt {
1186+ continue ;
1187+ }
12501188
1251- let abstract_const = self . tcx . mir_abstract_const ( def_id) ;
1252- if let Ok ( Some ( abstract_const) ) = abstract_const {
1253- record ! ( self . tables. mir_abstract_consts[ def_id. to_def_id( ) ] <- abstract_const) ;
1254- }
1255- }
1189+ debug ! ( "EntryBuilder::encode_mir({:?})" , def_id) ;
1190+ if encode_opt {
1191+ record ! ( self . tables. mir[ def_id. to_def_id( ) ] <- self . tcx. optimized_mir( def_id) ) ;
1192+ }
1193+ if encode_const {
1194+ record ! ( self . tables. mir_for_ctfe[ def_id. to_def_id( ) ] <- self . tcx. mir_for_ctfe( def_id) ) ;
1195+ }
1196+ record ! ( self . tables. promoted_mir[ def_id. to_def_id( ) ] <- self . tcx. promoted_mir( def_id) ) ;
12561197
1257- fn encode_optimized_mir ( & mut self , def_id : LocalDefId ) {
1258- debug ! ( "EntryBuilder::encode_optimized_mir({:?})" , def_id) ;
1259- record ! ( self . tables. mir[ def_id. to_def_id( ) ] <- self . tcx. optimized_mir( def_id) ) ;
1198+ let unused = self . tcx . unused_generic_params ( def_id) ;
1199+ if !unused. is_empty ( ) {
1200+ record ! ( self . tables. unused_generic_params[ def_id. to_def_id( ) ] <- unused) ;
1201+ }
12601202
1261- let unused = self . tcx . unused_generic_params ( def_id) ;
1262- if !unused. is_empty ( ) {
1263- record ! ( self . tables. unused_generic_params[ def_id. to_def_id( ) ] <- unused) ;
1203+ let abstract_const = self . tcx . mir_abstract_const ( def_id) ;
1204+ if let Ok ( Some ( abstract_const) ) = abstract_const {
1205+ record ! ( self . tables. mir_abstract_consts[ def_id. to_def_id( ) ] <- abstract_const) ;
1206+ }
12641207 }
12651208 }
12661209
1267- fn encode_promoted_mir ( & mut self , def_id : LocalDefId ) {
1268- debug ! ( "EncodeContext::encode_promoted_mir({:?})" , def_id) ;
1269- record ! ( self . tables. promoted_mir[ def_id. to_def_id( ) ] <- self . tcx. promoted_mir( def_id) ) ;
1270- }
1271-
12721210 // Encodes the inherent implementations of a structure, enumeration, or trait.
12731211 fn encode_inherent_implementations ( & mut self , def_id : DefId ) {
12741212 debug ! ( "EncodeContext::encode_inherent_implementations({:?})" , def_id) ;
@@ -1524,28 +1462,6 @@ impl EncodeContext<'a, 'tcx> {
15241462 }
15251463 _ => { }
15261464 }
1527-
1528- // The following part should be kept in sync with `PrefetchVisitor.visit_item`.
1529-
1530- let ( mir, const_mir) = match item. kind {
1531- hir:: ItemKind :: Static ( ..) | hir:: ItemKind :: Const ( ..) => ( false , true ) ,
1532- hir:: ItemKind :: Fn ( ref sig, ..) => {
1533- let opt_mir = self . should_encode_fn_opt_mir ( def_id) ;
1534- let is_const_fn = sig. header . constness == hir:: Constness :: Const ;
1535- // We don't need the optimized MIR for const fns.
1536- ( opt_mir, is_const_fn)
1537- }
1538- _ => ( false , false ) ,
1539- } ;
1540- if mir {
1541- self . encode_optimized_mir ( def_id. expect_local ( ) ) ;
1542- }
1543- if mir || const_mir {
1544- self . encode_promoted_mir ( def_id. expect_local ( ) ) ;
1545- }
1546- if const_mir {
1547- self . encode_mir_for_ctfe ( def_id. expect_local ( ) ) ;
1548- }
15491465 }
15501466
15511467 /// Serialize the text of exported macros
@@ -1587,14 +1503,6 @@ impl EncodeContext<'a, 'tcx> {
15871503 record ! ( self . tables. fn_sig[ def_id] <- substs. as_closure( ) . sig( ) ) ;
15881504 }
15891505 self . encode_generics ( def_id. to_def_id ( ) ) ;
1590- let opt_mir = // FIXME: Optimized MIR is necessary to determine the layout of generators.
1591- matches ! ( ty. kind( ) , ty:: Generator ( ..) )
1592- || self . tcx . sess . opts . debugging_opts . always_encode_mir
1593- || self . emit_codegen_mir ;
1594- if opt_mir {
1595- self . encode_optimized_mir ( def_id) ;
1596- self . encode_promoted_mir ( def_id) ;
1597- }
15981506 }
15991507
16001508 fn encode_info_for_anon_const ( & mut self , def_id : LocalDefId ) {
@@ -1609,8 +1517,6 @@ impl EncodeContext<'a, 'tcx> {
16091517 self . encode_generics ( def_id. to_def_id ( ) ) ;
16101518 self . encode_explicit_predicates ( def_id. to_def_id ( ) ) ;
16111519 self . encode_inferred_outlives ( def_id. to_def_id ( ) ) ;
1612- self . encode_mir_for_ctfe ( def_id) ;
1613- self . encode_promoted_mir ( def_id) ;
16141520 }
16151521
16161522 fn encode_native_libraries ( & mut self ) -> Lazy < [ NativeLib ] > {
@@ -2075,90 +1981,25 @@ impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplVisitor<'tcx> {
20751981
20761982/// Used to prefetch queries which will be needed later by metadata encoding.
20771983/// Only a subset of the queries are actually prefetched to keep this code smaller.
2078- struct PrefetchVisitor < ' tcx > {
2079- tcx : TyCtxt < ' tcx > ,
2080- mir_keys : & ' tcx FxHashSet < LocalDefId > ,
2081- }
2082-
2083- impl < ' tcx > PrefetchVisitor < ' tcx > {
2084- fn prefetch_ctfe_mir ( & self , def_id : LocalDefId ) {
2085- if self . mir_keys . contains ( & def_id) {
2086- self . tcx . ensure ( ) . mir_for_ctfe ( def_id) ;
2087- self . tcx . ensure ( ) . promoted_mir ( def_id) ;
2088- }
1984+ fn prefetch_mir ( tcx : TyCtxt < ' _ > ) {
1985+ if !tcx. sess . opts . output_types . should_codegen ( ) {
1986+ // We won't emit MIR, so don't prefetch it.
1987+ return ;
20891988 }
2090- fn prefetch_mir ( & self , def_id : LocalDefId ) {
2091- if self . mir_keys . contains ( & def_id) {
2092- self . tcx . ensure ( ) . optimized_mir ( def_id) ;
2093- self . tcx . ensure ( ) . promoted_mir ( def_id) ;
2094- }
2095- }
2096- }
20971989
2098- impl < ' tcx , ' v > ParItemLikeVisitor < ' v > for PrefetchVisitor < ' tcx > {
2099- fn visit_item ( & self , item : & hir:: Item < ' _ > ) {
2100- // This should be kept in sync with `encode_info_for_item`.
2101- let tcx = self . tcx ;
2102- match item. kind {
2103- hir:: ItemKind :: Static ( ..) | hir:: ItemKind :: Const ( ..) => {
2104- self . prefetch_ctfe_mir ( tcx. hir ( ) . local_def_id ( item. hir_id ) )
2105- }
2106- hir:: ItemKind :: Fn ( ref sig, ..) => {
2107- let def_id = tcx. hir ( ) . local_def_id ( item. hir_id ) ;
2108- let opt_mir = tcx. generics_of ( def_id. to_def_id ( ) ) . requires_monomorphization ( tcx)
2109- || tcx. codegen_fn_attrs ( def_id. to_def_id ( ) ) . requests_inline ( ) ;
2110- if opt_mir {
2111- self . prefetch_mir ( def_id)
2112- }
2113- if sig. header . constness == hir:: Constness :: Const {
2114- self . prefetch_ctfe_mir ( def_id) ;
2115- }
2116- }
2117- _ => ( ) ,
2118- }
2119- }
1990+ par_iter ( tcx. mir_keys ( LOCAL_CRATE ) ) . for_each ( |& def_id| {
1991+ let ( encode_const, encode_opt) = should_encode_mir ( tcx, def_id) ;
21201992
2121- fn visit_trait_item ( & self , trait_item : & ' v hir:: TraitItem < ' v > ) {
2122- // This should be kept in sync with `encode_info_for_trait_item`.
2123- let def_id = self . tcx . hir ( ) . local_def_id ( trait_item. hir_id ) ;
2124- match trait_item. kind {
2125- hir:: TraitItemKind :: Type ( ..) => { }
2126- hir:: TraitItemKind :: Const ( ..) => {
2127- self . prefetch_ctfe_mir ( def_id) ;
2128- }
2129- hir:: TraitItemKind :: Fn ( ..) => {
2130- self . prefetch_mir ( def_id) ;
2131- }
1993+ if encode_const {
1994+ tcx. ensure ( ) . mir_for_ctfe ( def_id) ;
21321995 }
2133- }
2134-
2135- fn visit_impl_item ( & self , impl_item : & ' v hir:: ImplItem < ' v > ) {
2136- // This should be kept in sync with `encode_info_for_impl_item`.
2137- let tcx = self . tcx ;
2138- match impl_item. kind {
2139- hir:: ImplItemKind :: Const ( ..) => {
2140- self . prefetch_ctfe_mir ( tcx. hir ( ) . local_def_id ( impl_item. hir_id ) )
2141- }
2142- hir:: ImplItemKind :: Fn ( ref sig, _) => {
2143- let def_id = tcx. hir ( ) . local_def_id ( impl_item. hir_id ) ;
2144- let opt_mir = tcx. generics_of ( def_id. to_def_id ( ) ) . requires_monomorphization ( tcx)
2145- || tcx. codegen_fn_attrs ( def_id. to_def_id ( ) ) . requests_inline ( ) ;
2146- let is_const_fn = sig. header . constness == hir:: Constness :: Const ;
2147- if opt_mir {
2148- self . prefetch_mir ( def_id)
2149- }
2150- if is_const_fn {
2151- self . prefetch_ctfe_mir ( def_id) ;
2152- }
2153- }
2154- hir:: ImplItemKind :: TyAlias ( ..) => ( ) ,
1996+ if encode_opt {
1997+ tcx. ensure ( ) . optimized_mir ( def_id) ;
21551998 }
2156- }
2157-
2158- fn visit_foreign_item ( & self , _foreign_item : & ' v hir:: ForeignItem < ' v > ) {
2159- // This should be kept in sync with `encode_info_for_foreign_item`.
2160- // Foreign items contain no MIR.
2161- }
1999+ if encode_opt || encode_const {
2000+ tcx. ensure ( ) . promoted_mir ( def_id) ;
2001+ }
2002+ } )
21622003}
21632004
21642005// NOTE(eddyb) The following comment was preserved for posterity, even
@@ -2198,19 +2039,7 @@ pub(super) fn encode_metadata(tcx: TyCtxt<'_>) -> EncodedMetadata {
21982039 // Prefetch some queries used by metadata encoding.
21992040 // This is not necessary for correctness, but is only done for performance reasons.
22002041 // It can be removed if it turns out to cause trouble or be detrimental to performance.
2201- join (
2202- || {
2203- if !tcx. sess . opts . output_types . should_codegen ( ) {
2204- // We won't emit MIR, so don't prefetch it.
2205- return ;
2206- }
2207- tcx. hir ( ) . krate ( ) . par_visit_all_item_likes ( & PrefetchVisitor {
2208- tcx,
2209- mir_keys : tcx. mir_keys ( LOCAL_CRATE ) ,
2210- } ) ;
2211- } ,
2212- || tcx. exported_symbols ( LOCAL_CRATE ) ,
2213- ) ;
2042+ join ( || prefetch_mir ( tcx) , || tcx. exported_symbols ( LOCAL_CRATE ) ) ;
22142043 } ,
22152044 )
22162045 . 0
@@ -2243,7 +2072,6 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>) -> EncodedMetadata {
22432072 required_source_files,
22442073 is_proc_macro : tcx. sess . crate_types ( ) . contains ( & CrateType :: ProcMacro ) ,
22452074 hygiene_ctxt : & hygiene_ctxt,
2246- emit_codegen_mir : tcx. sess . opts . output_types . should_codegen ( ) ,
22472075 } ;
22482076
22492077 // Encode the rustc version string in a predictable location.
0 commit comments