Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow for re-using monomorphizations in upstream crates. #48779

Merged
merged 16 commits into from
Apr 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
d3b5451
Fix incomplete ICH implementation for ty::subst::UnpackedKind.
michaelwoerister Mar 1, 2018
dad194a
Allow for representing exported monomorphizations in crate metadata.
michaelwoerister Mar 1, 2018
435477d
Move export level computation to reachable_non_generics query.
michaelwoerister Mar 6, 2018
4f6d05d
Allow for re-using monomorphizations from upstream crates.
michaelwoerister Mar 6, 2018
8d95c86
Make generics sharing the default for non-optimized builds.
michaelwoerister Mar 6, 2018
e203b3a
Remove the (inaccurate) symbol_export_level query.
michaelwoerister Mar 6, 2018
9b90674
Allow for internalizing monomorphizations that cannot be shared.
michaelwoerister Mar 6, 2018
5316a45
Adapt codegen-unit test to shared-generics.
michaelwoerister Mar 7, 2018
213ef11
Select upstream monomorphizations in a stable way.
michaelwoerister Mar 12, 2018
a1a986c
Fix some rebasing fallout.
michaelwoerister Mar 13, 2018
2d2cf03
Don't internalize generics that are re-exported
michaelwoerister Mar 13, 2018
94d36cf
Make sure that generics are internalized in executables even with -Zs…
michaelwoerister Mar 13, 2018
69c7f5c
Add codegen-units test for shared-generics.
michaelwoerister Mar 13, 2018
ec55390
Update a few comments about symbol visibility.
michaelwoerister Mar 14, 2018
07704a4
Allow for re-using hidden monomorphizations on platforms that don't s…
michaelwoerister Mar 21, 2018
61991a5
Update run-make/symbol-visibility to also cover shared-generics
michaelwoerister Mar 13, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/librustc/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,7 @@ define_dep_nodes!( <'tcx>
[] ImplParent(DefId),
[] TraitOfItem(DefId),
[] IsReachableNonGeneric(DefId),
[] IsUnreachableLocalDefinition(DefId),
[] IsMirAvailable(DefId),
[] ItemAttrs(DefId),
[] TransFnAttrs(DefId),
Expand Down Expand Up @@ -648,15 +649,16 @@ define_dep_nodes!( <'tcx>

[] InstanceDefSizeEstimate { instance_def: InstanceDef<'tcx> },

[] GetSymbolExportLevel(DefId),

[] WasmCustomSections(CrateNum),

[input] Features,

[] ProgramClausesFor(DefId),
[] WasmImportModuleMap(CrateNum),
[] ForeignModules(CrateNum),

[] UpstreamMonomorphizations(CrateNum),
[] UpstreamMonomorphizationsFor(DefId),
);

trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {
Expand Down
18 changes: 16 additions & 2 deletions src/librustc/ich/impls_ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,21 @@ for &'gcx ty::Slice<T>
}
}

impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
for ty::subst::Kind<'gcx> {
impl<'a, 'gcx, T> ToStableHashKey<StableHashingContext<'a>> for &'gcx ty::Slice<T>
where T: HashStable<StableHashingContext<'a>>
{
type KeyType = Fingerprint;

#[inline]
fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> Fingerprint {
let mut hasher = StableHasher::new();
let mut hcx: StableHashingContext<'a> = hcx.clone();
self.hash_stable(&mut hcx, &mut hasher);
hasher.finish()
}
}

impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ty::subst::Kind<'gcx> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
Expand All @@ -67,6 +80,7 @@ for ty::subst::UnpackedKind<'gcx> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
mem::discriminant(self).hash_stable(hcx, hasher);
match self {
ty::subst::UnpackedKind::Lifetime(lt) => lt.hash_stable(hcx, hasher),
ty::subst::UnpackedKind::Type(ty) => ty.hash_stable(hcx, hasher),
Expand Down
88 changes: 63 additions & 25 deletions src/librustc/middle/exported_symbols.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,13 @@
// except according to those terms.

use hir::def_id::{DefId, LOCAL_CRATE};
use ich::StableHashingContext;
use rustc_data_structures::stable_hasher::{StableHasher, HashStable,
StableHasherResult};
use std::cmp;
use std::mem;
use ty;
use ty::subst::Substs;

/// The SymbolExportLevel of a symbols specifies from which kinds of crates
/// the symbol will be exported. `C` symbols will be exported from any
Expand Down Expand Up @@ -40,56 +45,89 @@ impl SymbolExportLevel {
}

#[derive(Eq, PartialEq, Debug, Copy, Clone, RustcEncodable, RustcDecodable)]
pub enum ExportedSymbol {
pub enum ExportedSymbol<'tcx> {
NonGeneric(DefId),
Generic(DefId, &'tcx Substs<'tcx>),
NoDefId(ty::SymbolName),
}

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

pub fn compare_stable(&self, tcx: ty::TyCtxt, other: &ExportedSymbol) -> cmp::Ordering {
pub fn compare_stable(&self,
tcx: ty::TyCtxt<'_, 'tcx, '_>,
other: &ExportedSymbol<'tcx>)
-> 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::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::Generic(..) |
ExportedSymbol::NoDefId(_) => {
cmp::Ordering::Less
}
}
ExportedSymbol::Generic(..) => match *other {
ExportedSymbol::NonGeneric(_) => {
cmp::Ordering::Greater
}
ExportedSymbol::Generic(..) => {
self.symbol_name(tcx).cmp(&other.symbol_name(tcx))
}
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)
}
ExportedSymbol::NoDefId(self_symbol_name) => match *other {
ExportedSymbol::NonGeneric(_) |
ExportedSymbol::Generic(..) => {
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())
}

impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ExportedSymbol<'gcx> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
mem::discriminant(self).hash_stable(hcx, hasher);
match *self {
ExportedSymbol::NonGeneric(def_id) => {
def_id.hash_stable(hcx, hasher);
}
ExportedSymbol::Generic(def_id, substs) => {
def_id.hash_stable(hcx, hasher);
substs.hash_stable(hcx, hasher);
}
ExportedSymbol::NoDefId(symbol_name) => {
symbol_name.hash_stable(hcx, hasher);
}
}
}
}
2 changes: 2 additions & 0 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1304,6 +1304,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
"embed LLVM bitcode in object files"),
strip_debuginfo_if_disabled: Option<bool> = (None, parse_opt_bool, [TRACKED],
"tell the linker to strip debuginfo when building without debuginfo enabled."),
share_generics: Option<bool> = (None, parse_opt_bool, [TRACKED],
"make the current crate share its generic instantiations"),
}

