@@ -14,14 +14,15 @@ use rustc::ty::layout::VariantIdx;
14
14
use rustc:: ty:: { self , SymbolName , Ty , TyCtxt } ;
15
15
use rustc_data_structures:: fingerprint:: Fingerprint ;
16
16
use rustc_hir:: def:: CtorKind ;
17
+ use rustc_hir:: def_id:: DefIdSet ;
17
18
use rustc_hir:: def_id:: { CrateNum , DefId , DefIndex , LocalDefId , CRATE_DEF_INDEX , LOCAL_CRATE } ;
18
19
use rustc_hir:: { AnonConst , GenericParamKind } ;
19
20
use rustc_index:: vec:: Idx ;
20
21
21
22
use rustc:: session:: config:: { self , CrateType } ;
22
23
use rustc_data_structures:: fx:: FxHashMap ;
23
24
use 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 } ;
25
26
use rustc_serialize:: { opaque, Encodable , Encoder , SpecializedEncoder } ;
26
27
27
28
use log:: { debug, trace} ;
@@ -38,7 +39,7 @@ use syntax::expand::is_proc_macro_attr;
38
39
39
40
use rustc_hir as hir;
40
41
use rustc_hir:: intravisit:: { self , NestedVisitorMap , Visitor } ;
41
- use rustc_hir:: itemlikevisit:: ItemLikeVisitor ;
42
+ use rustc_hir:: itemlikevisit:: { ItemLikeVisitor , ParItemLikeVisitor } ;
42
43
43
44
struct EncodeContext < ' tcx > {
44
45
opaque : opaque:: Encoder ,
@@ -1681,6 +1682,66 @@ impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplVisitor<'tcx> {
1681
1682
}
1682
1683
}
1683
1684
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
+
1684
1745
// NOTE(eddyb) The following comment was preserved for posterity, even
1685
1746
// though it's no longer relevant as EBML (which uses nested & tagged
1686
1747
// "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 {
1708
1769
join (
1709
1770
|| encode_metadata_impl ( tcx) ,
1710
1771
|| {
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.
1712
1776
tcx. dep_graph . with_ignore ( || {
1713
1777
join (
1714
1778
|| {
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
+ } ) ;
1719
1787
} ,
1720
1788
|| tcx. exported_symbols ( LOCAL_CRATE ) ,
1721
1789
) ;
0 commit comments