Skip to content

Commit

Permalink
Auto merge of #48611 - michaelwoerister:share-generics2, r=alexcrichton
Browse files Browse the repository at this point in the history
Don't recompute SymbolExportLevel for upstream crates.

The data collected in #48373 suggests that we can avoid generating up to 30% of the LLVM definitions by only instantiating function monomorphizations once with a given crate graph. Some more data, collected with a [proof-of-concept implementation](https://github.com/michaelwoerister/rust/commits/share-generics) of re-using monomorphizations, which is less efficient than the MIR-only RLIB approach, suggests that it's still around 25% LLVM definitions that we can save.

So far, this PR only cleans up handling of symbol export status. Too early to review still.
  • Loading branch information
bors committed Mar 6, 2018
2 parents 6f2100b + f5ab4d4 commit b977e04
Show file tree
Hide file tree
Showing 26 changed files with 413 additions and 271 deletions.
4 changes: 2 additions & 2 deletions src/librustc/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ define_dep_nodes!( <'tcx>
[] RvaluePromotableMap(DefId),
[] ImplParent(DefId),
[] TraitOfItem(DefId),
[] IsExportedSymbol(DefId),
[] IsReachableNonGeneric(DefId),
[] IsMirAvailable(DefId),
[] ItemAttrs(DefId),
[] FnArgNames(DefId),
Expand All @@ -574,7 +574,7 @@ define_dep_nodes!( <'tcx>
[] GetPanicStrategy(CrateNum),
[] IsNoBuiltins(CrateNum),
[] ImplDefaultness(DefId),
[] ExportedSymbolIds(CrateNum),
[] ReachableNonGenerics(CrateNum),
[] NativeLibraries(CrateNum),
[] PluginRegistrarFn(CrateNum),
[] DeriveRegistrarFn(CrateNum),
Expand Down
7 changes: 2 additions & 5 deletions src/librustc/middle/cstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ use ich;
use ty::{self, TyCtxt};
use session::{Session, CrateDisambiguator};
use session::search_paths::PathKind;
use util::nodemap::NodeSet;

use std::any::Any;
use std::collections::BTreeMap;
Expand Down Expand Up @@ -258,8 +257,7 @@ pub trait CrateStore {
// utility functions
fn encode_metadata<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
link_meta: &LinkMeta,
reachable: &NodeSet)
link_meta: &LinkMeta)
-> EncodedMetadata;
fn metadata_encoding_version(&self) -> &[u8];
}
Expand Down Expand Up @@ -342,8 +340,7 @@ impl CrateStore for DummyCrateStore {
fn extern_mod_stmt_cnum_untracked(&self, emod_id: ast::NodeId) -> Option<CrateNum> { None }
fn encode_metadata<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
link_meta: &LinkMeta,
reachable: &NodeSet)
link_meta: &LinkMeta)
-> EncodedMetadata {
bug!("encode_metadata")
}
Expand Down
61 changes: 60 additions & 1 deletion src/librustc/middle/exported_symbols.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use hir::def_id::{DefId, LOCAL_CRATE};
use std::cmp;
use ty;

/// The SymbolExportLevel of a symbols specifies from which kinds of crates
/// the symbol will be exported. `C` symbols will be exported from any
/// kind of crate, including cdylibs which export very few things.
/// `Rust` will only be exported if the crate produced is a Rust
/// dylib.
#[derive(Eq, PartialEq, Debug, Copy, Clone)]
#[derive(Eq, PartialEq, Debug, Copy, Clone, RustcEncodable, RustcDecodable)]
pub enum SymbolExportLevel {
C,
Rust,
Expand All @@ -34,3 +38,58 @@ impl SymbolExportLevel {
}
}
}

#[derive(Eq, PartialEq, Debug, Copy, Clone, RustcEncodable, RustcDecodable)]
pub enum ExportedSymbol {
NonGeneric(DefId),
NoDefId(ty::SymbolName),
}

impl ExportedSymbol {
pub fn symbol_name(&self, tcx: ty::TyCtxt) -> ty::SymbolName {
match *self {
ExportedSymbol::NonGeneric(def_id) => {
tcx.symbol_name(ty::Instance::mono(tcx, def_id))
}
ExportedSymbol::NoDefId(symbol_name) => {
symbol_name
}
}
}

pub fn compare_stable(&self, tcx: ty::TyCtxt, other: &ExportedSymbol) -> cmp::Ordering {
match *self {
ExportedSymbol::NonGeneric(self_def_id) => {
match *other {
ExportedSymbol::NonGeneric(other_def_id) => {
tcx.def_path_hash(self_def_id).cmp(&tcx.def_path_hash(other_def_id))
}
ExportedSymbol::NoDefId(_) => {
cmp::Ordering::Less
}
}
}
ExportedSymbol::NoDefId(self_symbol_name) => {
match *other {
ExportedSymbol::NonGeneric(_) => {
cmp::Ordering::Greater
}
ExportedSymbol::NoDefId(ref other_symbol_name) => {
self_symbol_name.cmp(other_symbol_name)
}
}
}
}
}
}

