Skip to content

Commit 4cea70f

Browse files
committed
Make metadata prefetching more accurate
1 parent 8ea0206 commit 4cea70f

File tree

1 file changed

+75
-7
lines changed

1 file changed

+75
-7
lines changed

src/librustc_metadata/rmeta/encoder.rs

Lines changed: 75 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,15 @@ use rustc::ty::layout::VariantIdx;
1414
use rustc::ty::{self, SymbolName, Ty, TyCtxt};
1515
use rustc_data_structures::fingerprint::Fingerprint;
1616
use rustc_hir::def::CtorKind;
17+
use rustc_hir::def_id::DefIdSet;
1718
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
1819
use rustc_hir::{AnonConst, GenericParamKind};
1920
use rustc_index::vec::Idx;
2021

2122
use rustc::session::config::{self, CrateType};
2223
use rustc_data_structures::fx::FxHashMap;
2324
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};
2526
use rustc_serialize::{opaque, Encodable, Encoder, SpecializedEncoder};
2627

2728
use log::{debug, trace};
@@ -38,7 +39,7 @@ use syntax::expand::is_proc_macro_attr;
3839

3940
use rustc_hir as hir;
4041
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
41-
use rustc_hir::itemlikevisit::ItemLikeVisitor;
42+
use rustc_hir::itemlikevisit::{ItemLikeVisitor, ParItemLikeVisitor};
4243

4344
struct 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

Comments
 (0)