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

Polymorphize cont #6

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4242,6 +4242,8 @@ dependencies = [
"rustc_errors",
"rustc_hir",
"rustc_index",
"rustc_infer",
"rustc_macros",
"rustc_middle",
"rustc_session",
"rustc_span",
Expand Down
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
8 changes: 4 additions & 4 deletions compiler/rustc_codegen_ssa/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -874,7 +874,7 @@ impl CrateInfo {
}

pub fn provide(providers: &mut Providers) {
providers.backend_optimization_level = |tcx, cratenum| {
providers.backend_optimization_level = |tcx, ()| {
let for_speed = match tcx.sess.opts.optimize {
// If globally no optimisation is done, #[optimize] has no effect.
//
Expand All @@ -893,9 +893,9 @@ pub fn provide(providers: &mut Providers) {
config::OptLevel::SizeMin => config::OptLevel::Default,
};

let (defids, _) = tcx.collect_and_partition_mono_items(cratenum);
for id in &*defids {
let CodegenFnAttrs { optimize, .. } = tcx.codegen_fn_attrs(*id);
let (mono_items, _) = tcx.collect_and_partition_mono_items(());
for did in mono_items.def_id_iter() {
let CodegenFnAttrs { optimize, .. } = tcx.codegen_fn_attrs(did);
match optimize {
attr::OptimizeAttr::None => continue,
attr::OptimizeAttr::Size => continue,
Expand Down
23 changes: 23 additions & 0 deletions compiler/rustc_infer/src/infer/at.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,29 @@ impl<'tcx> ToTrace<'tcx> for &'tcx Const<'tcx> {
}
}

impl<'tcx> ToTrace<'tcx> for GenericArg<'tcx> {
fn to_trace(
tcx: TyCtxt<'tcx>,
cause: &ObligationCause<'tcx>,
a_is_expected: bool,
a: Self,
b: Self,
) -> TypeTrace<'tcx> {
match (a.unpack(), b.unpack()) {
(GenericArgKind::Lifetime(a), GenericArgKind::Lifetime(b)) => {
ToTrace::to_trace(tcx, cause, a_is_expected, a, b)
}
(GenericArgKind::Type(a), GenericArgKind::Type(b)) => {
ToTrace::to_trace(tcx, cause, a_is_expected, a, b)
}
(GenericArgKind::Const(a), GenericArgKind::Const(b)) => {
ToTrace::to_trace(tcx, cause, a_is_expected, a, b)
}
_ => bug!("generic arg mismatch: {:?} {:?}", a, b),
}
}
}

impl<'tcx> ToTrace<'tcx> for ty::TraitRef<'tcx> {
fn to_trace(
_: TyCtxt<'tcx>,
Expand Down
9 changes: 7 additions & 2 deletions compiler/rustc_infer/src/infer/combine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,13 +129,18 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> {
where
R: ConstEquateRelation<'tcx>,
{
let a = self.tcx.expose_default_const_substs(a);
let b = self.tcx.expose_default_const_substs(b);
let mut a = self.tcx.expose_default_const_substs(a);
let mut b = self.tcx.expose_default_const_substs(b);
debug!("{}.consts({:?}, {:?})", relation.tag(), a, b);
if a == b {
return Ok(a);
}

if a.ty != b.ty {
a = self.resolve_vars_if_possible(a);
b = self.resolve_vars_if_possible(b);
}

let a = replace_if_possible(&mut self.inner.borrow_mut().const_unification_table(), a);
let b = replace_if_possible(&mut self.inner.borrow_mut().const_unification_table(), b);

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ macro_rules! arena_types {
[] const_allocs: rustc_middle::mir::interpret::Allocation,
// Required for the incremental on-disk cache
[] mir_keys: rustc_hir::def_id::DefIdSet,
[few] mono_item_map: rustc_middle::mir::mono::MonoItemMap<'tcx>,
[] region_scope_tree: rustc_middle::middle::region::ScopeTree,
[] dropck_outlives:
rustc_middle::infer::canonical::Canonical<'tcx,
Expand Down
71 changes: 69 additions & 2 deletions compiler/rustc_middle/src/mir/mono.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use crate::dep_graph::{DepNode, WorkProduct, WorkProductId};
use crate::ty::{subst::InternalSubsts, Instance, InstanceDef, SymbolName, TyCtxt};
use crate::ty::subst::{InternalSubsts, SubstsRef};
use crate::ty::{Instance, InstanceDef, SymbolName, TyCtxt};
use rustc_attr::InlineAttr;
use rustc_data_structures::base_n;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use rustc_hir::{HirId, ItemId};
Expand Down Expand Up @@ -237,6 +238,72 @@ impl<'tcx> fmt::Display for MonoItem<'tcx> {
}
}

/// A map containing all monomorphized items of the current crate.
#[derive(Default, Debug, HashStable)]
pub struct MonoItemMap<'tcx> {
/// Items which are not generic functions.
///
/// we don't care about these wrt polymorphization,
/// so we can treat them in a far simpler way.
pub trivially_concrete: FxIndexSet<MonoItem<'tcx>>,
pub item_map: FxIndexMap<InstanceDef<'tcx>, Vec<SubstsRef<'tcx>>>,
}

impl MonoItemMap<'tcx> {
pub fn all_items<'a>(&'a self) -> impl Iterator<Item = MonoItem<'tcx>> + 'a {
self.trivially_concrete.iter().copied().chain(self.item_map.iter().flat_map(
|(&def, substs)| {
substs.iter().map(move |&substs| MonoItem::Fn(Instance { def, substs }))
},
))
}

pub fn def_id_iter<'a>(&'a self) -> impl Iterator<Item = DefId> + 'a {
self.trivially_concrete
.iter()
.filter_map(|&mono_item| match mono_item {
MonoItem::Fn(instance) => Some(instance.def_id()),
MonoItem::Static(def_id) => Some(def_id),
_ => None,
})
.chain(self.item_map.iter().map(|(&def, _)| def.def_id()))
}

pub fn contains(&self, item: MonoItem<'tcx>) -> bool {
match item {
MonoItem::Fn(instance) if item.is_generic_fn() => self
.item_map
.get(&instance.def)
.map_or(false, |substs| substs.contains(&instance.substs)),
MonoItem::Static(_) | MonoItem::GlobalAsm(_) | MonoItem::Fn(_) => {
self.trivially_concrete.contains(&item)
}
}
}

pub fn get_polymorphic_instance(
&self,
tcx: TyCtxt<'tcx>,
instance: Instance<'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() {
if substs == instance.substs
|| tcx.is_polymorphic_parent((instance.def, substs, instance.substs))
{
return Some(Instance { def: instance.def, substs });
}
}

None
} else if self.trivially_concrete.contains(&MonoItem::Fn(instance)) {
Some(instance)
} else {
None
}
}
}

#[derive(Debug)]
pub struct CodegenUnit<'tcx> {
/// A name for this CGU. Incremental compilation requires that
Expand Down
13 changes: 10 additions & 3 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 Expand Up @@ -1600,7 +1600,7 @@ rustc_queries! {
separate_provide_extern
}

query collect_and_partition_mono_items(_: ()) -> (&'tcx DefIdSet, &'tcx [CodegenUnit<'tcx>]) {
query collect_and_partition_mono_items(_: ()) -> (&'tcx MonoItemMap<'tcx>, &'tcx [CodegenUnit<'tcx>]) {
eval_always
desc { "collect_and_partition_mono_items" }
}
Expand All @@ -1625,6 +1625,13 @@ rustc_queries! {
}
separate_provide_extern
}
query is_polymorphic_parent(key: (ty::InstanceDef<'tcx>, SubstsRef<'tcx>, SubstsRef<'tcx>)) -> bool {
desc {
"checking whether `{:?}` is the polymorphic parent of {:?}",
key.1, key.2
}
}

query backend_optimization_level(_: ()) -> OptLevel {
desc { "optimization level used by backend" }
}
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1424,6 +1424,10 @@ impl<'tcx> TyCtxt<'tcx> {
features.generic_const_exprs
}

pub fn should_polymorphize(self) -> bool {
true
}

#[inline]
pub fn local_crate_exports_generics(self) -> bool {
debug_assert!(self.sess.opts.share_generics());
Expand Down
Loading