Skip to content

Commit 4f6d05d

Browse files
Allow for re-using monomorphizations from upstream crates.
1 parent 435477d commit 4f6d05d

File tree

13 files changed

+195
-38
lines changed

13 files changed

+195
-38
lines changed

src/librustc/dep_graph/dep_node.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,9 @@ define_dep_nodes!( <'tcx>
657657
[] ProgramClausesFor(DefId),
658658
[] WasmImportModuleMap(CrateNum),
659659
[] ForeignModules(CrateNum),
660+
661+
[] UpstreamMonomorphizations(CrateNum),
662+
[] UpstreamMonomorphizationsFor(DefId),
660663
);
661664

662665
trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {

src/librustc/ich/impls_ty.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,21 @@ for &'gcx ty::Slice<T>
5353
}
5454
}
5555

56-
impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
57-
for ty::subst::Kind<'gcx> {
56+
impl<'a, 'gcx, T> ToStableHashKey<StableHashingContext<'a>> for &'gcx ty::Slice<T>
57+
where T: HashStable<StableHashingContext<'a>>
58+
{
59+
type KeyType = Fingerprint;
60+
61+
#[inline]
62+
fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> Fingerprint {
63+
let mut hasher = StableHasher::new();
64+
let mut hcx: StableHashingContext<'a> = hcx.clone();
65+
self.hash_stable(&mut hcx, &mut hasher);
66+
hasher.finish()
67+
}
68+
}
69+
70+
impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ty::subst::Kind<'gcx> {
5871
fn hash_stable<W: StableHasherResult>(&self,
5972
hcx: &mut StableHashingContext<'a>,
6073
hasher: &mut StableHasher<W>) {

src/librustc/session/config.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,6 +1304,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
13041304
"embed LLVM bitcode in object files"),
13051305
strip_debuginfo_if_disabled: Option<bool> = (None, parse_opt_bool, [TRACKED],
13061306
"tell the linker to strip debuginfo when building without debuginfo enabled."),
1307+
share_generics: Option<bool> = (None, parse_opt_bool, [TRACKED],
1308+
"make the current crate share its generic instantiations"),
13071309
}
13081310

13091311
pub fn default_lib_output() -> CrateType {

src/librustc/ty/context.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1499,6 +1499,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
14991499
self.sess.opts.debugging_opts.mir_emit_validate > 0 ||
15001500
self.use_mir()
15011501
}
1502+
1503+
#[inline]
1504+
pub fn share_generics(self) -> bool {
1505+
match self.sess.opts.debugging_opts.share_generics {
1506+
Some(true) => true,
1507+
Some(false) | None => false,
1508+
}
1509+
}
15021510
}
15031511

15041512
impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {

src/librustc/ty/maps/config.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::coherent_trait<'tcx> {
131131
}
132132
}
133133

