rustc: Mostly remove ExportedSymbols
This is a big map that ends up inside of a `CrateContext` during translation for all codegen units. This means that any change to the map may end up causing an incremental recompilation of a codegen unit! In order to reduce the amount of dependencies here between codegen units and the actual input crate this commit refactors dealing with exported symbols and such into various queries. The new queries are largely based on existing queries with filled out implementations for the local crate in addition to external crates, but the main idea is that while translating codegen untis no unit needs the entire set of exported symbols, instead they only need queries about particulare `DefId` instances every now and then. The linking stage, however, still generates a full list of all exported symbols from all crates, but that's going to always happen unconditionally anyway, so no news there!
This commit is contained in:
parent
8821affd15
commit
afb85cfd33
18 changed files with 234 additions and 314 deletions
|
@ -575,7 +575,7 @@ define_dep_nodes!( <'tcx>
|
|||
[] MaybeUnusedExternCrates,
|
||||
[] StabilityIndex,
|
||||
[] AllCrateNums,
|
||||
[] ExportedSymbols,
|
||||
[] ExportedSymbols(CrateNum),
|
||||
[] CollectAndPartitionTranslationItems,
|
||||
[] ExportName(DefId),
|
||||
[] ContainsExternIndicator(DefId),
|
||||
|
|
|
@ -366,8 +366,9 @@ pub trait CrateLoader {
|
|||
// In order to get this left-to-right dependency ordering, we perform a
|
||||
// topological sort of all crates putting the leaves at the right-most
|
||||
// positions.
|
||||
pub fn used_crates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)> {
|
||||
pub fn used_crates(tcx: TyCtxt, prefer: LinkagePreference)
|
||||
-> Vec<(CrateNum, LibSource)>
|
||||
{
|
||||
let mut libs = tcx.crates()
|
||||
.iter()
|
||||
.cloned()
|
||||
|
|
|
@ -8,9 +8,6 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use util::nodemap::{FxHashMap, NodeSet};
|
||||
use hir::def_id::{DefId, CrateNum};
|
||||
|
||||
/// The SymbolExportLevel of a symbols specifies from which kinds of crates
|
||||
/// the symbol will be exported. `C` symbols will be exported from any
|
||||
/// kind of crate, including cdylibs which export very few things.
|
||||
|
@ -22,56 +19,13 @@ pub enum SymbolExportLevel {
|
|||
Rust,
|
||||
}
|
||||
|
||||
/// The set of symbols exported from each crate in the crate graph.
|
||||
#[derive(Debug)]
|
||||
pub struct ExportedSymbols {
|
||||
pub export_threshold: SymbolExportLevel,
|
||||
exports: FxHashMap<CrateNum, Vec<(String, DefId, SymbolExportLevel)>>,
|
||||
local_exports: NodeSet,
|
||||
}
|
||||
|
||||
impl ExportedSymbols {
|
||||
pub fn new(export_threshold: SymbolExportLevel,
|
||||
exports: FxHashMap<CrateNum, Vec<(String, DefId, SymbolExportLevel)>>,
|
||||
local_exports: NodeSet) -> ExportedSymbols {
|
||||
ExportedSymbols {
|
||||
export_threshold,
|
||||
exports,
|
||||
local_exports,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn local_exports(&self) -> &NodeSet {
|
||||
&self.local_exports
|
||||
}
|
||||
|
||||
pub fn exported_symbols(&self, cnum: CrateNum)
|
||||
-> &[(String, DefId, SymbolExportLevel)]
|
||||
{
|
||||
match self.exports.get(&cnum) {
|
||||
Some(exports) => exports,
|
||||
None => &[]
|
||||
}
|
||||
}
|
||||
|
||||
pub fn for_each_exported_symbol<F>(&self, cnum: CrateNum, mut f: F)
|
||||
where F: FnMut(&str, DefId, SymbolExportLevel)
|
||||
{
|
||||
for &(ref name, def_id, export_level) in self.exported_symbols(cnum) {
|
||||
if is_below_threshold(export_level, self.export_threshold) {
|
||||
f(&name, def_id, export_level)
|
||||
}
|
||||
impl SymbolExportLevel {
|
||||
pub fn is_below_threshold(self, threshold: SymbolExportLevel) -> bool {
|
||||
if threshold == SymbolExportLevel::Rust {
|
||||
// We export everything from Rust dylibs
|
||||
true
|
||||
} else {
|
||||
self == SymbolExportLevel::C
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_below_threshold(level: SymbolExportLevel,
|
||||
threshold: SymbolExportLevel)
|
||||
-> bool {
|
||||
if threshold == SymbolExportLevel::Rust {
|
||||
// We export everything from Rust dylibs
|
||||
true
|
||||
} else {
|
||||
level == SymbolExportLevel::C
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@ use middle::cstore::EncodedMetadata;
|
|||
use middle::free_region::FreeRegionMap;
|
||||
use middle::lang_items;
|
||||
use middle::resolve_lifetime::{self, ObjectLifetimeDefault};
|
||||
use middle::exported_symbols::ExportedSymbols;
|
||||
use middle::stability;
|
||||
use mir::Mir;
|
||||
use mir::transform::Passes;
|
||||
|
@ -65,7 +64,6 @@ use std::mem;
|
|||
use std::ops::Deref;
|
||||
use std::iter;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
use syntax::abi;
|
||||
use syntax::ast::{self, Name, NodeId};
|
||||
use syntax::attr;
|
||||
|
@ -1220,10 +1218,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
pub fn crate_data_as_rc_any(self, cnum: CrateNum) -> Rc<Any> {
|
||||
self.cstore.crate_data_as_rc_any(cnum)
|
||||
}
|
||||
|
||||
pub fn exported_symbols(self) -> Arc<ExportedSymbols> {
|
||||
self.exported_symbol_set(LOCAL_CRATE)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
|
||||
|
|
|
@ -23,7 +23,7 @@ use middle::region;
|
|||
use middle::resolve_lifetime::{Region, ObjectLifetimeDefault};
|
||||
use middle::stability::{self, DeprecationEntry};
|
||||
use middle::lang_items::{LanguageItems, LangItem};
|
||||
use middle::exported_symbols::ExportedSymbols;
|
||||
use middle::exported_symbols::SymbolExportLevel;
|
||||
use middle::trans::{TransItem, CodegenUnit};
|
||||
use mir;
|
||||
use mir::transform::{MirSuite, MirPassIndex};
|
||||
|
@ -748,9 +748,9 @@ impl<'tcx> QueryDescription for queries::all_crate_nums<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> QueryDescription for queries::exported_symbol_set<'tcx> {
|
||||
impl<'tcx> QueryDescription for queries::exported_symbols<'tcx> {
|
||||
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
|
||||
format!("exported symbol set")
|
||||
format!("exported_symbols")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1337,7 +1337,7 @@ define_maps! { <'tcx>
|
|||
[] fn lint_levels: lint_levels_node(CrateNum) -> Rc<lint::LintLevelMap>,
|
||||
|
||||
[] fn impl_defaultness: ImplDefaultness(DefId) -> hir::Defaultness,
|
||||
[] fn exported_symbol_ids: ExportedSymbolIds(CrateNum) -> Rc<Vec<DefId>>,
|
||||
[] fn exported_symbol_ids: ExportedSymbolIds(CrateNum) -> Rc<DefIdSet>,
|
||||
[] fn native_libraries: NativeLibraries(CrateNum) -> Rc<Vec<NativeLibrary>>,
|
||||
[] fn plugin_registrar_fn: PluginRegistrarFn(CrateNum) -> Option<DefId>,
|
||||
[] fn derive_registrar_fn: DeriveRegistrarFn(CrateNum) -> Option<DefId>,
|
||||
|
@ -1387,8 +1387,8 @@ define_maps! { <'tcx>
|
|||
[] fn stability_index: stability_index_node(CrateNum) -> Rc<stability::Index<'tcx>>,
|
||||
[] fn all_crate_nums: all_crate_nums_node(CrateNum) -> Rc<Vec<CrateNum>>,
|
||||
|
||||
[] fn exported_symbol_set: exported_symbol_set_node(CrateNum)
|
||||
-> Arc<ExportedSymbols>,
|
||||
[] fn exported_symbols: ExportedSymbols(CrateNum)
|
||||
-> Arc<Vec<(String, DefId, SymbolExportLevel)>>,
|
||||
[] fn collect_and_partition_translation_items:
|
||||
collect_and_partition_translation_items_node(CrateNum)
|
||||
-> (Arc<FxHashSet<TransItem<'tcx>>>, Vec<Arc<CodegenUnit<'tcx>>>),
|
||||
|
@ -1508,10 +1508,6 @@ fn all_crate_nums_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
|
|||
DepConstructor::AllCrateNums
|
||||
}
|
||||
|
||||
fn exported_symbol_set_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
|
||||
DepConstructor::ExportedSymbols
|
||||
}
|
||||
|
||||
fn collect_and_partition_translation_items_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
|
||||
DepConstructor::CollectAndPartitionTranslationItems
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ use rustc::middle::lang_items;
|
|||
use rustc::session::Session;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc::util::nodemap::DefIdSet;
|
||||
|
||||
use rustc::mir::Mir;
|
||||
|
||||
|
@ -1017,7 +1018,7 @@ impl<'a, 'tcx> CrateMetadata {
|
|||
arg_names.decode(self).collect()
|
||||
}
|
||||
|
||||
pub fn get_exported_symbols(&self) -> Vec<DefId> {
|
||||
pub fn get_exported_symbols(&self) -> DefIdSet {
|
||||
self.exported_symbols
|
||||
.iter()
|
||||
.map(|&index| self.local_def_id(index))
|
||||
|
|
|
@ -15,16 +15,15 @@ use std::io::prelude::*;
|
|||
use std::io::{self, BufWriter};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use context::SharedCrateContext;
|
||||
|
||||
use back::archive;
|
||||
use back::command::Command;
|
||||
use rustc::middle::dependency_format::Linkage;
|
||||
use rustc::middle::exported_symbols::ExportedSymbols;
|
||||
use back::symbol_export;
|
||||
use rustc::hir::def_id::{LOCAL_CRATE, CrateNum};
|
||||
use rustc_back::LinkerFlavor;
|
||||
use rustc::middle::dependency_format::Linkage;
|
||||
use rustc::session::Session;
|
||||
use rustc::session::config::{self, CrateType, OptLevel, DebugInfoLevel};
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc_back::LinkerFlavor;
|
||||
use serialize::{json, Encoder};
|
||||
|
||||
/// For all the linkers we support, and information they might
|
||||
|
@ -33,19 +32,18 @@ pub struct LinkerInfo {
|
|||
exports: HashMap<CrateType, Vec<String>>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> LinkerInfo {
|
||||
pub fn new(scx: &SharedCrateContext<'a, 'tcx>) -> LinkerInfo {
|
||||
let exports = scx.tcx().exported_symbols();
|
||||
impl LinkerInfo {
|
||||
pub fn new(tcx: TyCtxt) -> LinkerInfo {
|
||||
LinkerInfo {
|
||||
exports: scx.sess().crate_types.borrow().iter().map(|&c| {
|
||||
(c, exported_symbols(scx, &exports, c))
|
||||
exports: tcx.sess.crate_types.borrow().iter().map(|&c| {
|
||||
(c, exported_symbols(tcx, c))
|
||||
}).collect(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_linker(&'a self,
|
||||
cmd: Command,
|
||||
sess: &'a Session) -> Box<Linker+'a> {
|
||||
pub fn to_linker<'a>(&'a self,
|
||||
cmd: Command,
|
||||
sess: &'a Session) -> Box<Linker+'a> {
|
||||
match sess.linker_flavor() {
|
||||
LinkerFlavor::Msvc => {
|
||||
Box::new(MsvcLinker {
|
||||
|
@ -734,16 +732,17 @@ impl<'a> Linker for EmLinker<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn exported_symbols(scx: &SharedCrateContext,
|
||||
exported_symbols: &ExportedSymbols,
|
||||
crate_type: CrateType)
|
||||
-> Vec<String> {
|
||||
fn exported_symbols(tcx: TyCtxt, crate_type: CrateType) -> Vec<String> {
|
||||
let mut symbols = Vec::new();
|
||||
exported_symbols.for_each_exported_symbol(LOCAL_CRATE, |name, _, _| {
|
||||
symbols.push(name.to_owned());
|
||||
});
|
||||
|
||||
let formats = scx.sess().dependency_formats.borrow();
|
||||
let export_threshold = symbol_export::threshold(tcx);
|
||||
for &(ref name, _, level) in tcx.exported_symbols(LOCAL_CRATE).iter() {
|
||||
if level.is_below_threshold(export_threshold) {
|
||||
symbols.push(name.clone());
|
||||
}
|
||||
}
|
||||
|
||||
let formats = tcx.sess.dependency_formats.borrow();
|
||||
let deps = formats[&crate_type].iter();
|
||||
|
||||
for (index, dep_format) in deps.enumerate() {
|
||||
|
@ -751,9 +750,11 @@ fn exported_symbols(scx: &SharedCrateContext,
|
|||
// For each dependency that we are linking to statically ...
|
||||
if *dep_format == Linkage::Static {
|
||||
// ... we add its symbol list to our export list.
|
||||
exported_symbols.for_each_exported_symbol(cnum, |name, _, _| {
|
||||
symbols.push(name.to_owned());
|
||||
})
|
||||
for &(ref name, _, level) in tcx.exported_symbols(cnum).iter() {
|
||||
if level.is_below_threshold(export_threshold) {
|
||||
symbols.push(name.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ use errors::{FatalError, Handler};
|
|||
use llvm;
|
||||
use llvm::archive_ro::ArchiveRO;
|
||||
use llvm::{ModuleRef, TargetMachineRef, True, False};
|
||||
use rustc::middle::exported_symbols;
|
||||
use rustc::middle::exported_symbols::SymbolExportLevel;
|
||||
use rustc::util::common::time;
|
||||
use rustc::util::common::path2cstr;
|
||||
use rustc::hir::def_id::LOCAL_CRATE;
|
||||
|
@ -68,8 +68,8 @@ pub fn run(cgcx: &CodegenContext,
|
|||
let export_threshold =
|
||||
symbol_export::crates_export_threshold(&cgcx.crate_types);
|
||||
|
||||
let symbol_filter = &|&(ref name, _, level): &(String, _, _)| {
|
||||
if exported_symbols::is_below_threshold(level, export_threshold) {
|
||||
let symbol_filter = &|&(ref name, _, level): &(String, _, SymbolExportLevel)| {
|
||||
if level.is_below_threshold(export_threshold) {
|
||||
let mut bytes = Vec::with_capacity(name.len() + 1);
|
||||
bytes.extend(name.bytes());
|
||||
Some(CString::new(bytes).unwrap())
|
||||
|
@ -78,8 +78,7 @@ pub fn run(cgcx: &CodegenContext,
|
|||
}
|
||||
};
|
||||
|
||||
let mut symbol_white_list: Vec<CString> = cgcx.exported_symbols
|
||||
.exported_symbols(LOCAL_CRATE)
|
||||
let mut symbol_white_list: Vec<CString> = cgcx.exported_symbols[&LOCAL_CRATE]
|
||||
.iter()
|
||||
.filter_map(symbol_filter)
|
||||
.collect();
|
||||
|
@ -89,9 +88,9 @@ pub fn run(cgcx: &CodegenContext,
|
|||
// module that we've got.
|
||||
for &(cnum, ref path) in cgcx.each_linked_rlib_for_lto.iter() {
|
||||
symbol_white_list.extend(
|
||||
cgcx.exported_symbols.exported_symbols(cnum)
|
||||
.iter()
|
||||
.filter_map(symbol_filter));
|
||||
cgcx.exported_symbols[&cnum]
|
||||
.iter()
|
||||
.filter_map(symbol_filter));
|
||||
|
||||
let archive = ArchiveRO::open(&path).expect("wanted an rlib");
|
||||
let bytecodes = archive.iter().filter_map(|child| {
|
||||
|
|
|
@ -8,89 +8,140 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
use base;
|
||||
use monomorphize::Instance;
|
||||
use rustc::util::nodemap::{FxHashMap, NodeSet};
|
||||
use rustc::hir::def_id::CrateNum;
|
||||
use rustc::hir::def_id::{DefId, LOCAL_CRATE, INVALID_CRATE, CRATE_DEF_INDEX};
|
||||
use rustc::middle::exported_symbols::SymbolExportLevel;
|
||||
use rustc::session::config;
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc::ty::maps::Providers;
|
||||
use rustc::util::nodemap::FxHashMap;
|
||||
use rustc_allocator::ALLOCATOR_METHODS;
|
||||
use rustc::middle::exported_symbols::{ExportedSymbols, SymbolExportLevel};
|
||||
use rustc::middle::exported_symbols::is_below_threshold;
|
||||
|
||||
pub fn compute<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ExportedSymbols {
|
||||
let export_threshold = crates_export_threshold(&tcx.sess.crate_types.borrow());
|
||||
let local_exported_symbols = base::find_exported_symbols(tcx);
|
||||
pub type ExportedSymbols = FxHashMap<
|
||||
CrateNum,
|
||||
Arc<Vec<(String, DefId, SymbolExportLevel)>>,
|
||||
>;
|
||||
|
||||
let mut local_crate: Vec<_> = local_exported_symbols
|
||||
.iter()
|
||||
.map(|&node_id| {
|
||||
tcx.hir.local_def_id(node_id)
|
||||
})
|
||||
.map(|def_id| {
|
||||
let name = tcx.symbol_name(Instance::mono(tcx, def_id));
|
||||
let export_level = export_level(tcx, def_id);
|
||||
debug!("EXPORTED SYMBOL (local): {} ({:?})", name, export_level);
|
||||
(str::to_owned(&name), def_id, export_level)
|
||||
})
|
||||
.collect();
|
||||
pub fn threshold(tcx: TyCtxt) -> SymbolExportLevel {
|
||||
crates_export_threshold(&tcx.sess.crate_types.borrow())
|
||||
}
|
||||
|
||||
let mut local_exports = local_crate
|
||||
.iter()
|
||||
.filter_map(|&(_, def_id, level)| {
|
||||
if is_below_threshold(level, export_threshold) {
|
||||
tcx.hir.as_local_node_id(def_id)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<NodeSet>();
|
||||
pub fn metadata_symbol_name(tcx: TyCtxt) -> String {
|
||||
format!("rust_metadata_{}_{}",
|
||||
tcx.crate_name(LOCAL_CRATE),
|
||||
tcx.crate_disambiguator(LOCAL_CRATE))
|
||||
}
|
||||
|
||||
const INVALID_DEF_ID: DefId = DefId {
|
||||
krate: INVALID_CRATE,
|
||||
index: CRATE_DEF_INDEX,
|
||||
fn crate_export_threshold(crate_type: config::CrateType) -> SymbolExportLevel {
|
||||
match crate_type {
|
||||
config::CrateTypeExecutable |
|
||||
config::CrateTypeStaticlib |
|
||||
config::CrateTypeProcMacro |
|
||||
config::CrateTypeCdylib => SymbolExportLevel::C,
|
||||
config::CrateTypeRlib |
|
||||
config::CrateTypeDylib => SymbolExportLevel::Rust,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn crates_export_threshold(crate_types: &[config::CrateType])
|
||||
-> SymbolExportLevel {
|
||||
if crate_types.iter().any(|&crate_type| {
|
||||
crate_export_threshold(crate_type) == SymbolExportLevel::Rust
|
||||
}) {
|
||||
SymbolExportLevel::Rust
|
||||
} else {
|
||||
SymbolExportLevel::C
|
||||
}
|
||||
}
|
||||
|
||||
pub fn provide_local(providers: &mut Providers) {
|
||||
providers.exported_symbol_ids = |tcx, cnum| {
|
||||
let export_threshold = threshold(tcx);
|
||||
Rc::new(tcx.exported_symbols(cnum)
|
||||
.iter()
|
||||
.filter_map(|&(_, id, level)| {
|
||||
if level.is_below_threshold(export_threshold) {
|
||||
Some(id)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect())
|
||||
};
|
||||
|
||||
if let Some(_) = *tcx.sess.entry_fn.borrow() {
|
||||
local_crate.push(("main".to_string(),
|
||||
INVALID_DEF_ID,
|
||||
SymbolExportLevel::C));
|
||||
}
|
||||
providers.is_exported_symbol = |tcx, id| {
|
||||
// FIXME(#42293) needs red/green to not break a bunch of incremental
|
||||
// tests
|
||||
tcx.dep_graph.with_ignore(|| {
|
||||
tcx.exported_symbol_ids(id.krate).contains(&id)
|
||||
})
|
||||
};
|
||||
|
||||
if tcx.sess.allocator_kind.get().is_some() {
|
||||
for method in ALLOCATOR_METHODS {
|
||||
local_crate.push((format!("__rust_{}", method.name),
|
||||
providers.exported_symbols = |tcx, cnum| {
|
||||
assert_eq!(cnum, LOCAL_CRATE);
|
||||
let local_exported_symbols = base::find_exported_symbols(tcx);
|
||||
|
||||
let mut local_crate: Vec<_> = local_exported_symbols
|
||||
.iter()
|
||||
.map(|&node_id| {
|
||||
tcx.hir.local_def_id(node_id)
|
||||
})
|
||||
.map(|def_id| {
|
||||
let name = tcx.symbol_name(Instance::mono(tcx, def_id));
|
||||
let export_level = export_level(tcx, def_id);
|
||||
debug!("EXPORTED SYMBOL (local): {} ({:?})", name, export_level);
|
||||
(str::to_owned(&name), def_id, export_level)
|
||||
})
|
||||
.collect();
|
||||
|
||||
const INVALID_DEF_ID: DefId = DefId {
|
||||
krate: INVALID_CRATE,
|
||||
index: CRATE_DEF_INDEX,
|
||||
};
|
||||
|
||||
if let Some(_) = *tcx.sess.entry_fn.borrow() {
|
||||
local_crate.push(("main".to_string(),
|
||||
INVALID_DEF_ID,
|
||||
SymbolExportLevel::C));
|
||||
}
|
||||
|
||||
if tcx.sess.allocator_kind.get().is_some() {
|
||||
for method in ALLOCATOR_METHODS {
|
||||
local_crate.push((format!("__rust_{}", method.name),
|
||||
INVALID_DEF_ID,
|
||||
SymbolExportLevel::Rust));
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(id) = tcx.sess.derive_registrar_fn.get() {
|
||||
let def_id = tcx.hir.local_def_id(id);
|
||||
let idx = def_id.index;
|
||||
let disambiguator = tcx.sess.local_crate_disambiguator();
|
||||
let registrar = tcx.sess.generate_derive_registrar_symbol(disambiguator, idx);
|
||||
local_crate.push((registrar, def_id, SymbolExportLevel::C));
|
||||
}
|
||||
|
||||
if tcx.sess.crate_types.borrow().contains(&config::CrateTypeDylib) {
|
||||
local_crate.push((metadata_symbol_name(tcx),
|
||||
INVALID_DEF_ID,
|
||||
SymbolExportLevel::Rust));
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(id) = tcx.sess.derive_registrar_fn.get() {
|
||||
let def_id = tcx.hir.local_def_id(id);
|
||||
let idx = def_id.index;
|
||||
let disambiguator = tcx.sess.local_crate_disambiguator();
|
||||
let registrar = tcx.sess.generate_derive_registrar_symbol(disambiguator, idx);
|
||||
local_crate.push((registrar, def_id, SymbolExportLevel::C));
|
||||
local_exports.insert(id);
|
||||
}
|
||||
|
||||
if tcx.sess.crate_types.borrow().contains(&config::CrateTypeDylib) {
|
||||
local_crate.push((metadata_symbol_name(tcx),
|
||||
INVALID_DEF_ID,
|
||||
SymbolExportLevel::Rust));
|
||||
}
|
||||
|
||||
let mut exports = FxHashMap();
|
||||
exports.insert(LOCAL_CRATE, local_crate);
|
||||
|
||||
for &cnum in tcx.crates().iter() {
|
||||
debug_assert!(cnum != LOCAL_CRATE);
|
||||
Arc::new(local_crate)
|
||||
};
|
||||
}
|
||||
|
||||
pub fn provide_extern(providers: &mut Providers) {
|
||||
providers.exported_symbols = |tcx, cnum| {
|
||||
// If this crate is a plugin and/or a custom derive crate, then
|
||||
// we're not even going to link those in so we skip those crates.
|
||||
if tcx.plugin_registrar_fn(cnum).is_some() ||
|
||||
tcx.derive_registrar_fn(cnum).is_some() {
|
||||
continue;
|
||||
return Arc::new(Vec::new())
|
||||
}
|
||||
|
||||
// Check to see if this crate is a "special runtime crate". These
|
||||
|
@ -131,45 +182,14 @@ pub fn compute<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ExportedSymbols {
|
|||
})
|
||||
.collect();
|
||||
|
||||
exports.insert(cnum, crate_exports);
|
||||
}
|
||||
|
||||
return ExportedSymbols::new(export_threshold, exports, local_exports);
|
||||
|
||||
fn export_level(tcx: TyCtxt, sym_def_id: DefId) -> SymbolExportLevel {
|
||||
if tcx.contains_extern_indicator(sym_def_id) {
|
||||
SymbolExportLevel::C
|
||||
} else {
|
||||
SymbolExportLevel::Rust
|
||||
}
|
||||
}
|
||||
Arc::new(crate_exports)
|
||||
};
|
||||
}
|
||||
|
||||
pub fn metadata_symbol_name(tcx: TyCtxt) -> String {
|
||||
format!("rust_metadata_{}_{}",
|
||||
tcx.crate_name(LOCAL_CRATE),
|
||||
tcx.crate_disambiguator(LOCAL_CRATE))
|
||||
}
|
||||
|
||||
pub fn crate_export_threshold(crate_type: config::CrateType)
|
||||
-> SymbolExportLevel {
|
||||
match crate_type {
|
||||
config::CrateTypeExecutable |
|
||||
config::CrateTypeStaticlib |
|
||||
config::CrateTypeProcMacro |
|
||||
config::CrateTypeCdylib => SymbolExportLevel::C,
|
||||
config::CrateTypeRlib |
|
||||
config::CrateTypeDylib => SymbolExportLevel::Rust,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn crates_export_threshold(crate_types: &[config::CrateType])
|
||||
-> SymbolExportLevel {
|
||||
if crate_types.iter().any(|&crate_type| {
|
||||
crate_export_threshold(crate_type) == SymbolExportLevel::Rust
|
||||
}) {
|
||||
SymbolExportLevel::Rust
|
||||
} else {
|
||||
fn export_level(tcx: TyCtxt, sym_def_id: DefId) -> SymbolExportLevel {
|
||||
if tcx.contains_extern_indicator(sym_def_id) {
|
||||
SymbolExportLevel::C
|
||||
} else {
|
||||
SymbolExportLevel::Rust
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,24 +11,27 @@
|
|||
use back::lto;
|
||||
use back::link::{self, get_linker, remove};
|
||||
use back::linker::LinkerInfo;
|
||||
use rustc::middle::exported_symbols::ExportedSymbols;
|
||||
use back::symbol_export::ExportedSymbols;
|
||||
use rustc_incremental::{save_trans_partition, in_incr_comp_dir};
|
||||
use rustc::dep_graph::DepGraph;
|
||||
use rustc::middle::cstore::{LinkMeta, EncodedMetadata};
|
||||
use rustc::session::config::{self, OutputFilenames, OutputType, OutputTypes, Passes, SomePasses,
|
||||
AllPasses, Sanitizer};
|
||||
use rustc::session::Session;
|
||||
use rustc::util::nodemap::FxHashMap;
|
||||
use time_graph::{self, TimeGraph};
|
||||
use llvm;
|
||||
use llvm::{ModuleRef, TargetMachineRef, PassManagerRef, DiagnosticInfoRef};
|
||||
use llvm::SMDiagnosticRef;
|
||||
use {CrateTranslation, ModuleSource, ModuleTranslation, CompiledModule, ModuleKind};
|
||||
use CrateInfo;
|
||||
use rustc::hir::def_id::CrateNum;
|
||||
use rustc::hir::def_id::{CrateNum, LOCAL_CRATE};
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc::util::common::{time, time_depth, set_time_depth, path2cstr, print_time_passes_entry};
|
||||
use rustc::util::fs::{link_or_copy, rename_or_copy_remove};
|
||||
use errors::{self, Handler, Level, DiagnosticBuilder, FatalError};
|
||||
use errors::emitter::{Emitter};
|
||||
use syntax::attr;
|
||||
use syntax::ext::hygiene::Mark;
|
||||
use syntax_pos::MultiSpan;
|
||||
use syntax_pos::symbol::Symbol;
|
||||
|
@ -667,19 +670,40 @@ fn need_crate_bitcode_for_rlib(sess: &Session) -> bool {
|
|||
sess.opts.output_types.contains_key(&OutputType::Exe)
|
||||
}
|
||||
|
||||
pub fn start_async_translation(sess: &Session,
|
||||
pub fn start_async_translation(tcx: TyCtxt,
|
||||
crate_output: &OutputFilenames,
|
||||
time_graph: Option<TimeGraph>,
|
||||
crate_name: Symbol,
|
||||
link: LinkMeta,
|
||||
metadata: EncodedMetadata,
|
||||
exported_symbols: Arc<ExportedSymbols>,
|
||||
no_builtins: bool,
|
||||
windows_subsystem: Option<String>,
|
||||
linker_info: LinkerInfo,
|
||||
crate_info: CrateInfo,
|
||||
no_integrated_as: bool)
|
||||
metadata: EncodedMetadata)
|
||||
-> OngoingCrateTranslation {
|
||||
let sess = tcx.sess;
|
||||
let crate_name = tcx.crate_name(LOCAL_CRATE);
|
||||
let no_builtins = attr::contains_name(&tcx.hir.krate().attrs, "no_builtins");
|
||||
let subsystem = attr::first_attr_value_str_by_name(&tcx.hir.krate().attrs,
|
||||
"windows_subsystem");
|
||||
let windows_subsystem = subsystem.map(|subsystem| {
|
||||
if subsystem != "windows" && subsystem != "console" {
|
||||
tcx.sess.fatal(&format!("invalid windows subsystem `{}`, only \
|
||||
`windows` and `console` are allowed",
|
||||
subsystem));
|
||||
}
|
||||
subsystem.to_string()
|
||||
});
|
||||
|
||||
let no_integrated_as = tcx.sess.opts.cg.no_integrated_as ||
|
||||
(tcx.sess.target.target.options.no_integrated_as &&
|
||||
(crate_output.outputs.contains_key(&OutputType::Object) ||
|
||||
crate_output.outputs.contains_key(&OutputType::Exe)));
|
||||
let linker_info = LinkerInfo::new(tcx);
|
||||
let crate_info = CrateInfo::new(tcx);
|
||||
|
||||
let mut exported_symbols = FxHashMap();
|
||||
exported_symbols.insert(LOCAL_CRATE, tcx.exported_symbols(LOCAL_CRATE));
|
||||
for &cnum in tcx.crates().iter() {
|
||||
exported_symbols.insert(cnum, tcx.exported_symbols(cnum));
|
||||
}
|
||||
let exported_symbols = Arc::new(exported_symbols);
|
||||
|
||||
let output_types_override = if no_integrated_as {
|
||||
OutputTypes::new(&[(OutputType::Assembly, None)])
|
||||
} else {
|
||||
|
|
|
@ -30,7 +30,6 @@ use super::ModuleKind;
|
|||
|
||||
use assert_module_sources;
|
||||
use back::link;
|
||||
use back::linker::LinkerInfo;
|
||||
use back::symbol_export;
|
||||
use back::write::{self, OngoingCrateTranslation};
|
||||
use llvm::{ContextRef, ModuleRef, ValueRef, Vector, get_param};
|
||||
|
@ -44,10 +43,9 @@ use rustc::ty::{self, Ty, TyCtxt};
|
|||
use rustc::ty::maps::Providers;
|
||||
use rustc::dep_graph::AssertDepGraphSafe;
|
||||
use rustc::middle::cstore::{self, LinkMeta, LinkagePreference};
|
||||
use rustc::middle::exported_symbols::ExportedSymbols;
|
||||
use rustc::hir::map as hir_map;
|
||||
use rustc::util::common::{time, print_time_passes_entry};
|
||||
use rustc::session::config::{self, NoDebugInfo, OutputFilenames, OutputType};
|
||||
use rustc::session::config::{self, NoDebugInfo, OutputFilenames};
|
||||
use rustc::session::Session;
|
||||
use rustc_incremental::{self, IncrementalHashesMap};
|
||||
use abi;
|
||||
|
@ -939,11 +937,6 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
-> OngoingCrateTranslation {
|
||||
check_for_rustc_errors_attr(tcx);
|
||||
|
||||
// Be careful with this krate: obviously it gives access to the
|
||||
// entire contents of the krate. So if you push any subtasks of
|
||||
// `TransCrate`, you need to be careful to register "reads" of the
|
||||
// particular items that will be processed.
|
||||
let krate = tcx.hir.krate();
|
||||
let check_overflow = tcx.sess.overflow_checks();
|
||||
let link_meta = link::build_link_meta(&incremental_hashes_map);
|
||||
let exported_symbol_node_ids = find_exported_symbols(tcx);
|
||||
|
@ -967,31 +960,21 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
kind: ModuleKind::Metadata,
|
||||
};
|
||||
|
||||
let no_builtins = attr::contains_name(&krate.attrs, "no_builtins");
|
||||
let time_graph = if tcx.sess.opts.debugging_opts.trans_time_graph {
|
||||
Some(time_graph::TimeGraph::new())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let crate_info = CrateInfo::new(tcx);
|
||||
|
||||
// Skip crate items and just output metadata in -Z no-trans mode.
|
||||
if tcx.sess.opts.debugging_opts.no_trans ||
|
||||
!tcx.sess.opts.output_types.should_trans() {
|
||||
let linker_info = LinkerInfo::new(&shared_ccx);
|
||||
let ongoing_translation = write::start_async_translation(
|
||||
tcx.sess,
|
||||
tcx,
|
||||
output_filenames,
|
||||
time_graph.clone(),
|
||||
tcx.crate_name(LOCAL_CRATE),
|
||||
link_meta,
|
||||
metadata,
|
||||
shared_ccx.tcx().exported_symbols(),
|
||||
no_builtins,
|
||||
None,
|
||||
linker_info,
|
||||
crate_info,
|
||||
false);
|
||||
metadata);
|
||||
|
||||
ongoing_translation.submit_pre_translated_module_to_llvm(tcx.sess, metadata_module, true);
|
||||
|
||||
|
@ -1012,36 +995,12 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
|
||||
assert!(codegen_units.len() <= 1 || !tcx.sess.lto());
|
||||
|
||||
let linker_info = LinkerInfo::new(&shared_ccx);
|
||||
let subsystem = attr::first_attr_value_str_by_name(&krate.attrs,
|
||||
"windows_subsystem");
|
||||
let windows_subsystem = subsystem.map(|subsystem| {
|
||||
if subsystem != "windows" && subsystem != "console" {
|
||||
tcx.sess.fatal(&format!("invalid windows subsystem `{}`, only \
|
||||
`windows` and `console` are allowed",
|
||||
subsystem));
|
||||
}
|
||||
subsystem.to_string()
|
||||
});
|
||||
|
||||
let no_integrated_as = tcx.sess.opts.cg.no_integrated_as ||
|
||||
(tcx.sess.target.target.options.no_integrated_as &&
|
||||
(output_filenames.outputs.contains_key(&OutputType::Object) ||
|
||||
output_filenames.outputs.contains_key(&OutputType::Exe)));
|
||||
|
||||
let ongoing_translation = write::start_async_translation(
|
||||
tcx.sess,
|
||||
tcx,
|
||||
output_filenames,
|
||||
time_graph.clone(),
|
||||
tcx.crate_name(LOCAL_CRATE),
|
||||
link_meta,
|
||||
metadata,
|
||||
tcx.exported_symbols(),
|
||||
no_builtins,
|
||||
windows_subsystem,
|
||||
linker_info,
|
||||
crate_info,
|
||||
no_integrated_as);
|
||||
metadata);
|
||||
|
||||
// Translate an allocator shim, if any
|
||||
//
|
||||
|
@ -1118,8 +1077,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
tcx.dep_graph.with_task(dep_node,
|
||||
AssertDepGraphSafe(&shared_ccx),
|
||||
AssertDepGraphSafe((cgu,
|
||||
translation_items.clone(),
|
||||
tcx.exported_symbols())),
|
||||
translation_items.clone())),
|
||||
module_translation);
|
||||
all_stats.extend(stats);
|
||||
|
||||
|
@ -1161,13 +1119,12 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
fn module_translation<'a, 'tcx>(
|
||||
scx: AssertDepGraphSafe<&SharedCrateContext<'a, 'tcx>>,
|
||||
args: AssertDepGraphSafe<(Arc<CodegenUnit<'tcx>>,
|
||||
Arc<FxHashSet<TransItem<'tcx>>>,
|
||||
Arc<ExportedSymbols>)>)
|
||||
Arc<FxHashSet<TransItem<'tcx>>>)>)
|
||||
-> (Stats, ModuleTranslation)
|
||||
{
|
||||
// FIXME(#40304): We ought to be using the id as a key and some queries, I think.
|
||||
let AssertDepGraphSafe(scx) = scx;
|
||||
let AssertDepGraphSafe((cgu, crate_trans_items, exported_symbols)) = args;
|
||||
let AssertDepGraphSafe((cgu, crate_trans_items)) = args;
|
||||
|
||||
let cgu_name = cgu.name().to_string();
|
||||
let cgu_id = cgu.work_product_id();
|
||||
|
@ -1207,7 +1164,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
}
|
||||
|
||||
// Instantiate translation items without filling out definitions yet...
|
||||
let lcx = LocalCrateContext::new(scx, cgu, crate_trans_items, exported_symbols);
|
||||
let lcx = LocalCrateContext::new(scx, cgu, crate_trans_items);
|
||||
let module = {
|
||||
let ccx = CrateContext::new(scx, &lcx);
|
||||
let trans_items = ccx.codegen_unit()
|
||||
|
@ -1400,7 +1357,6 @@ fn collect_and_partition_translation_items<'a, 'tcx>(
|
|||
{
|
||||
assert_eq!(cnum, LOCAL_CRATE);
|
||||
let time_passes = tcx.sess.time_passes();
|
||||
let exported_symbols = tcx.exported_symbols();
|
||||
|
||||
let collection_mode = match tcx.sess.opts.debugging_opts.print_trans_items {
|
||||
Some(ref s) => {
|
||||
|
@ -1424,9 +1380,7 @@ fn collect_and_partition_translation_items<'a, 'tcx>(
|
|||
|
||||
let (items, inlining_map) =
|
||||
time(time_passes, "translation item collection", || {
|
||||
collector::collect_crate_translation_items(tcx,
|
||||
&exported_symbols,
|
||||
collection_mode)
|
||||
collector::collect_crate_translation_items(tcx, collection_mode)
|
||||
});
|
||||
|
||||
assert_symbols_are_distinct(tcx, items.iter());
|
||||
|
@ -1441,8 +1395,7 @@ fn collect_and_partition_translation_items<'a, 'tcx>(
|
|||
partitioning::partition(tcx,
|
||||
items.iter().cloned(),
|
||||
strategy,
|
||||
&inlining_map,
|
||||
&exported_symbols)
|
||||
&inlining_map)
|
||||
.into_iter()
|
||||
.map(Arc::new)
|
||||
.collect::<Vec<_>>()
|
||||
|
@ -1510,7 +1463,7 @@ fn collect_and_partition_translation_items<'a, 'tcx>(
|
|||
}
|
||||
|
||||
impl CrateInfo {
|
||||
pub fn new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CrateInfo {
|
||||
pub fn new(tcx: TyCtxt) -> CrateInfo {
|
||||
let mut info = CrateInfo {
|
||||
panic_runtime: None,
|
||||
compiler_builtins: None,
|
||||
|
|
|
@ -114,8 +114,8 @@ pub fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||
llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::ExternalLinkage);
|
||||
|
||||
if ccx.crate_trans_items().contains(&TransItem::Fn(instance)) {
|
||||
if let Some(node_id) = tcx.hir.as_local_node_id(instance_def_id) {
|
||||
if !ccx.exported_symbols().local_exports().contains(&node_id) {
|
||||
if instance_def_id.is_local() {
|
||||
if !ccx.tcx().is_exported_symbol(instance_def_id) {
|
||||
llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -194,7 +194,6 @@ use rustc::hir::itemlikevisit::ItemLikeVisitor;
|
|||
use rustc::hir::map as hir_map;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::middle::const_val::ConstVal;
|
||||
use rustc::middle::exported_symbols::ExportedSymbols;
|
||||
use rustc::middle::lang_items::{ExchangeMallocFnLangItem};
|
||||
use rustc::traits;
|
||||
use rustc::ty::subst::Substs;
|
||||
|
@ -294,14 +293,13 @@ impl<'tcx> InliningMap<'tcx> {
|
|||
}
|
||||
|
||||
pub fn collect_crate_translation_items<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
exported_symbols: &ExportedSymbols,
|
||||
mode: TransItemCollectionMode)
|
||||
-> (FxHashSet<TransItem<'tcx>>,
|
||||
InliningMap<'tcx>) {
|
||||
// We are not tracking dependencies of this pass as it has to be re-executed
|
||||
// every time no matter what.
|
||||
tcx.dep_graph.with_ignore(|| {
|
||||
let roots = collect_roots(tcx, exported_symbols, mode);
|
||||
let roots = collect_roots(tcx, mode);
|
||||
|
||||
debug!("Building translation item graph, beginning at roots");
|
||||
let mut visited = FxHashSet();
|
||||
|
@ -323,7 +321,6 @@ pub fn collect_crate_translation_items<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
// Find all non-generic items by walking the HIR. These items serve as roots to
|
||||
// start monomorphizing from.
|
||||
fn collect_roots<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
exported_symbols: &ExportedSymbols,
|
||||
mode: TransItemCollectionMode)
|
||||
-> Vec<TransItem<'tcx>> {
|
||||
debug!("Collecting roots");
|
||||
|
@ -333,7 +330,6 @@ fn collect_roots<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
let mut visitor = RootCollector {
|
||||
tcx,
|
||||
mode,
|
||||
exported_symbols,
|
||||
output: &mut roots,
|
||||
};
|
||||
|
||||
|
@ -865,7 +861,6 @@ fn create_trans_items_for_vtable_methods<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
|
||||
struct RootCollector<'b, 'a: 'b, 'tcx: 'a + 'b> {
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
exported_symbols: &'b ExportedSymbols,
|
||||
mode: TransItemCollectionMode,
|
||||
output: &'b mut Vec<TransItem<'tcx>>,
|
||||
}
|
||||
|
@ -926,8 +921,7 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> {
|
|||
let def_id = tcx.hir.local_def_id(item.id);
|
||||
|
||||
if (self.mode == TransItemCollectionMode::Eager ||
|
||||
!tcx.is_const_fn(def_id) ||
|
||||
self.exported_symbols.local_exports().contains(&item.id)) &&
|
||||
!tcx.is_const_fn(def_id) || tcx.is_exported_symbol(def_id)) &&
|
||||
!item_has_type_parameters(tcx, def_id) {
|
||||
|
||||
debug!("RootCollector: ItemFn({})",
|
||||
|
@ -953,7 +947,7 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> {
|
|||
|
||||
if (self.mode == TransItemCollectionMode::Eager ||
|
||||
!tcx.is_const_fn(def_id) ||
|
||||
self.exported_symbols.local_exports().contains(&ii.id)) &&
|
||||
tcx.is_exported_symbol(def_id)) &&
|
||||
!item_has_type_parameters(tcx, def_id) {
|
||||
debug!("RootCollector: MethodImplItem({})",
|
||||
def_id_to_string(tcx, def_id));
|
||||
|
|
|
@ -130,7 +130,7 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef {
|
|||
|
||||
let g = declare::define_global(ccx, &sym[..], llty).unwrap();
|
||||
|
||||
if !ccx.exported_symbols().local_exports().contains(&id) {
|
||||
if !ccx.tcx().is_exported_symbol(def_id) {
|
||||
unsafe {
|
||||
llvm::LLVMRustSetVisibility(g, llvm::Visibility::Hidden);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ use llvm::{ContextRef, ModuleRef, ValueRef};
|
|||
use rustc::dep_graph::{DepGraph, DepGraphSafe};
|
||||
use rustc::hir;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::middle::exported_symbols::ExportedSymbols;
|
||||
use rustc::traits;
|
||||
use debuginfo;
|
||||
use callee;
|
||||
|
@ -98,9 +97,6 @@ pub struct LocalCrateContext<'a, 'tcx: 'a> {
|
|||
/// The translation items of the whole crate.
|
||||
crate_trans_items: Arc<FxHashSet<TransItem<'tcx>>>,
|
||||
|
||||
/// Information about which symbols are exported from the crate.
|
||||
exported_symbols: Arc<ExportedSymbols>,
|
||||
|
||||
/// Cache instances of monomorphic and polymorphic items
|
||||
instances: RefCell<FxHashMap<Instance<'tcx>, ValueRef>>,
|
||||
/// Cache generated vtables
|
||||
|
@ -354,8 +350,7 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
|
|||
impl<'a, 'tcx> LocalCrateContext<'a, 'tcx> {
|
||||
pub fn new(shared: &SharedCrateContext<'a, 'tcx>,
|
||||
codegen_unit: Arc<CodegenUnit<'tcx>>,
|
||||
crate_trans_items: Arc<FxHashSet<TransItem<'tcx>>>,
|
||||
exported_symbols: Arc<ExportedSymbols>,)
|
||||
crate_trans_items: Arc<FxHashSet<TransItem<'tcx>>>)
|
||||
-> LocalCrateContext<'a, 'tcx> {
|
||||
unsafe {
|
||||
// Append ".rs" to LLVM module identifier.
|
||||
|
@ -388,7 +383,6 @@ impl<'a, 'tcx> LocalCrateContext<'a, 'tcx> {
|
|||
stats: Stats::default(),
|
||||
codegen_unit,
|
||||
crate_trans_items,
|
||||
exported_symbols,
|
||||
instances: RefCell::new(FxHashMap()),
|
||||
vtables: RefCell::new(FxHashMap()),
|
||||
const_cstr_cache: RefCell::new(FxHashMap()),
|
||||
|
@ -499,10 +493,6 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
|
|||
&self.local().crate_trans_items
|
||||
}
|
||||
|
||||
pub fn exported_symbols(&self) -> &ExportedSymbols {
|
||||
&self.local().exported_symbols
|
||||
}
|
||||
|
||||
pub fn td(&self) -> llvm::TargetDataRef {
|
||||
unsafe { llvm::LLVMRustGetModuleDataLayout(self.llmod()) }
|
||||
}
|
||||
|
|
|
@ -37,7 +37,8 @@ pub fn is_node_local_to_unit(cx: &CrateContext, node_id: ast::NodeId) -> bool
|
|||
// visible). It might better to use the `exported_items` set from
|
||||
// `driver::CrateAnalysis` in the future, but (atm) this set is not
|
||||
// available in the translation pass.
|
||||
!cx.exported_symbols().local_exports().contains(&node_id)
|
||||
let def_id = cx.tcx().hir.local_def_id(node_id);
|
||||
!cx.tcx().is_exported_symbol(def_id)
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
|
|
|
@ -69,9 +69,8 @@ pub use metadata::LlvmMetadataLoader;
|
|||
pub use llvm_util::{init, target_features, print_version, print_passes, print, enable_llvm_debug};
|
||||
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
use rustc::hir::def_id::{CrateNum, LOCAL_CRATE};
|
||||
use rustc::hir::def_id::CrateNum;
|
||||
use rustc::middle::cstore::{NativeLibrary, CrateSource, LibSource};
|
||||
use rustc::ty::maps::Providers;
|
||||
use rustc::util::nodemap::{FxHashSet, FxHashMap};
|
||||
|
@ -251,13 +250,11 @@ __build_diagnostic_array! { librustc_trans, DIAGNOSTICS }
|
|||
|
||||
pub fn provide_local(providers: &mut Providers) {
|
||||
back::symbol_names::provide(providers);
|
||||
back::symbol_export::provide_local(providers);
|
||||
base::provide(providers);
|
||||
providers.exported_symbol_set = |tcx, cnum| {
|
||||
assert_eq!(cnum, LOCAL_CRATE);
|
||||
Arc::new(back::symbol_export::compute(tcx))
|
||||
};
|
||||
}
|
||||
|
||||
pub fn provide_extern(providers: &mut Providers) {
|
||||
back::symbol_names::provide(providers);
|
||||
back::symbol_export::provide_extern(providers);
|
||||
}
|
||||
|
|
|
@ -108,7 +108,6 @@ use context::SharedCrateContext;
|
|||
use rustc::dep_graph::{DepNode, WorkProductId};
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::hir::map::DefPathData;
|
||||
use rustc::middle::exported_symbols::ExportedSymbols;
|
||||
use rustc::middle::trans::{Linkage, Visibility};
|
||||
use rustc::session::config::NUMBERED_CODEGEN_UNIT_MARKER;
|
||||
use rustc::ty::{self, TyCtxt, InstanceDef};
|
||||
|
@ -212,8 +211,7 @@ const FALLBACK_CODEGEN_UNIT: &'static str = "__rustc_fallback_codegen_unit";
|
|||
pub fn partition<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
trans_items: I,
|
||||
strategy: PartitioningStrategy,
|
||||
inlining_map: &InliningMap<'tcx>,
|
||||
exported_symbols: &ExportedSymbols)
|
||||
inlining_map: &InliningMap<'tcx>)
|
||||
-> Vec<CodegenUnit<'tcx>>
|
||||
where I: Iterator<Item = TransItem<'tcx>>
|
||||
{
|
||||
|
@ -221,7 +219,6 @@ pub fn partition<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
// respective 'home' codegen unit. Regular translation items are all
|
||||
// functions and statics defined in the local crate.
|
||||
let mut initial_partitioning = place_root_translation_items(tcx,
|
||||
exported_symbols,
|
||||
trans_items);
|
||||
|
||||
debug_dump(tcx, "INITIAL PARTITIONING:", initial_partitioning.codegen_units.iter());
|
||||
|
@ -291,13 +288,10 @@ struct PostInliningPartitioning<'tcx> {
|
|||
}
|
||||
|
||||
fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
exported_symbols: &ExportedSymbols,
|
||||
trans_items: I)
|
||||
-> PreInliningPartitioning<'tcx>
|
||||
where I: Iterator<Item = TransItem<'tcx>>
|
||||
{
|
||||
let exported_symbols = exported_symbols.local_exports();
|
||||
|
||||
let mut roots = FxHashSet();
|
||||
let mut codegen_units = FxHashMap();
|
||||
let is_incremental_build = tcx.sess.opts.incremental.is_some();
|
||||
|
@ -330,8 +324,8 @@ fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
TransItem::Fn(ref instance) => {
|
||||
let visibility = match instance.def {
|
||||
InstanceDef::Item(def_id) => {
|
||||
if let Some(node_id) = tcx.hir.as_local_node_id(def_id) {
|
||||
if exported_symbols.contains(&node_id) {
|
||||
if def_id.is_local() {
|
||||
if tcx.is_exported_symbol(def_id) {
|
||||
Visibility::Default
|
||||
} else {
|
||||
internalization_candidates.insert(trans_item);
|
||||
|
@ -357,7 +351,8 @@ fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
}
|
||||
TransItem::Static(node_id) |
|
||||
TransItem::GlobalAsm(node_id) => {
|
||||
let visibility = if exported_symbols.contains(&node_id) {
|
||||
let def_id = tcx.hir.local_def_id(node_id);
|
||||
let visibility = if tcx.is_exported_symbol(def_id) {
|
||||
Visibility::Default
|
||||
} else {
|
||||
internalization_candidates.insert(trans_item);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue