Skip to content

Commit

Permalink
cross crate polymorphization
Browse files Browse the repository at this point in the history
  • Loading branch information
lcnr committed Dec 9, 2021
1 parent ccb1eae commit 47ebc3d
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 15 deletions.
26 changes: 20 additions & 6 deletions compiler/rustc_codegen_ssa/src/back/symbol_export.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::collections::hash_map::Entry::*;
use std::collections::btree_map::Entry::*;
use std::collections::BTreeMap;

use rustc_ast::expand::allocator::ALLOCATOR_METHODS;
use rustc_data_structures::fingerprint::Fingerprint;
Expand All @@ -14,7 +15,7 @@ use rustc_middle::middle::exported_symbols::{
use rustc_middle::ty::query::{ExternProviders, Providers};
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
use rustc_middle::ty::Instance;
use rustc_middle::ty::{SymbolName, TyCtxt};
use rustc_middle::ty::{self, SymbolName, TyCtxt};
use rustc_session::config::CrateType;
use rustc_target::spec::SanitizerSet;

Expand Down Expand Up @@ -272,10 +273,10 @@ fn exported_symbols_provider_local(
fn upstream_monomorphizations_provider(
tcx: TyCtxt<'_>,
(): (),
) -> DefIdMap<FxHashMap<SubstsRef<'_>, CrateNum>> {
) -> DefIdMap<BTreeMap<SubstsRef<'_>, CrateNum>> {
let cnums = tcx.crates(());

let mut instances: DefIdMap<FxHashMap<_, _>> = Default::default();
let mut instances: DefIdMap<BTreeMap<_, _>> = Default::default();

let cnum_stable_ids: IndexVec<CrateNum, Fingerprint> = {
let mut cnum_stable_ids = IndexVec::from_elem_n(Fingerprint::ZERO, cnums.len() + 1);
Expand Down Expand Up @@ -333,7 +334,7 @@ fn upstream_monomorphizations_provider(
fn upstream_monomorphizations_for_provider(
tcx: TyCtxt<'_>,
def_id: DefId,
) -> Option<&FxHashMap<SubstsRef<'_>, CrateNum>> {
) -> Option<&BTreeMap<SubstsRef<'_>, CrateNum>> {
debug_assert!(!def_id.is_local());
tcx.upstream_monomorphizations(()).get(&def_id)
}
Expand All @@ -343,7 +344,20 @@ fn upstream_drop_glue_for_provider<'tcx>(
substs: SubstsRef<'tcx>,
) -> Option<CrateNum> {
if let Some(def_id) = tcx.lang_items().drop_in_place_fn() {
tcx.upstream_monomorphizations_for(def_id).and_then(|monos| monos.get(&substs).cloned())
tcx.upstream_monomorphizations_for(def_id).and_then(|monos| {
monos.get(&substs).cloned().or_else(|| {
monos
.iter()
.find(|(k, _)| {
tcx.is_polymorphic_parent((
ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)),
k,
substs,
))
})
.map(|(_, &v)| v)
})
})
} else {
None
}
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_middle/src/mir/mono.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,6 @@ impl MonoItemMap<'tcx> {
) -> Option<Instance<'tcx>> {
if instance.substs.non_erasable_generics().next().is_some() {
for substs in self.item_map.get(&instance.def).into_iter().flat_map(|v| v).copied() {
// FIXME(polymorphization): Deal with more complex polymorphized stuff.
if substs == instance.substs
|| tcx.is_polymorphic_parent((instance.def, substs, instance.substs))
{
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1307,7 +1307,7 @@ rustc_queries! {
/// added or removed in any upstream crate. Instead use the narrower
/// `upstream_monomorphizations_for`, `upstream_drop_glue_for`, or, even
/// better, `Instance::upstream_monomorphization()`.
query upstream_monomorphizations(_: ()) -> DefIdMap<FxHashMap<SubstsRef<'tcx>, CrateNum>> {
query upstream_monomorphizations(_: ()) -> DefIdMap<BTreeMap<SubstsRef<'tcx>, CrateNum>> {
storage(ArenaCacheSelector<'tcx>)
desc { "collecting available upstream monomorphizations" }
}
Expand All @@ -1320,7 +1320,7 @@ rustc_queries! {
/// You likely want to call `Instance::upstream_monomorphization()`
/// instead of invoking this query directly.
query upstream_monomorphizations_for(def_id: DefId)
-> Option<&'tcx FxHashMap<SubstsRef<'tcx>, CrateNum>> {
-> Option<&'tcx BTreeMap<SubstsRef<'tcx>, CrateNum>> {
desc { |tcx|
"collecting available upstream monomorphizations for `{}`",
tcx.def_path_str(def_id),
Expand Down
28 changes: 22 additions & 6 deletions compiler/rustc_middle/src/ty/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,16 @@ impl<'tcx> Instance<'tcx> {
self.substs.non_erasable_generics().next()?;

match self.def {
// FIXME(polymorphization): Deal with this. Can't use
// `polymorphize` as that causes cycles.
InstanceDef::Item(def) => tcx
.upstream_monomorphizations_for(def.did)
.and_then(|monos| monos.get(&self.substs).cloned()),
InstanceDef::Item(def) => {
tcx.upstream_monomorphizations_for(def.did).and_then(|monos| {
monos.get(&self.substs).cloned().or_else(|| {
monos
.iter()
.find(|(k, _)| tcx.is_polymorphic_parent((self.def, k, self.substs)))
.map(|(_, &v)| v)
})
})
}
InstanceDef::DropGlue(_, Some(_)) => tcx.upstream_drop_glue_for(self.substs),
_ => None,
}
Expand Down Expand Up @@ -594,7 +599,18 @@ impl<'tcx> Instance<'tcx> {
// polymorphic instances from separate crates,
// and assume that we just have a mono item for this
// instance in some other crate.
None => self,
None => match self.def {
InstanceDef::Item(def) if !def.is_local() => tcx
.upstream_monomorphizations_for(def.did)
.and_then(|monos| {
monos
.iter()
.find(|(k, _)| tcx.is_polymorphic_parent((self.def, k, self.substs)))
.map(|(k, _)| Instance { def: self.def, substs: k })
})
.unwrap_or(self),
_ => self,
},
}
}
}
Expand Down

0 comments on commit 47ebc3d

Please sign in to comment.