134+
impl<'tcx> QueryDescription<'tcx> for queries::upstream_monomorphizations<'tcx> {
135+
fn describe(_: TyCtxt, k: CrateNum) -> String {
136+
format!("collecting available upstream monomorphizations `{:?}`", k)
137+
}
138+
}
139+
134140
impl<'tcx> QueryDescription<'tcx> for queries::crate_inherent_impls<'tcx> {
135141
fn describe(_: TyCtxt, k: CrateNum) -> String {
136142
format!("all inherent impls defined in crate `{:?}`", k)

src/librustc/ty/maps/mod.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,9 +319,14 @@ define_maps! { <'tcx>
319319
//
320320
// Does not include external symbols that don't have a corresponding DefId,
321321
// like the compiler-generated `main` function and so on.
322-
[] fn reachable_non_generics: ReachableNonGenerics(CrateNum) -> Lrc<DefIdSet>,
322+
[] fn reachable_non_generics: ReachableNonGenerics(CrateNum)
323+
-> Lrc<DefIdMap<SymbolExportLevel>>,
323324
[] fn is_reachable_non_generic: IsReachableNonGeneric(DefId) -> bool,
324325

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

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

src/librustc/ty/maps/plumbing.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,6 +1094,13 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
10941094
DepKind::WasmCustomSections => { force!(wasm_custom_sections, krate!()); }
10951095
DepKind::WasmImportModuleMap => { force!(wasm_import_module_map, krate!()); }
10961096
DepKind::ForeignModules => { force!(foreign_modules, krate!()); }
1097+
1098+
DepKind::UpstreamMonomorphizations => {
1099+
force!(upstream_monomorphizations, krate!());
1100+
}
1101+
DepKind::UpstreamMonomorphizationsFor => {
1102+
force!(upstream_monomorphizations_for, def_id!());
1103+
}
10971104
}
10981105

10991106
true

src/librustc_metadata/cstore_impl.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,9 +186,9 @@ provide! { <'tcx> tcx, def_id, other, cdata,
186186
let reachable_non_generics = tcx
187187
.exported_symbols(cdata.cnum)
188188
.iter()
189-
.filter_map(|&(exported_symbol, _)| {
189+
.filter_map(|&(exported_symbol, export_level)| {
190190
if let ExportedSymbol::NonGeneric(def_id) = exported_symbol {
191-
return Some(def_id)
191+
return Some((def_id, export_level))
192192
} else {
193193
None
194194
}

src/librustc_mir/monomorphize/collector.rs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,9 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
569569
ty::TyClosure(def_id, substs) => {
570570
let instance = monomorphize::resolve_closure(
571571
self.tcx, def_id, substs, ty::ClosureKind::FnOnce);
572-
self.output.push(create_fn_mono_item(instance));
572+
if should_monomorphize_locally(self.tcx, &instance) {
573+
self.output.push(create_fn_mono_item(instance));
574+
}
573575
}
574576
_ => bug!(),
575577
}
@@ -731,14 +733,16 @@ fn should_monomorphize_locally<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance:
731733
ty::InstanceDef::Intrinsic(_) |
732734
ty::InstanceDef::CloneShim(..) => return true
733735
};
734-
match tcx.hir.get_if_local(def_id) {
736+
737+
return match tcx.hir.get_if_local(def_id) {
735738
Some(hir_map::NodeForeignItem(..)) => {
736739
false // foreign items are linked against, not translated.
737740
}
738741
Some(_) => true,
739742
None => {
740743
if tcx.is_reachable_non_generic(def_id) ||
741-
tcx.is_foreign_item(def_id)
744+
tcx.is_foreign_item(def_id) ||
745+
is_available_upstream_generic(tcx, def_id, instance.substs)
742746
{
743747
// We can link to the item in question, no instance needed
744748
// in this crate
@@ -750,6 +754,25 @@ fn should_monomorphize_locally<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance:
750754
true
751755
}
752756
}
757+
};
758+
759+
fn is_available_upstream_generic<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
760+
def_id: DefId,
761+
substs: &'tcx Substs<'tcx>)
762+
-> bool {
763+
debug_assert!(!def_id.is_local());
764+
765+
if !tcx.share_generics() {
766+
return false
767+
}
768+
769+
if substs.types().next().is_none() {
770+
return false
771+
}
772+
773+
tcx.upstream_monomorphizations_for(def_id)
774+
.map(|set| set.contains_key(substs))
775+
.unwrap_or(false)
753776
}
754777
}
755778

src/librustc_mir/monomorphize/partitioning.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
301301
let mut codegen_units = FxHashMap();
302302
let is_incremental_build = tcx.sess.opts.incremental.is_some();
303303
let mut internalization_candidates = FxHashSet();
304+
let share_generics = tcx.share_generics();
304305

305306
for trans_item in trans_items {
306307
match trans_item.instantiation_mode(tcx) {
@@ -362,6 +363,13 @@ fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
362363
if tcx.lang_items().start_fn() == Some(def_id) {
363364
can_be_internalized = false;
364365
Visibility::Hidden
366+
} else if instance.substs.types().next().is_some() {
367+
if share_generics {
368+
can_be_internalized = false;
369+
Visibility::Default
370+
} else {
371+
Visibility::Hidden
372+
}
365373
} else if def_id.is_local() {
366374
if tcx.is_reachable_non_generic(def_id) {
367375
can_be_internalized = false;

0 commit comments

Comments
 (0)