pub fn default_lib_output() -> CrateType {
Expand Down
37 changes: 36 additions & 1 deletion src/librustc/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ use dep_graph::DepGraph;
use dep_graph::{DepNode, DepConstructor};
use errors::DiagnosticBuilder;
use session::Session;
use session::config::{BorrowckMode, OutputFilenames};
use session::config::{BorrowckMode, OutputFilenames, OptLevel};
use session::config::CrateType::*;
use middle;
use hir::{TraitCandidate, HirId, ItemLocalId};
use hir::def::{Def, Export};
Expand Down Expand Up @@ -1499,6 +1500,40 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
self.sess.opts.debugging_opts.mir_emit_validate > 0 ||
self.use_mir()
}

#[inline]
pub fn share_generics(self) -> bool {
match self.sess.opts.debugging_opts.share_generics {
Some(setting) => setting,
None => {
self.sess.opts.incremental.is_some() ||
match self.sess.opts.optimize {
OptLevel::No |
OptLevel::Less |
OptLevel::Size |
OptLevel::SizeMin => true,
OptLevel::Default |
OptLevel::Aggressive => false,
}
}
}
}

#[inline]
pub fn local_crate_exports_generics(self) -> bool {
debug_assert!(self.share_generics());

self.sess.crate_types.borrow().iter().any(|crate_type| {
match crate_type {
CrateTypeExecutable |
CrateTypeStaticlib |
CrateTypeProcMacro |
CrateTypeCdylib => false,
CrateTypeRlib |
CrateTypeDylib => true,
}
})
}
}

impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
Expand Down
6 changes: 6 additions & 0 deletions src/librustc/ty/maps/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::coherent_trait<'tcx> {
}
}

impl<'tcx> QueryDescription<'tcx> for queries::upstream_monomorphizations<'tcx> {
fn describe(_: TyCtxt, k: CrateNum) -> String {
format!("collecting available upstream monomorphizations `{:?}`", k)
}
}

