rustc: Remove another global map from trans
This commit removes the `crate_trans_items` field from the `CrateContext` of trans. This field, a big map, was calculated during partioning and was a set of all translation items. This isn't quite incremental-friendly because the map may change a lot but not have much effect on downstream consumers. Instead a new query was added for the one location this map was needed, along with a new comment explaining what the location is doing!
This commit is contained in:
parent
19727c84dd
commit
2eada58706
@ -579,6 +579,7 @@ define_dep_nodes!( <'tcx>
|
|||||||
[] CollectAndPartitionTranslationItems,
|
[] CollectAndPartitionTranslationItems,
|
||||||
[] ExportName(DefId),
|
[] ExportName(DefId),
|
||||||
[] ContainsExternIndicator(DefId),
|
[] ContainsExternIndicator(DefId),
|
||||||
|
[] IsTranslatedFunction(DefId),
|
||||||
);
|
);
|
||||||
|
|
||||||
trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {
|
trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {
|
||||||
|
@ -24,7 +24,7 @@ use middle::resolve_lifetime::{Region, ObjectLifetimeDefault};
|
|||||||
use middle::stability::{self, DeprecationEntry};
|
use middle::stability::{self, DeprecationEntry};
|
||||||
use middle::lang_items::{LanguageItems, LangItem};
|
use middle::lang_items::{LanguageItems, LangItem};
|
||||||
use middle::exported_symbols::SymbolExportLevel;
|
use middle::exported_symbols::SymbolExportLevel;
|
||||||
use middle::trans::{TransItem, CodegenUnit};
|
use middle::trans::CodegenUnit;
|
||||||
use mir;
|
use mir;
|
||||||
use mir::transform::{MirSuite, MirPassIndex};
|
use mir::transform::{MirSuite, MirPassIndex};
|
||||||
use session::CompileResult;
|
use session::CompileResult;
|
||||||
@ -1391,9 +1391,10 @@ define_maps! { <'tcx>
|
|||||||
-> Arc<Vec<(String, DefId, SymbolExportLevel)>>,
|
-> Arc<Vec<(String, DefId, SymbolExportLevel)>>,
|
||||||
[] fn collect_and_partition_translation_items:
|
[] fn collect_and_partition_translation_items:
|
||||||
collect_and_partition_translation_items_node(CrateNum)
|
collect_and_partition_translation_items_node(CrateNum)
|
||||||
-> (Arc<FxHashSet<TransItem<'tcx>>>, Vec<Arc<CodegenUnit<'tcx>>>),
|
-> (Arc<DefIdSet>, Arc<Vec<Arc<CodegenUnit<'tcx>>>>),
|
||||||
[] fn export_name: ExportName(DefId) -> Option<Symbol>,
|
[] fn export_name: ExportName(DefId) -> Option<Symbol>,
|
||||||
[] fn contains_extern_indicator: ContainsExternIndicator(DefId) -> bool,
|
[] fn contains_extern_indicator: ContainsExternIndicator(DefId) -> bool,
|
||||||
|
[] fn is_translated_function: IsTranslatedFunction(DefId) -> bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn type_param_predicates<'tcx>((item_id, param_id): (DefId, DefId)) -> DepConstructor<'tcx> {
|
fn type_param_predicates<'tcx>((item_id, param_id): (DefId, DefId)) -> DepConstructor<'tcx> {
|
||||||
|
@ -35,7 +35,7 @@ use back::write::{self, OngoingCrateTranslation};
|
|||||||
use llvm::{ContextRef, ModuleRef, ValueRef, Vector, get_param};
|
use llvm::{ContextRef, ModuleRef, ValueRef, Vector, get_param};
|
||||||
use llvm;
|
use llvm;
|
||||||
use metadata;
|
use metadata;
|
||||||
use rustc::hir::def_id::{CrateNum, LOCAL_CRATE};
|
use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
|
||||||
use rustc::middle::lang_items::StartFnLangItem;
|
use rustc::middle::lang_items::StartFnLangItem;
|
||||||
use rustc::middle::trans::{Linkage, Visibility};
|
use rustc::middle::trans::{Linkage, Visibility};
|
||||||
use rustc::middle::cstore::{EncodedMetadata, EncodedMetadataHashes};
|
use rustc::middle::cstore::{EncodedMetadata, EncodedMetadataHashes};
|
||||||
@ -75,7 +75,7 @@ use trans_item::{TransItem, TransItemExt, DefPathBasedNames};
|
|||||||
use type_::Type;
|
use type_::Type;
|
||||||
use type_of;
|
use type_of;
|
||||||
use value::Value;
|
use value::Value;
|
||||||
use rustc::util::nodemap::{NodeSet, FxHashMap, FxHashSet};
|
use rustc::util::nodemap::{NodeSet, FxHashMap, FxHashSet, DefIdSet};
|
||||||
use CrateInfo;
|
use CrateInfo;
|
||||||
|
|
||||||
use libc::c_uint;
|
use libc::c_uint;
|
||||||
@ -990,8 +990,9 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
|
|
||||||
// Run the translation item collector and partition the collected items into
|
// Run the translation item collector and partition the collected items into
|
||||||
// codegen units.
|
// codegen units.
|
||||||
let (translation_items, codegen_units) =
|
let codegen_units =
|
||||||
shared_ccx.tcx().collect_and_partition_translation_items(LOCAL_CRATE);
|
shared_ccx.tcx().collect_and_partition_translation_items(LOCAL_CRATE).1;
|
||||||
|
let codegen_units = (*codegen_units).clone();
|
||||||
|
|
||||||
assert!(codegen_units.len() <= 1 || !tcx.sess.lto());
|
assert!(codegen_units.len() <= 1 || !tcx.sess.lto());
|
||||||
|
|
||||||
@ -1076,8 +1077,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
let ((stats, module), _) =
|
let ((stats, module), _) =
|
||||||
tcx.dep_graph.with_task(dep_node,
|
tcx.dep_graph.with_task(dep_node,
|
||||||
AssertDepGraphSafe(&shared_ccx),
|
AssertDepGraphSafe(&shared_ccx),
|
||||||
AssertDepGraphSafe((cgu,
|
AssertDepGraphSafe(cgu),
|
||||||
translation_items.clone())),
|
|
||||||
module_translation);
|
module_translation);
|
||||||
all_stats.extend(stats);
|
all_stats.extend(stats);
|
||||||
|
|
||||||
@ -1118,13 +1118,12 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
|
|
||||||
fn module_translation<'a, 'tcx>(
|
fn module_translation<'a, 'tcx>(
|
||||||
scx: AssertDepGraphSafe<&SharedCrateContext<'a, 'tcx>>,
|
scx: AssertDepGraphSafe<&SharedCrateContext<'a, 'tcx>>,
|
||||||
args: AssertDepGraphSafe<(Arc<CodegenUnit<'tcx>>,
|
args: AssertDepGraphSafe<Arc<CodegenUnit<'tcx>>>)
|
||||||
Arc<FxHashSet<TransItem<'tcx>>>)>)
|
|
||||||
-> (Stats, ModuleTranslation)
|
-> (Stats, ModuleTranslation)
|
||||||
{
|
{
|
||||||
// FIXME(#40304): We ought to be using the id as a key and some queries, I think.
|
// FIXME(#40304): We ought to be using the id as a key and some queries, I think.
|
||||||
let AssertDepGraphSafe(scx) = scx;
|
let AssertDepGraphSafe(scx) = scx;
|
||||||
let AssertDepGraphSafe((cgu, crate_trans_items)) = args;
|
let AssertDepGraphSafe(cgu) = args;
|
||||||
|
|
||||||
let cgu_name = cgu.name().to_string();
|
let cgu_name = cgu.name().to_string();
|
||||||
let cgu_id = cgu.work_product_id();
|
let cgu_id = cgu.work_product_id();
|
||||||
@ -1164,7 +1163,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Instantiate translation items without filling out definitions yet...
|
// Instantiate translation items without filling out definitions yet...
|
||||||
let lcx = LocalCrateContext::new(scx, cgu, crate_trans_items);
|
let lcx = LocalCrateContext::new(scx, cgu);
|
||||||
let module = {
|
let module = {
|
||||||
let ccx = CrateContext::new(scx, &lcx);
|
let ccx = CrateContext::new(scx, &lcx);
|
||||||
let trans_items = ccx.codegen_unit()
|
let trans_items = ccx.codegen_unit()
|
||||||
@ -1353,7 +1352,7 @@ fn assert_symbols_are_distinct<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trans_i
|
|||||||
fn collect_and_partition_translation_items<'a, 'tcx>(
|
fn collect_and_partition_translation_items<'a, 'tcx>(
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
cnum: CrateNum,
|
cnum: CrateNum,
|
||||||
) -> (Arc<FxHashSet<TransItem<'tcx>>>, Vec<Arc<CodegenUnit<'tcx>>>)
|
) -> (Arc<DefIdSet>, Arc<Vec<Arc<CodegenUnit<'tcx>>>>)
|
||||||
{
|
{
|
||||||
assert_eq!(cnum, LOCAL_CRATE);
|
assert_eq!(cnum, LOCAL_CRATE);
|
||||||
let time_passes = tcx.sess.time_passes();
|
let time_passes = tcx.sess.time_passes();
|
||||||
@ -1404,7 +1403,12 @@ fn collect_and_partition_translation_items<'a, 'tcx>(
|
|||||||
assert!(tcx.sess.opts.cg.codegen_units == codegen_units.len() ||
|
assert!(tcx.sess.opts.cg.codegen_units == codegen_units.len() ||
|
||||||
tcx.sess.opts.debugging_opts.incremental.is_some());
|
tcx.sess.opts.debugging_opts.incremental.is_some());
|
||||||
|
|
||||||
let translation_items: FxHashSet<TransItem<'tcx>> = items.iter().cloned().collect();
|
let translation_items: DefIdSet = items.iter().filter_map(|trans_item| {
|
||||||
|
match *trans_item {
|
||||||
|
TransItem::Fn(ref instance) => Some(instance.def_id()),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}).collect();
|
||||||
|
|
||||||
if tcx.sess.opts.debugging_opts.print_trans_items.is_some() {
|
if tcx.sess.opts.debugging_opts.print_trans_items.is_some() {
|
||||||
let mut item_to_cgus = FxHashMap();
|
let mut item_to_cgus = FxHashMap();
|
||||||
@ -1459,7 +1463,7 @@ fn collect_and_partition_translation_items<'a, 'tcx>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(Arc::new(translation_items), codegen_units)
|
(Arc::new(translation_items), Arc::new(codegen_units))
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CrateInfo {
|
impl CrateInfo {
|
||||||
@ -1505,9 +1509,25 @@ impl CrateInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn provide(providers: &mut Providers) {
|
fn is_translated_function(tcx: TyCtxt, id: DefId) -> bool {
|
||||||
|
// FIXME(#42293) needs red/green tracking to avoid failing a bunch of
|
||||||
|
// existing tests
|
||||||
|
tcx.dep_graph.with_ignore(|| {
|
||||||
|
let (all_trans_items, _) =
|
||||||
|
tcx.collect_and_partition_translation_items(LOCAL_CRATE);
|
||||||
|
all_trans_items.contains(&id)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn provide_local(providers: &mut Providers) {
|
||||||
providers.collect_and_partition_translation_items =
|
providers.collect_and_partition_translation_items =
|
||||||
collect_and_partition_translation_items;
|
collect_and_partition_translation_items;
|
||||||
|
|
||||||
|
providers.is_translated_function = is_translated_function;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn provide_extern(providers: &mut Providers) {
|
||||||
|
providers.is_translated_function = is_translated_function;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn linkage_to_llvm(linkage: Linkage) -> llvm::Linkage {
|
pub fn linkage_to_llvm(linkage: Linkage) -> llvm::Linkage {
|
||||||
|
@ -23,7 +23,6 @@ use monomorphize::{self, Instance};
|
|||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::DefId;
|
||||||
use rustc::ty::TypeFoldable;
|
use rustc::ty::TypeFoldable;
|
||||||
use rustc::ty::subst::Substs;
|
use rustc::ty::subst::Substs;
|
||||||
use trans_item::TransItem;
|
|
||||||
use type_of;
|
use type_of;
|
||||||
|
|
||||||
/// Translates a reference to a fn/method item, monomorphizing and
|
/// Translates a reference to a fn/method item, monomorphizing and
|
||||||
@ -109,10 +108,43 @@ pub fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||||||
attributes::unwind(llfn, true);
|
attributes::unwind(llfn, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply an appropriate linkage/visibility value to our item that we
|
||||||
|
// just declared.
|
||||||
|
//
|
||||||
|
// This is sort of subtle. Inside our codegen unit we started off
|
||||||
|
// compilation by predefining all our own `TransItem` instances. That
|
||||||
|
// is, everything we're translating ourselves is already defined. That
|
||||||
|
// means that anything we're actually translating ourselves will have
|
||||||
|
// hit the above branch in `get_declared_value`. As a result, we're
|
||||||
|
// guaranteed here that we're declaring a symbol that won't get defined,
|
||||||
|
// or in other words we're referencing a foreign value.
|
||||||
|
//
|
||||||
|
// So because this is a foreign value we blanket apply an external
|
||||||
|
// linkage directive because it's coming from a different object file.
|
||||||
|
// The visibility here is where it gets tricky. This symbol could be
|
||||||
|
// referencing some foreign crate or foreign library (an `extern`
|
||||||
|
// block) in which case we want to leave the default visibility. We may
|
||||||
|
// also, though, have multiple codegen units.
|
||||||
|
//
|
||||||
|
// In the situation of multiple codegen units this function may be
|
||||||
|
// referencing a function from another codegen unit. If we're
|
||||||
|
// indeed referencing a symbol in another codegen unit then we're in one
|
||||||
|
// of two cases:
|
||||||
|
//
|
||||||
|
// * This is a symbol defined in a foreign crate and we're just
|
||||||
|
// monomorphizing in another codegen unit. In this case this symbols
|
||||||
|
// is for sure not exported, so both codegen units will be using
|
||||||
|
// hidden visibility. Hence, we apply a hidden visibility here.
|
||||||
|
//
|
||||||
|
// * This is a symbol defined in our local crate. If the symbol in the
|
||||||
|
// other codegen unit is also not exported then like with the foreign
|
||||||
|
// case we apply a hidden visibility. If the symbol is exported from
|
||||||
|
// the foreign object file, however, then we leave this at the
|
||||||
|
// default visibility as we'll just import it naturally.
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::ExternalLinkage);
|
llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::ExternalLinkage);
|
||||||
|
|
||||||
if ccx.crate_trans_items().contains(&TransItem::Fn(instance)) {
|
if ccx.tcx().is_translated_function(instance_def_id) {
|
||||||
if instance_def_id.is_local() {
|
if instance_def_id.is_local() {
|
||||||
if !ccx.tcx().is_exported_symbol(instance_def_id) {
|
if !ccx.tcx().is_exported_symbol(instance_def_id) {
|
||||||
llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
|
llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
|
||||||
|
@ -22,14 +22,13 @@ use declare;
|
|||||||
use monomorphize::Instance;
|
use monomorphize::Instance;
|
||||||
|
|
||||||
use partitioning::CodegenUnit;
|
use partitioning::CodegenUnit;
|
||||||
use trans_item::TransItem;
|
|
||||||
use type_::Type;
|
use type_::Type;
|
||||||
use rustc_data_structures::base_n;
|
use rustc_data_structures::base_n;
|
||||||
use rustc::session::config::{self, NoDebugInfo, OutputFilenames};
|
use rustc::session::config::{self, NoDebugInfo, OutputFilenames};
|
||||||
use rustc::session::Session;
|
use rustc::session::Session;
|
||||||
use rustc::ty::{self, Ty, TyCtxt};
|
use rustc::ty::{self, Ty, TyCtxt};
|
||||||
use rustc::ty::layout::{LayoutCx, LayoutError, LayoutTyper, TyLayout};
|
use rustc::ty::layout::{LayoutCx, LayoutError, LayoutTyper, TyLayout};
|
||||||
use rustc::util::nodemap::{FxHashMap, FxHashSet};
|
use rustc::util::nodemap::FxHashMap;
|
||||||
|
|
||||||
use std::ffi::{CStr, CString};
|
use std::ffi::{CStr, CString};
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
@ -94,9 +93,6 @@ pub struct LocalCrateContext<'a, 'tcx: 'a> {
|
|||||||
stats: Stats,
|
stats: Stats,
|
||||||
codegen_unit: Arc<CodegenUnit<'tcx>>,
|
codegen_unit: Arc<CodegenUnit<'tcx>>,
|
||||||
|
|
||||||
/// The translation items of the whole crate.
|
|
||||||
crate_trans_items: Arc<FxHashSet<TransItem<'tcx>>>,
|
|
||||||
|
|
||||||
/// Cache instances of monomorphic and polymorphic items
|
/// Cache instances of monomorphic and polymorphic items
|
||||||
instances: RefCell<FxHashMap<Instance<'tcx>, ValueRef>>,
|
instances: RefCell<FxHashMap<Instance<'tcx>, ValueRef>>,
|
||||||
/// Cache generated vtables
|
/// Cache generated vtables
|
||||||
@ -349,8 +345,7 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
|
|||||||
|
|
||||||
impl<'a, 'tcx> LocalCrateContext<'a, 'tcx> {
|
impl<'a, 'tcx> LocalCrateContext<'a, 'tcx> {
|
||||||
pub fn new(shared: &SharedCrateContext<'a, 'tcx>,
|
pub fn new(shared: &SharedCrateContext<'a, 'tcx>,
|
||||||
codegen_unit: Arc<CodegenUnit<'tcx>>,
|
codegen_unit: Arc<CodegenUnit<'tcx>>)
|
||||||
crate_trans_items: Arc<FxHashSet<TransItem<'tcx>>>)
|
|
||||||
-> LocalCrateContext<'a, 'tcx> {
|
-> LocalCrateContext<'a, 'tcx> {
|
||||||
unsafe {
|
unsafe {
|
||||||
// Append ".rs" to LLVM module identifier.
|
// Append ".rs" to LLVM module identifier.
|
||||||
@ -382,7 +377,6 @@ impl<'a, 'tcx> LocalCrateContext<'a, 'tcx> {
|
|||||||
llcx,
|
llcx,
|
||||||
stats: Stats::default(),
|
stats: Stats::default(),
|
||||||
codegen_unit,
|
codegen_unit,
|
||||||
crate_trans_items,
|
|
||||||
instances: RefCell::new(FxHashMap()),
|
instances: RefCell::new(FxHashMap()),
|
||||||
vtables: RefCell::new(FxHashMap()),
|
vtables: RefCell::new(FxHashMap()),
|
||||||
const_cstr_cache: RefCell::new(FxHashMap()),
|
const_cstr_cache: RefCell::new(FxHashMap()),
|
||||||
@ -489,10 +483,6 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
|
|||||||
&self.local().codegen_unit
|
&self.local().codegen_unit
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn crate_trans_items(&self) -> &FxHashSet<TransItem<'tcx>> {
|
|
||||||
&self.local().crate_trans_items
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn td(&self) -> llvm::TargetDataRef {
|
pub fn td(&self) -> llvm::TargetDataRef {
|
||||||
unsafe { llvm::LLVMRustGetModuleDataLayout(self.llmod()) }
|
unsafe { llvm::LLVMRustGetModuleDataLayout(self.llmod()) }
|
||||||
}
|
}
|
||||||
|
@ -251,10 +251,11 @@ __build_diagnostic_array! { librustc_trans, DIAGNOSTICS }
|
|||||||
pub fn provide_local(providers: &mut Providers) {
|
pub fn provide_local(providers: &mut Providers) {
|
||||||
back::symbol_names::provide(providers);
|
back::symbol_names::provide(providers);
|
||||||
back::symbol_export::provide_local(providers);
|
back::symbol_export::provide_local(providers);
|
||||||
base::provide(providers);
|
base::provide_local(providers);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn provide_extern(providers: &mut Providers) {
|
pub fn provide_extern(providers: &mut Providers) {
|
||||||
back::symbol_names::provide(providers);
|
back::symbol_names::provide(providers);
|
||||||
back::symbol_export::provide_extern(providers);
|
back::symbol_export::provide_extern(providers);
|
||||||
|
base::provide_extern(providers);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user