@@ -14,14 +14,15 @@ use rustc::ty::layout::VariantIdx;
1414use rustc:: ty:: { self , SymbolName , Ty , TyCtxt } ;
1515use rustc_data_structures:: fingerprint:: Fingerprint ;
1616use rustc_hir:: def:: CtorKind ;
17+ use rustc_hir:: def_id:: DefIdSet ;
1718use rustc_hir:: def_id:: { CrateNum , DefId , DefIndex , LocalDefId , CRATE_DEF_INDEX , LOCAL_CRATE } ;
1819use rustc_hir:: { AnonConst , GenericParamKind } ;
1920use rustc_index:: vec:: Idx ;
2021
2122use rustc:: session:: config:: { self , CrateType } ;
2223use rustc_data_structures:: fx:: FxHashMap ;
2324use rustc_data_structures:: stable_hasher:: StableHasher ;
24- use rustc_data_structures:: sync:: { join, par_for_each_in , Lrc } ;
25+ use rustc_data_structures:: sync:: { join, Lrc } ;
2526use rustc_serialize:: { opaque, Encodable , Encoder , SpecializedEncoder } ;
2627
2728use log:: { debug, trace} ;
@@ -38,7 +39,7 @@ use syntax::expand::is_proc_macro_attr;
3839
3940use rustc_hir as hir;
4041use rustc_hir:: intravisit:: { self , NestedVisitorMap , Visitor } ;
41- use rustc_hir:: itemlikevisit:: ItemLikeVisitor ;
42+ use rustc_hir:: itemlikevisit:: { ItemLikeVisitor , ParItemLikeVisitor } ;
4243
4344struct EncodeContext < ' tcx > {
4445 opaque : opaque:: Encoder ,
@@ -1681,6 +1682,66 @@ impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplVisitor<'tcx> {
16811682 }
16821683}
16831684
1685+ /// Used to prefetch queries which will be needed later by metadata encoding.
1686+ struct PrefetchVisitor < ' tcx > {
1687+ tcx : TyCtxt < ' tcx > ,
1688+ mir_keys : & ' tcx DefIdSet ,
1689+ }
1690+
1691+ impl < ' tcx > PrefetchVisitor < ' tcx > {
1692+ fn prefetch_mir ( & self , def_id : DefId ) {
1693+ if self . mir_keys . contains ( & def_id) {
1694+ self . tcx . optimized_mir ( def_id) ;
1695+ self . tcx . promoted_mir ( def_id) ;
1696+ }
1697+ }
1698+ }
1699+
1700+ impl < ' tcx , ' v > ParItemLikeVisitor < ' v > for PrefetchVisitor < ' tcx > {
1701+ fn visit_item ( & self , item : & hir:: Item < ' _ > ) {
1702+ let tcx = self . tcx ;
1703+ match item. kind {
1704+ hir:: ItemKind :: Static ( ..) | hir:: ItemKind :: Const ( ..) => {
1705+ self . prefetch_mir ( tcx. hir ( ) . local_def_id ( item. hir_id ) )
1706+ }
1707+ hir:: ItemKind :: Fn ( ref sig, ..) => {
1708+ let def_id = tcx. hir ( ) . local_def_id ( item. hir_id ) ;
1709+ let generics = tcx. generics_of ( def_id) ;
1710+ let needs_inline = generics. requires_monomorphization ( tcx)
1711+ || tcx. codegen_fn_attrs ( def_id) . requests_inline ( ) ;
1712+ if needs_inline || sig. header . constness == hir:: Constness :: Const {
1713+ self . prefetch_mir ( def_id)
1714+ }
1715+ }
1716+ _ => ( ) ,
1717+ }
1718+ }
1719+
1720+ fn visit_trait_item ( & self , trait_item : & ' v hir:: TraitItem < ' v > ) {
1721+ self . prefetch_mir ( self . tcx . hir ( ) . local_def_id ( trait_item. hir_id ) ) ;
1722+ }
1723+
1724+ fn visit_impl_item ( & self , impl_item : & ' v hir:: ImplItem < ' v > ) {
1725+ let tcx = self . tcx ;
1726+ match impl_item. kind {
1727+ hir:: ImplItemKind :: Const ( ..) => {
1728+ self . prefetch_mir ( tcx. hir ( ) . local_def_id ( impl_item. hir_id ) )
1729+ }
1730+ hir:: ImplItemKind :: Method ( ref sig, _) => {
1731+ let def_id = tcx. hir ( ) . local_def_id ( impl_item. hir_id ) ;
1732+ let generics = tcx. generics_of ( def_id) ;
1733+ let needs_inline = generics. requires_monomorphization ( tcx)
1734+ || tcx. codegen_fn_attrs ( def_id) . requests_inline ( ) ;
1735+ let is_const_fn = sig. header . constness == hir:: Constness :: Const ;
1736+ if needs_inline || is_const_fn {
1737+ self . prefetch_mir ( def_id)
1738+ }
1739+ }
1740+ hir:: ImplItemKind :: OpaqueTy ( ..) | hir:: ImplItemKind :: TyAlias ( ..) => ( ) ,
1741+ }
1742+ }
1743+ }
1744+
16841745// NOTE(eddyb) The following comment was preserved for posterity, even
16851746// though it's no longer relevant as EBML (which uses nested & tagged
16861747// "documents") was replaced with a scheme that can't go out of bounds.
@@ -1708,14 +1769,21 @@ pub(super) fn encode_metadata(tcx: TyCtxt<'_>) -> EncodedMetadata {
17081769 join (
17091770 || encode_metadata_impl ( tcx) ,
17101771 || {
1711- // Prefetch some queries used by metadata encoding
1772+ if tcx. sess . threads ( ) == 1 {
1773+ return ;
1774+ }
1775+ // Prefetch some queries used by metadata encoding.
17121776 tcx. dep_graph . with_ignore ( || {
17131777 join (
17141778 || {
1715- par_for_each_in ( tcx. mir_keys ( LOCAL_CRATE ) , |& def_id| {
1716- tcx. optimized_mir ( def_id) ;
1717- tcx. promoted_mir ( def_id) ;
1718- } )
1779+ if !tcx. sess . opts . output_types . should_codegen ( ) {
1780+ // We won't emit MIR, so don't prefetch it.
1781+ return ;
1782+ }
1783+ tcx. hir ( ) . krate ( ) . par_visit_all_item_likes ( & PrefetchVisitor {
1784+ tcx,
1785+ mir_keys : tcx. mir_keys ( LOCAL_CRATE ) ,
1786+ } ) ;
17191787 } ,
17201788 || tcx. exported_symbols ( LOCAL_CRATE ) ,
17211789 ) ;
0 commit comments