@@ -18,12 +18,13 @@ use rustc_ast::attr;
1818use rustc_data_structures:: fingerprint:: Fingerprint ;
1919use rustc_data_structures:: fx:: FxHashMap ;
2020use rustc_data_structures:: stable_hasher:: StableHasher ;
21- use rustc_data_structures:: sync:: { join, par_for_each_in , Lrc } ;
21+ use rustc_data_structures:: sync:: { join, Lrc } ;
2222use rustc_hir as hir;
2323use rustc_hir:: def:: CtorKind ;
24+ use rustc_hir:: def_id:: DefIdSet ;
2425use rustc_hir:: def_id:: { CrateNum , DefId , DefIndex , LocalDefId , CRATE_DEF_INDEX , LOCAL_CRATE } ;
2526use rustc_hir:: intravisit:: { self , NestedVisitorMap , Visitor } ;
26- use rustc_hir:: itemlikevisit:: ItemLikeVisitor ;
27+ use rustc_hir:: itemlikevisit:: { ItemLikeVisitor , ParItemLikeVisitor } ;
2728use rustc_hir:: { AnonConst , GenericParamKind } ;
2829use rustc_index:: vec:: Idx ;
2930use rustc_serialize:: { opaque, Encodable , Encoder , SpecializedEncoder } ;
@@ -1697,6 +1698,66 @@ impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplVisitor<'tcx> {
16971698 }
16981699}
16991700
1701+ /// Used to prefetch queries which will be needed later by metadata encoding.
1702+ struct PrefetchVisitor < ' tcx > {
1703+ tcx : TyCtxt < ' tcx > ,
1704+ mir_keys : & ' tcx DefIdSet ,
1705+ }
1706+
1707+ impl < ' tcx > PrefetchVisitor < ' tcx > {
1708+ fn prefetch_mir ( & self , def_id : DefId ) {
1709+ if self . mir_keys . contains ( & def_id) {
1710+ self . tcx . optimized_mir ( def_id) ;
1711+ self . tcx . promoted_mir ( def_id) ;
1712+ }
1713+ }
1714+ }
1715+
1716+ impl < ' tcx , ' v > ParItemLikeVisitor < ' v > for PrefetchVisitor < ' tcx > {
1717+ fn visit_item ( & self , item : & hir:: Item < ' _ > ) {
1718+ let tcx = self . tcx ;
1719+ match item. kind {
1720+ hir:: ItemKind :: Static ( ..) | hir:: ItemKind :: Const ( ..) => {
1721+ self . prefetch_mir ( tcx. hir ( ) . local_def_id ( item. hir_id ) )
1722+ }
1723+ hir:: ItemKind :: Fn ( ref sig, ..) => {
1724+ let def_id = tcx. hir ( ) . local_def_id ( item. hir_id ) ;
1725+ let generics = tcx. generics_of ( def_id) ;
1726+ let needs_inline = generics. requires_monomorphization ( tcx)
1727+ || tcx. codegen_fn_attrs ( def_id) . requests_inline ( ) ;
1728+ if needs_inline || sig. header . constness == hir:: Constness :: Const {
1729+ self . prefetch_mir ( def_id)
1730+ }
1731+ }
1732+ _ => ( ) ,
1733+ }
1734+ }
1735+
1736+ fn visit_trait_item ( & self , trait_item : & ' v hir:: TraitItem < ' v > ) {
1737+ self . prefetch_mir ( self . tcx . hir ( ) . local_def_id ( trait_item. hir_id ) ) ;
1738+ }
1739+
1740+ fn visit_impl_item ( & self , impl_item : & ' v hir:: ImplItem < ' v > ) {
1741+ let tcx = self . tcx ;
1742+ match impl_item. kind {
1743+ hir:: ImplItemKind :: Const ( ..) => {
1744+ self . prefetch_mir ( tcx. hir ( ) . local_def_id ( impl_item. hir_id ) )
1745+ }
1746+ hir:: ImplItemKind :: Fn ( ref sig, _) => {
1747+ let def_id = tcx. hir ( ) . local_def_id ( impl_item. hir_id ) ;
1748+ let generics = tcx. generics_of ( def_id) ;
1749+ let needs_inline = generics. requires_monomorphization ( tcx)
1750+ || tcx. codegen_fn_attrs ( def_id) . requests_inline ( ) ;
1751+ let is_const_fn = sig. header . constness == hir:: Constness :: Const ;
1752+ if needs_inline || is_const_fn {
1753+ self . prefetch_mir ( def_id)
1754+ }
1755+ }
1756+ hir:: ImplItemKind :: OpaqueTy ( ..) | hir:: ImplItemKind :: TyAlias ( ..) => ( ) ,
1757+ }
1758+ }
1759+ }
1760+
17001761// NOTE(eddyb) The following comment was preserved for posterity, even
17011762// though it's no longer relevant as EBML (which uses nested & tagged
17021763// "documents") was replaced with a scheme that can't go out of bounds.
@@ -1724,14 +1785,21 @@ pub(super) fn encode_metadata(tcx: TyCtxt<'_>) -> EncodedMetadata {
17241785 join (
17251786 || encode_metadata_impl ( tcx) ,
17261787 || {
1727- // Prefetch some queries used by metadata encoding
1788+ if tcx. sess . threads ( ) == 1 {
1789+ return ;
1790+ }
1791+ // Prefetch some queries used by metadata encoding.
17281792 tcx. dep_graph . with_ignore ( || {
17291793 join (
17301794 || {
1731- par_for_each_in ( tcx. mir_keys ( LOCAL_CRATE ) , |& def_id| {
1732- tcx. optimized_mir ( def_id) ;
1733- tcx. promoted_mir ( def_id) ;
1734- } )
1795+ if !tcx. sess . opts . output_types . should_codegen ( ) {
1796+ // We won't emit MIR, so don't prefetch it.
1797+ return ;
1798+ }
1799+ tcx. hir ( ) . krate ( ) . par_visit_all_item_likes ( & PrefetchVisitor {
1800+ tcx,
1801+ mir_keys : tcx. mir_keys ( LOCAL_CRATE ) ,
1802+ } ) ;
17351803 } ,
17361804 || tcx. exported_symbols ( LOCAL_CRATE ) ,
17371805 ) ;
0 commit comments