提交 afb85cfd 编写于 作者: A Alex Crichton

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!
上级 8821affd
......@@ -575,7 +575,7 @@ pub fn to_dep_node(self, tcx: TyCtxt, kind: DepKind) -> DepNode {
[] 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::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::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 @@ pub fn metadata_encoding_version(self) -> Vec<u8> {
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::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 @@ fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
}
}
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 @@ fn default() -> Self {
[] 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 @@ fn default() -> Self {
[] 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::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 @@ pub fn get_fn_arg_names(&self, id: DefIndex) -> Vec<ast::Name> {
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::{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 @@ fn finalize(&mut self) -> Command {
}
}
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 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();
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 threshold(tcx: TyCtxt) -> SymbolExportLevel {
crates_export_threshold(&tcx.sess.crate_types.borrow())
}
const INVALID_DEF_ID: DefId = DefId {
krate: INVALID_CRATE,
index: CRATE_DEF_INDEX,
};
pub fn metadata_symbol_name(tcx: TyCtxt) -> String {
format!("rust_metadata_{}_{}",
tcx.crate_name(LOCAL_CRATE),
tcx.crate_disambiguator(LOCAL_CRATE))
}
if let Some(_) = *tcx.sess.entry_fn.borrow() {
local_crate.push(("main".to_string(),
INVALID_DEF_ID,
SymbolExportLevel::C));
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,
}
}
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));
}
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
}
}
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);
}
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 tcx.sess.crate_types.borrow().contains(&config::CrateTypeDylib) {
local_crate.push((metadata_symbol_name(tcx),
INVALID_DEF_ID,
SymbolExportLevel::Rust));
}
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)
})
};
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));
}
let mut exports = FxHashMap();
exports.insert(LOCAL_CRATE, local_crate);
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));
}
}
for &cnum in tcx.crates().iter() {
debug_assert!(cnum != LOCAL_CRATE);
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));
}
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
}
}
}
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,
}
Arc::new(crate_exports)
};
}
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 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::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 @@ fn module_translation<'a, '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::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 @@ pub fn iter_accesses<F>(&self, mut f: F)
}
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 @@ fn visit_item(&mut self, item: &'v hir::Item) {
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 @@ fn visit_impl_item(&mut self, ii: &'v hir::ImplItem) {
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 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 @@ pub fn output_filenames(&self) -> &OutputFilenames {
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 @@ pub fn new(shared: &SharedCrateContext<'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 @@ pub fn crate_trans_items(&self) -> &FxHashSet<TransItem<'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 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 @@ pub struct CrateInfo {
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 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 @@ fn as_codegen_unit(&self) -> &CodegenUnit<'tcx> {
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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册