impl_stable_hash_for!(enum self::ExportedSymbol {
NonGeneric(def_id),
NoDefId(symbol_name)
});

pub fn metadata_symbol_name(tcx: ty::TyCtxt) -> String {
format!("rust_metadata_{}_{}",
tcx.original_crate_name(LOCAL_CRATE),
tcx.crate_disambiguator(LOCAL_CRATE).to_fingerprint().to_hex())
}
14 changes: 11 additions & 3 deletions src/librustc/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ use ty::layout::{LayoutDetails, TargetDataLayout};
use ty::maps;
use ty::steal::Steal;
use ty::BindingMode;
use util::nodemap::{NodeMap, NodeSet, DefIdSet, ItemLocalMap};
use util::nodemap::{NodeMap, DefIdSet, ItemLocalMap};
use util::nodemap::{FxHashMap, FxHashSet};
use rustc_data_structures::accumulate_vec::AccumulateVec;
use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap,
Expand Down Expand Up @@ -1417,10 +1417,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}

impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
pub fn encode_metadata(self, link_meta: &LinkMeta, reachable: &NodeSet)
pub fn encode_metadata(self, link_meta: &LinkMeta)
-> EncodedMetadata
{
self.cstore.encode_metadata(self, link_meta, reachable)
self.cstore.encode_metadata(self, link_meta)
}
}

Expand Down Expand Up @@ -2460,4 +2460,12 @@ pub fn provide(providers: &mut ty::maps::Providers) {
assert_eq!(cnum, LOCAL_CRATE);
Lrc::new(tcx.sess.features_untracked().clone())
};
providers.is_panic_runtime = |tcx, cnum| {
assert_eq!(cnum, LOCAL_CRATE);
attr::contains_name(tcx.hir.krate_attrs(), "panic_runtime")
};
providers.is_compiler_builtins = |tcx, cnum| {
assert_eq!(cnum, LOCAL_CRATE);
attr::contains_name(tcx.hir.krate_attrs(), "compiler_builtins")
};
}
6 changes: 3 additions & 3 deletions src/librustc/ty/maps/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,9 +212,9 @@ impl<'tcx> QueryDescription<'tcx> for queries::item_attrs<'tcx> {
}
}

impl<'tcx> QueryDescription<'tcx> for queries::is_exported_symbol<'tcx> {
impl<'tcx> QueryDescription<'tcx> for queries::is_reachable_non_generic<'tcx> {
fn describe(_: TyCtxt, _: DefId) -> String {
bug!("is_exported_symbol")
bug!("is_reachable_non_generic")
}
}

Expand Down Expand Up @@ -383,7 +383,7 @@ impl<'tcx> QueryDescription<'tcx> for queries::is_sanitizer_runtime<'tcx> {
}
}