impl<'tcx> QueryDescription<'tcx> for queries::crate_inherent_impls<'tcx> {
fn describe(_: TyCtxt, k: CrateNum) -> String {
format!("all inherent impls defined in crate `{:?}`", k)
Expand Down
11 changes: 8 additions & 3 deletions src/librustc/ty/maps/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,9 +319,15 @@ define_maps! { <'tcx>
//
// 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 reachable_non_generics: ReachableNonGenerics(CrateNum)
-> Lrc<DefIdMap<SymbolExportLevel>>,
[] fn is_reachable_non_generic: IsReachableNonGeneric(DefId) -> bool,
[] fn is_unreachable_local_definition: IsUnreachableLocalDefinition(DefId) -> bool,

[] fn upstream_monomorphizations: UpstreamMonomorphizations(CrateNum)
-> Lrc<DefIdMap<Lrc<FxHashMap<&'tcx Substs<'tcx>, CrateNum>>>>,
[] fn upstream_monomorphizations_for: UpstreamMonomorphizationsFor(DefId)
-> Option<Lrc<FxHashMap<&'tcx Substs<'tcx>, CrateNum>>>,

[] fn native_libraries: NativeLibraries(CrateNum) -> Lrc<Vec<NativeLibrary>>,

Expand Down Expand Up @@ -381,11 +387,10 @@ define_maps! { <'tcx>
[] fn all_crate_nums: all_crate_nums_node(CrateNum) -> Lrc<Vec<CrateNum>>,

[] fn exported_symbols: ExportedSymbols(CrateNum)
-> Arc<Vec<(ExportedSymbol, SymbolExportLevel)>>,
-> Arc<Vec<(ExportedSymbol<'tcx>, SymbolExportLevel)>>,
[] fn collect_and_partition_translation_items:
collect_and_partition_translation_items_node(CrateNum)
-> (Arc<DefIdSet>, Arc<Vec<Arc<CodegenUnit<'tcx>>>>),
[] fn symbol_export_level: GetSymbolExportLevel(DefId) -> SymbolExportLevel,
[] fn is_translated_item: IsTranslatedItem(DefId) -> bool,
[] fn codegen_unit: CodegenUnit(InternedString) -> Arc<CodegenUnit<'tcx>>,
[] fn compile_codegen_unit: CompileCodegenUnit(InternedString) -> Stats,
Expand Down
11 changes: 10 additions & 1 deletion src/librustc/ty/maps/plumbing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1003,6 +1003,9 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
DepKind::ImplParent => { force!(impl_parent, def_id!()); }
DepKind::TraitOfItem => { force!(trait_of_item, def_id!()); }
DepKind::IsReachableNonGeneric => { force!(is_reachable_non_generic, def_id!()); }
DepKind::IsUnreachableLocalDefinition => {
force!(is_unreachable_local_definition, def_id!());
}
DepKind::IsMirAvailable => { force!(is_mir_available, def_id!()); }
DepKind::ItemAttrs => { force!(item_attrs, def_id!()); }
DepKind::TransFnAttrs => { force!(trans_fn_attrs, def_id!()); }
Expand Down Expand Up @@ -1087,13 +1090,19 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,

DepKind::TargetFeaturesWhitelist => { force!(target_features_whitelist, LOCAL_CRATE); }

DepKind::GetSymbolExportLevel => { force!(symbol_export_level, def_id!()); }
DepKind::Features => { force!(features_query, LOCAL_CRATE); }

DepKind::ProgramClausesFor => { force!(program_clauses_for, def_id!()); }
DepKind::WasmCustomSections => { force!(wasm_custom_sections, krate!()); }
DepKind::WasmImportModuleMap => { force!(wasm_import_module_map, krate!()); }
DepKind::ForeignModules => { force!(foreign_modules, krate!()); }

DepKind::UpstreamMonomorphizations => {
force!(upstream_monomorphizations, krate!());
}
DepKind::UpstreamMonomorphizationsFor => {
force!(upstream_monomorphizations_for, def_id!());
}
}

true
Expand Down
6 changes: 3 additions & 3 deletions src/librustc_metadata/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,9 @@ provide! { <'tcx> tcx, def_id, other, cdata,
let reachable_non_generics = tcx
.exported_symbols(cdata.cnum)
.iter()
.filter_map(|&(exported_symbol, _)| {
.filter_map(|&(exported_symbol, export_level)| {
if let ExportedSymbol::NonGeneric(def_id) = exported_symbol {
return Some(def_id)
return Some((def_id, export_level))
} else {
None
}
Expand Down Expand Up @@ -268,7 +268,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
return Arc::new(Vec::new())
}

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

wasm_custom_sections => { Lrc::new(cdata.wasm_custom_sections()) }
Expand Down
12 changes: 7 additions & 5 deletions src/librustc_metadata/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1065,11 +1065,13 @@ impl<'a, 'tcx> CrateMetadata {
arg_names.decode(self).collect()
}

pub fn exported_symbols(&self) -> Vec<(ExportedSymbol, SymbolExportLevel)> {
self.root
.exported_symbols
.decode(self)
.collect()
pub fn exported_symbols(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>)
-> Vec<(ExportedSymbol<'tcx>, SymbolExportLevel)> {
let lazy_seq: LazySeq<(ExportedSymbol<'tcx>, SymbolExportLevel)> =
LazySeq::with_position_and_length(self.root.exported_symbols.position,
self.root.exported_symbols.len);
lazy_seq.decode((self, tcx)).collect()
}

pub fn wasm_custom_sections(&self) -> Vec<DefId> {
Expand Down
12 changes: 8 additions & 4 deletions src/librustc_metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1444,13 +1444,12 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
// definition (as that's not defined in this crate).
fn encode_exported_symbols(&mut self,
exported_symbols: &[(ExportedSymbol, SymbolExportLevel)])
-> LazySeq<(ExportedSymbol, SymbolExportLevel)> {

-> EncodedExportedSymbols {
// The metadata symbol name is special. It should not show up in
// downstream crates.
let metadata_symbol_name = SymbolName::new(&metadata_symbol_name(self.tcx));

self.lazy_seq(exported_symbols
let lazy_seq = self.lazy_seq(exported_symbols
.iter()
.filter(|&&(ref exported_symbol, _)| {
match *exported_symbol {
Expand All @@ -1460,7 +1459,12 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
_ => true,
}
})
.cloned())
.cloned());

EncodedExportedSymbols {
len: lazy_seq.len,
position: lazy_seq.position,
}
}

fn encode_wasm_custom_sections(&mut self, statics: &[DefId]) -> LazySeq<DefIndex> {
Expand Down
Loading