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

rustc: Calculate `ExportedSymbols` in a query

This commit moves the definition of the `ExportedSymbols` structure to the
`rustc` crate and then creates a query that'll be used to construct the
`ExportedSymbols` set. This in turn uses the reachablity query exposed in the
previous commit.
上级 baca9a62
......@@ -535,7 +535,7 @@ pub fn to_dep_node(self, tcx: TyCtxt, kind: DepKind) -> DepNode {
[] GetPanicStrategy(CrateNum),
[] IsNoBuiltins(CrateNum),
[] ImplDefaultness(DefId),
[] ExportedSymbols(CrateNum),
[] ExportedSymbolIds(CrateNum),
[] NativeLibraries(CrateNum),
[] PluginRegistrarFn(CrateNum),
[] DeriveRegistrarFn(CrateNum),
......@@ -575,6 +575,7 @@ pub fn to_dep_node(self, tcx: TyCtxt, kind: DepKind) -> DepNode {
[] MaybeUnusedExternCrates,
[] StabilityIndex,
[] AllCrateNums,
[] ExportedSymbols,
);
trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {
......
......@@ -92,6 +92,7 @@ pub mod middle {
pub mod dependency_format;
pub mod effect;
pub mod entry;
pub mod exported_symbols;
pub mod free_region;
pub mod intrinsicck;
pub mod lang_items;
......
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// 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.
/// `Rust` will only be exported if the crate produced is a Rust
/// dylib.
#[derive(Eq, PartialEq, Debug, Copy, Clone)]
pub enum SymbolExportLevel {
C,
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)
}
}
}
}
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,6 +27,7 @@
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;
......@@ -64,6 +65,7 @@
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;
......@@ -1218,6 +1220,10 @@ 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,6 +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 mir;
use mir::transform::{MirSuite, MirPassIndex};
use session::CompileResult;
......@@ -48,6 +49,7 @@
use std::collections::BTreeMap;
use std::ops::Deref;
use std::rc::Rc;
use std::sync::Arc;
use syntax_pos::{Span, DUMMY_SP};
use syntax::attr;
use syntax::ast;
......@@ -595,7 +597,7 @@ fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
}
}
impl<'tcx> QueryDescription for queries::exported_symbols<'tcx> {
impl<'tcx> QueryDescription for queries::exported_symbol_ids<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("looking up the exported symbols of a crate")
}
......@@ -745,6 +747,12 @@ fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
}
}
impl<'tcx> QueryDescription for queries::exported_symbol_set<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("exported symbol set")
}
}
// If enabled, send a message to the profile-queries thread
macro_rules! profq_msg {
($tcx:expr, $msg:expr) => {
......@@ -1322,7 +1330,7 @@ fn default() -> Self {
[] fn lint_levels: lint_levels_node(CrateNum) -> Rc<lint::LintLevelMap>,
[] fn impl_defaultness: ImplDefaultness(DefId) -> hir::Defaultness,
[] fn exported_symbols: ExportedSymbols(CrateNum) -> Rc<Vec<DefId>>,
[] fn exported_symbol_ids: ExportedSymbolIds(CrateNum) -> Rc<Vec<DefId>>,
[] fn native_libraries: NativeLibraries(CrateNum) -> Rc<Vec<NativeLibrary>>,
[] fn plugin_registrar_fn: PluginRegistrarFn(CrateNum) -> Option<DefId>,
[] fn derive_registrar_fn: DeriveRegistrarFn(CrateNum) -> Option<DefId>,
......@@ -1371,6 +1379,9 @@ 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 type_param_predicates<'tcx>((item_id, param_id): (DefId, DefId)) -> DepConstructor<'tcx> {
......@@ -1484,3 +1495,7 @@ fn stability_index_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
fn all_crate_nums_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
DepConstructor::AllCrateNums
}
fn exported_symbol_set_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
DepConstructor::ExportedSymbols
}
......@@ -956,7 +956,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
mir::provide(&mut local_providers);
reachable::provide(&mut local_providers);
rustc_privacy::provide(&mut local_providers);
trans::provide(&mut local_providers);
trans::provide_local(&mut local_providers);
typeck::provide(&mut local_providers);
ty::provide(&mut local_providers);
traits::provide(&mut local_providers);
......@@ -968,7 +968,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
let mut extern_providers = ty::maps::Providers::default();
cstore::provide(&mut extern_providers);
trans::provide(&mut extern_providers);
trans::provide_extern(&mut extern_providers);
ty::provide_extern(&mut extern_providers);
traits::provide_extern(&mut extern_providers);
// FIXME(eddyb) get rid of this once we replace const_eval with miri.
......
......@@ -175,7 +175,7 @@ fn into_args(self) -> (DefId, DefId) { (self.0.as_def_id(), self.1) }
extern_crate => { Rc::new(cdata.extern_crate.get()) }
is_no_builtins => { cdata.is_no_builtins() }
impl_defaultness => { cdata.get_impl_defaultness(def_id.index) }
exported_symbols => { Rc::new(cdata.get_exported_symbols()) }
exported_symbol_ids => { Rc::new(cdata.get_exported_symbols()) }
native_libraries => { Rc::new(cdata.get_native_libraries()) }
plugin_registrar_fn => {
cdata.root.plugin_registrar_fn.map(|index| {
......
......@@ -19,8 +19,8 @@
use back::archive;
use back::command::Command;
use back::symbol_export::ExportedSymbols;
use rustc::middle::dependency_format::Linkage;
use rustc::middle::exported_symbols::ExportedSymbols;
use rustc::hir::def_id::{LOCAL_CRATE, CrateNum};
use rustc_back::LinkerFlavor;
use rustc::session::Session;
......
......@@ -16,6 +16,7 @@
use llvm;
use llvm::archive_ro::ArchiveRO;
use llvm::{ModuleRef, TargetMachineRef, True, False};
use rustc::middle::exported_symbols;
use rustc::util::common::time;
use rustc::util::common::path2cstr;
use rustc::hir::def_id::LOCAL_CRATE;
......@@ -68,7 +69,7 @@ pub fn run(cgcx: &CodegenContext,
symbol_export::crates_export_threshold(&cgcx.crate_types);
let symbol_filter = &|&(ref name, _, level): &(String, _, _)| {
if symbol_export::is_below_threshold(level, export_threshold) {
if exported_symbols::is_below_threshold(level, export_threshold) {
let mut bytes = Vec::with_capacity(name.len() + 1);
bytes.extend(name.bytes());
Some(CString::new(bytes).unwrap())
......
......@@ -8,199 +8,143 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use base;
use monomorphize::Instance;
use rustc::util::nodemap::{FxHashMap, NodeSet};
use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE, INVALID_CRATE, CRATE_DEF_INDEX};
use rustc::hir::def_id::{DefId, LOCAL_CRATE, INVALID_CRATE, CRATE_DEF_INDEX};
use rustc::session::config;
use rustc::ty::TyCtxt;
use rustc_allocator::ALLOCATOR_METHODS;
use rustc::middle::exported_symbols::{ExportedSymbols, SymbolExportLevel};
use rustc::middle::exported_symbols::is_below_threshold;
use syntax::attr;
/// 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.
/// `Rust` will only be exported if the crate produced is a Rust
/// dylib.
#[derive(Eq, PartialEq, Debug, Copy, Clone)]
pub enum SymbolExportLevel {
C,
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 empty() -> ExportedSymbols {
ExportedSymbols {
export_threshold: SymbolExportLevel::C,
exports: FxHashMap(),
local_exports: NodeSet(),
}
}
pub fn compute<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
local_exported_symbols: &NodeSet)
-> ExportedSymbols {
let export_threshold = crates_export_threshold(&tcx.sess.crate_types.borrow());
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>();
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));
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);
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
}
}
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);
}
})
.collect::<NodeSet>();
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.crate_types.borrow().contains(&config::CrateTypeDylib) {
local_crate.push((metadata_symbol_name(tcx),
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));
}
}
let mut exports = FxHashMap();
exports.insert(LOCAL_CRATE, 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));
local_exports.insert(id);
}
for &cnum in tcx.crates().iter() {
debug_assert!(cnum != LOCAL_CRATE);
if tcx.sess.crate_types.borrow().contains(&config::CrateTypeDylib) {
local_crate.push((metadata_symbol_name(tcx),
INVALID_DEF_ID,
SymbolExportLevel::Rust));
}
// 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;
}
let mut exports = FxHashMap();
exports.insert(LOCAL_CRATE, local_crate);
// Check to see if this crate is a "special runtime crate". These
// crates, implementation details of the standard library, typically
// have a bunch of `pub extern` and `#[no_mangle]` functions as the
// ABI between them. We don't want their symbols to have a `C`
// export level, however, as they're just implementation details.
// Down below we'll hardwire all of the symbols to the `Rust` export
// level instead.
let special_runtime_crate =
tcx.is_panic_runtime(cnum) || tcx.is_compiler_builtins(cnum);
let crate_exports = tcx
.exported_symbols(cnum)
.iter()
.map(|&def_id| {
let name = tcx.symbol_name(Instance::mono(tcx, def_id));
let export_level = if special_runtime_crate {
// We can probably do better here by just ensuring that
// it has hidden visibility rather than public
// visibility, as this is primarily here to ensure it's
// not stripped during LTO.
//
// In general though we won't link right if these
// symbols are stripped, and LTO currently strips them.
if &*name == "rust_eh_personality" ||
&*name == "rust_eh_register_frames" ||
&*name == "rust_eh_unregister_frames" {
SymbolExportLevel::C
} else {
SymbolExportLevel::Rust
}
} else {
export_level(tcx, def_id)
};
debug!("EXPORTED SYMBOL (re-export): {} ({:?})", name, export_level);
(str::to_owned(&name), def_id, export_level)
})
.collect();
exports.insert(cnum, crate_exports);
}
for &cnum in tcx.crates().iter() {
debug_assert!(cnum != LOCAL_CRATE);
return ExportedSymbols {
export_threshold,
exports,
local_exports,
};
fn export_level(tcx: TyCtxt,
sym_def_id: DefId)
-> SymbolExportLevel {
let attrs = tcx.get_attrs(sym_def_id);
if attr::contains_extern_indicator(tcx.sess.diagnostic(), &attrs) {
SymbolExportLevel::C
} else {
SymbolExportLevel::Rust
}
// 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;
}
}
pub fn local_exports(&self) -> &NodeSet {
&self.local_exports
}
// Check to see if this crate is a "special runtime crate". These
// crates, implementation details of the standard library, typically
// have a bunch of `pub extern` and `#[no_mangle]` functions as the
// ABI between them. We don't want their symbols to have a `C`
// export level, however, as they're just implementation details.
// Down below we'll hardwire all of the symbols to the `Rust` export
// level instead.
let special_runtime_crate =
tcx.is_panic_runtime(cnum) || tcx.is_compiler_builtins(cnum);
let crate_exports = tcx
.exported_symbol_ids(cnum)
.iter()
.map(|&def_id| {
let name = tcx.symbol_name(Instance::mono(tcx, def_id));
let export_level = if special_runtime_crate {
// We can probably do better here by just ensuring that
// it has hidden visibility rather than public
// visibility, as this is primarily here to ensure it's
// not stripped during LTO.
//
// In general though we won't link right if these
// symbols are stripped, and LTO currently strips them.
if &*name == "rust_eh_personality" ||
&*name == "rust_eh_register_frames" ||
&*name == "rust_eh_unregister_frames" {
SymbolExportLevel::C
} else {
SymbolExportLevel::Rust
}
} else {
export_level(tcx, def_id)
};
debug!("EXPORTED SYMBOL (re-export): {} ({:?})", name, export_level);
(str::to_owned(&name), def_id, export_level)
})
.collect();
pub fn exported_symbols(&self,
cnum: CrateNum)
-> &[(String, DefId, SymbolExportLevel)] {
match self.exports.get(&cnum) {
Some(exports) => exports,
None => &[]
}
exports.insert(cnum, crate_exports);
}
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)
}
return ExportedSymbols::new(export_threshold, exports, local_exports);
fn export_level(tcx: TyCtxt,
sym_def_id: DefId)
-> SymbolExportLevel {
let attrs = tcx.get_attrs(sym_def_id);
if attr::contains_extern_indicator(tcx.sess.diagnostic(), &attrs) {
SymbolExportLevel::C
} else {
SymbolExportLevel::Rust
}
}
}
......@@ -233,14 +177,3 @@ pub fn crates_export_threshold(crate_types: &[config::CrateType])
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
}
}
......@@ -11,7 +11,7 @@
use back::lto;
use back::link::{self, get_linker, remove};
use back::linker::LinkerInfo;
use back::symbol_export::ExportedSymbols;
use rustc::middle::exported_symbols::ExportedSymbols;
use rustc_incremental::{save_trans_partition, in_incr_comp_dir};
use rustc::dep_graph::DepGraph;
use rustc::middle::cstore::{LinkMeta, EncodedMetadata};
......
......@@ -31,7 +31,7 @@
use assert_module_sources;
use back::link;
use back::linker::LinkerInfo;
use back::symbol_export::{self, ExportedSymbols};
use back::symbol_export;
use back::write::{self, OngoingCrateTranslation};
use llvm::{ContextRef, Linkage, ModuleRef, ValueRef, Vector, get_param};
use llvm;
......@@ -42,6 +42,7 @@
use rustc::ty::{self, Ty, TyCtxt};
use rustc::dep_graph::AssertDepGraphSafe;
use rustc::middle::cstore::{self, LinkMeta, LinkagePreference};
use rustc::middle::exported_symbols::{ExportedSymbols, SymbolExportLevel};
use rustc::hir::map as hir_map;
use rustc::util::common::{time, print_time_passes_entry};
use rustc::session::config::{self, NoDebugInfo, OutputFilenames, OutputType};
......@@ -973,7 +974,11 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, '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 empty_exported_symbols = ExportedSymbols::empty();
let empty_exported_symbols = ExportedSymbols::new(
SymbolExportLevel::C,
Default::default(),
Default::default(),
);
let linker_info = LinkerInfo::new(&shared_ccx, &empty_exported_symbols);
let ongoing_translation = write::start_async_translation(
tcx.sess,
......@@ -1001,13 +1006,12 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
return ongoing_translation;
}
let exported_symbols = Arc::new(ExportedSymbols::compute(tcx,
&exported_symbol_node_ids));
let exported_symbols = tcx.exported_symbols();
// Run the translation item collector and partition the collected items into
// codegen units.
let (translation_items, codegen_units) =
collect_and_partition_translation_items(&shared_ccx, &exported_symbols);
collect_and_partition_translation_items(shared_ccx.tcx(), &exported_symbols);
assert!(codegen_units.len() <= 1 || !tcx.sess.lto());
......@@ -1394,13 +1398,13 @@ fn assert_symbols_are_distinct<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trans_i
}
}
fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
fn collect_and_partition_translation_items<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
exported_symbols: &ExportedSymbols)
-> (FxHashSet<TransItem<'tcx>>,
Vec<CodegenUnit<'tcx>>) {
let time_passes = scx.sess().time_passes();
let time_passes = tcx.sess.time_passes();
let collection_mode = match scx.sess().opts.debugging_opts.print_trans_items {
let collection_mode = match tcx.sess.opts.debugging_opts.print_trans_items {
Some(ref s) => {
let mode_string = s.to_lowercase();
let mode_string = mode_string.trim();
......@@ -1411,7 +1415,7 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
let message = format!("Unknown codegen-item collection mode '{}'. \
Falling back to 'lazy' mode.",
mode_string);
scx.sess().warn(&message);
tcx.sess.warn(&message);
}
TransItemCollectionMode::Lazy
......@@ -1422,33 +1426,33 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
let (items, inlining_map) =
time(time_passes, "translation item collection", || {
collector::collect_crate_translation_items(scx.tcx(),
collector::collect_crate_translation_items(tcx,
exported_symbols,
collection_mode)
});
assert_symbols_are_distinct(scx.tcx(), items.iter());
assert_symbols_are_distinct(tcx, items.iter());
let strategy = if scx.sess().opts.debugging_opts.incremental.is_some() {
let strategy = if tcx.sess.opts.debugging_opts.incremental.is_some() {
PartitioningStrategy::PerModule
} else {
PartitioningStrategy::FixedUnitCount(scx.sess().opts.cg.codegen_units)
PartitioningStrategy::FixedUnitCount(tcx.sess.opts.cg.codegen_units)
};
let codegen_units = time(time_passes, "codegen unit partitioning", || {
partitioning::partition(scx.tcx(),
partitioning::partition(tcx,
items.iter().cloned(),
strategy,
&inlining_map,
exported_symbols)
});
assert!(scx.tcx().sess.opts.cg.codegen_units == codegen_units.len() ||
scx.tcx().sess.opts.debugging_opts.incremental.is_some());
assert!(tcx.sess.opts.cg.codegen_units == codegen_units.len() ||
tcx.sess.opts.debugging_opts.incremental.is_some());
let translation_items: FxHashSet<TransItem<'tcx>> = items.iter().cloned().collect();
if scx.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();
for cgu in &codegen_units {
......@@ -1462,7 +1466,7 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
let mut item_keys: Vec<_> = items
.iter()
.map(|i| {
let mut output = i.to_string(scx.tcx());
let mut output = i.to_string(tcx);
output.push_str(" @@");
let mut empty = Vec::new();
let cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty);
......
......@@ -194,6 +194,7 @@
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;
......@@ -209,7 +210,6 @@
use trans_item::{TransItem, DefPathBasedNames, InstantiationMode};
use rustc_data_structures::bitvec::BitVector;
use back::symbol_export::ExportedSymbols;
#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)]
pub enum TransItemCollectionMode {
......
......@@ -14,10 +14,10 @@
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;
use back::symbol_export::ExportedSymbols;
use base;
use declare;
use monomorphize::Instance;
......
......@@ -64,16 +64,17 @@
extern crate gcc; // Used to locate MSVC, not gcc :)
pub use base::trans_crate;
pub use back::symbol_names::provide;
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;
use rustc::util::nodemap::{FxHashSet, FxHashMap};
use rustc::hir::def_id::{CrateNum, LOCAL_CRATE};
use rustc::middle::cstore::{NativeLibrary, CrateSource, LibSource};
use rustc::ty::maps::Providers;
use rustc::util::nodemap::{FxHashSet, FxHashMap};
pub mod back {
mod archive;
......@@ -247,3 +248,15 @@ pub struct CrateInfo {
}
__build_diagnostic_array! { librustc_trans, DIAGNOSTICS }
pub fn provide_local(providers: &mut Providers) {
back::symbol_names::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);
}
......@@ -102,7 +102,6 @@
//! source-level module, functions from the same module will be available for
//! inlining, even when they are not marked #[inline].
use back::symbol_export::ExportedSymbols;
use collector::InliningMap;
use common;
use context::SharedCrateContext;
......@@ -110,6 +109,7 @@
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::session::config::NUMBERED_CODEGEN_UNIT_MARKER;
use rustc::ty::{self, TyCtxt, InstanceDef};
use rustc::ty::item_path::characteristic_def_id_of_type;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册