impl<'tcx> QueryDescription<'tcx> for queries::exported_symbol_ids<'tcx> {
impl<'tcx> QueryDescription<'tcx> for queries::reachable_non_generics<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("looking up the exported symbols of a crate")
}
Expand Down
23 changes: 19 additions & 4 deletions src/librustc/ty/maps/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use middle::region;
use middle::resolve_lifetime::{ResolveLifetimes, Region, ObjectLifetimeDefault};
use middle::stability::{self, DeprecationEntry};
use middle::lang_items::{LanguageItems, LangItem};
use middle::exported_symbols::SymbolExportLevel;
use middle::exported_symbols::{SymbolExportLevel, ExportedSymbol};
use mir::mono::{CodegenUnit, Stats};
use mir;
use session::{CompileResult, CrateDisambiguator};
Expand Down Expand Up @@ -238,7 +238,6 @@ define_maps! { <'tcx>
[] fn fn_arg_names: FnArgNames(DefId) -> Vec<ast::Name>,
[] fn impl_parent: ImplParent(DefId) -> Option<DefId>,
[] fn trait_of_item: TraitOfItem(DefId) -> Option<DefId>,
[] fn is_exported_symbol: IsExportedSymbol(DefId) -> bool,
[] fn item_body_nested_bodies: ItemBodyNestedBodies(DefId) -> ExternBodyNestedBodies,
[] fn const_is_rvalue_promotable_to_static: ConstIsRvaluePromotableToStatic(DefId) -> bool,
[] fn rvalue_promotable_map: RvaluePromotableMap(DefId) -> Lrc<ItemLocalSet>,
Expand Down Expand Up @@ -290,7 +289,23 @@ define_maps! { <'tcx>
[] fn lint_levels: lint_levels_node(CrateNum) -> Lrc<lint::LintLevelMap>,

[] fn impl_defaultness: ImplDefaultness(DefId) -> hir::Defaultness,
[] fn exported_symbol_ids: ExportedSymbolIds(CrateNum) -> Lrc<DefIdSet>,

// The DefIds of all non-generic functions and statics in the given crate
// that can be reached from outside the crate.
//
// We expect this items to be available for being linked to.
//
// This query can also be called for LOCAL_CRATE. In this case it will
// compute which items will be reachable to other crates, taking into account
// the kind of crate that is currently compiled. Crates with only a
// C interface have fewer reachable things.
//
// Does not include external symbols that don't have a corresponding DefId,
// like the compiler-generated `main` function and so on.
[] fn reachable_non_generics: ReachableNonGenerics(CrateNum) -> Lrc<DefIdSet>,
[] fn is_reachable_non_generic: IsReachableNonGeneric(DefId) -> bool,


[] fn native_libraries: NativeLibraries(CrateNum) -> Lrc<Vec<NativeLibrary>>,
[] fn plugin_registrar_fn: PluginRegistrarFn(CrateNum) -> Option<DefId>,
[] fn derive_registrar_fn: DeriveRegistrarFn(CrateNum) -> Option<DefId>,
Expand Down Expand Up @@ -343,7 +358,7 @@ define_maps! { <'tcx>
[] fn all_crate_nums: all_crate_nums_node(CrateNum) -> Lrc<Vec<CrateNum>>,

[] fn exported_symbols: ExportedSymbols(CrateNum)
-> Arc<Vec<(String, Option<DefId>, SymbolExportLevel)>>,
-> Arc<Vec<(ExportedSymbol, SymbolExportLevel)>>,
[] fn collect_and_partition_translation_items:
collect_and_partition_translation_items_node(CrateNum)
-> (Arc<DefIdSet>, Arc<Vec<Arc<CodegenUnit<'tcx>>>>),
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/ty/maps/plumbing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -851,7 +851,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
DepKind::RvaluePromotableMap => { force!(rvalue_promotable_map, def_id!()); }
DepKind::ImplParent => { force!(impl_parent, def_id!()); }
DepKind::TraitOfItem => { force!(trait_of_item, def_id!()); }
DepKind::IsExportedSymbol => { force!(is_exported_symbol, def_id!()); }
DepKind::IsReachableNonGeneric => { force!(is_reachable_non_generic, def_id!()); }
DepKind::IsMirAvailable => { force!(is_mir_available, def_id!()); }
DepKind::ItemAttrs => { force!(item_attrs, def_id!()); }
DepKind::FnArgNames => { force!(fn_arg_names, def_id!()); }
Expand All @@ -868,7 +868,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
DepKind::GetPanicStrategy => { force!(panic_strategy, krate!()); }
DepKind::IsNoBuiltins => { force!(is_no_builtins, krate!()); }
DepKind::ImplDefaultness => { force!(impl_defaultness, def_id!()); }
DepKind::ExportedSymbolIds => { force!(exported_symbol_ids, krate!()); }
DepKind::ReachableNonGenerics => { force!(reachable_non_generics, krate!()); }
DepKind::NativeLibraries => { force!(native_libraries, krate!()); }
DepKind::PluginRegistrarFn => { force!(plugin_registrar_fn, krate!()); }
DepKind::DeriveRegistrarFn => { force!(derive_registrar_fn, krate!()); }
Expand Down
16 changes: 15 additions & 1 deletion src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2806,7 +2806,7 @@ impl<'tcx> DtorckConstraint<'tcx> {
}
}

#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable)]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable)]
pub struct SymbolName {
// FIXME: we don't rely on interning or equality here - better have
// this be a `&'tcx str`.
Expand All @@ -2817,6 +2817,14 @@ impl_stable_hash_for!(struct self::SymbolName {
name
});

impl SymbolName {
pub fn new(name: &str) -> SymbolName {
SymbolName {
name: Symbol::intern(name).as_str()
}
}
}

impl Deref for SymbolName {
type Target = str;

Expand All @@ -2828,3 +2836,9 @@ impl fmt::Display for SymbolName {
fmt::Display::fmt(&self.name, fmt)
}
}

impl fmt::Debug for SymbolName {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&self.name, fmt)
}
}
4 changes: 0 additions & 4 deletions src/librustc_metadata/creader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,9 +225,6 @@ impl<'a> CrateLoader<'a> {
crate_root.def_path_table.decode((&metadata, self.sess))
});

let exported_symbols = crate_root.exported_symbols
.decode((&metadata, self.sess))
.collect();
let trait_impls = crate_root
.impls
.decode((&metadata, self.sess))
Expand All @@ -238,7 +235,6 @@ impl<'a> CrateLoader<'a> {
name,
extern_crate: Cell::new(None),
def_path_table: Lrc::new(def_path_table),
exported_symbols,
trait_impls,
proc_macros: crate_root.macro_derive_registrar.map(|_| {
self.load_derive_macros(&crate_root, dylib.clone().map(|p| p.0), span)
Expand Down
2 changes: 0 additions & 2 deletions src/librustc_metadata/cstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,6 @@ pub struct CrateMetadata {
/// compilation support.
pub def_path_table: Lrc<DefPathTable>,

pub exported_symbols: FxHashSet<DefIndex>,

pub trait_impls: FxHashMap<(u32, DefIndex), schema::LazySeq<DefIndex>>,

pub dep_kind: Cell<DepKind>,
Expand Down
41 changes: 33 additions & 8 deletions src/librustc_metadata/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use rustc::ty::maps::QueryConfig;
use rustc::middle::cstore::{CrateStore, DepKind,
MetadataLoader, LinkMeta,
LoadedMacro, EncodedMetadata, NativeLibraryKind};
use rustc::middle::exported_symbols::ExportedSymbol;
use rustc::middle::stability::DeprecationEntry;
use rustc::hir::def;
use rustc::session::{CrateDisambiguator, Session};
Expand All @@ -27,10 +28,11 @@ use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE, CRATE_DEF_INDEX};
use rustc::hir::map::{DefKey, DefPath, DefPathHash};
use rustc::hir::map::blocks::FnLikeNode;
use rustc::hir::map::definitions::DefPathTable;
use rustc::util::nodemap::{NodeSet, DefIdMap};
use rustc::util::nodemap::DefIdMap;

use std::any::Any;
use rustc_data_structures::sync::Lrc;
use std::sync::Arc;

use syntax::ast;
use syntax::attr;
Expand Down Expand Up @@ -160,9 +162,6 @@ provide! { <'tcx> tcx, def_id, other, cdata,
fn_arg_names => { cdata.get_fn_arg_names(def_id.index) }
impl_parent => { cdata.get_parent_impl(def_id.index) }
trait_of_item => { cdata.get_trait_of_item(def_id.index) }
is_exported_symbol => {
cdata.exported_symbols.contains(&def_id.index)
}
item_body_nested_bodies => { cdata.item_body_nested_bodies(def_id.index) }
const_is_rvalue_promotable_to_static => {
cdata.const_is_rvalue_promotable_to_static(def_id.index)
Expand All @@ -179,7 +178,21 @@ provide! { <'tcx> tcx, def_id, other, cdata,
extern_crate => { Lrc::new(cdata.extern_crate.get()) }
is_no_builtins => { cdata.is_no_builtins(tcx.sess) }
impl_defaultness => { cdata.get_impl_defaultness(def_id.index) }
exported_symbol_ids => { Lrc::new(cdata.get_exported_symbols()) }
reachable_non_generics => {
let reachable_non_generics = tcx
.exported_symbols(cdata.cnum)
.iter()
.filter_map(|&(exported_symbol, _)| {
if let ExportedSymbol::NonGeneric(def_id) = exported_symbol {
return Some(def_id)
} else {
None
}
})
.collect();

Lrc::new(reachable_non_generics)
}
native_libraries => { Lrc::new(cdata.get_native_libraries(tcx.sess)) }
plugin_registrar_fn => {
cdata.root.plugin_registrar_fn.map(|index| {
Expand Down Expand Up @@ -238,6 +251,19 @@ provide! { <'tcx> tcx, def_id, other, cdata,

has_copy_closures => { cdata.has_copy_closures(tcx.sess) }
has_clone_closures => { cdata.has_clone_closures(tcx.sess) }

exported_symbols => {
let cnum = cdata.cnum;
assert!(cnum != LOCAL_CRATE);

// If this crate is a custom derive crate, then we're not even going to
// link those in so we skip those crates.
if cdata.root.macro_derive_registrar.is_some() {
return Arc::new(Vec::new())
}

Arc::new(cdata.exported_symbols())
}
}

pub fn provide<'tcx>(providers: &mut Providers<'tcx>) {
Expand Down Expand Up @@ -520,11 +546,10 @@ impl CrateStore for cstore::CStore {

fn encode_metadata<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
link_meta: &LinkMeta,
reachable: &NodeSet)
link_meta: &LinkMeta)
-> EncodedMetadata
{
encoder::encode_metadata(tcx, link_meta, reachable)
encoder::encode_metadata(tcx, link_meta)
}

fn metadata_encoding_version(&self) -> &[u8]
Expand Down
Loading

0 comments on commit b977e04

Please sign in to comment.