Skip to content

Commit afb85cf

Browse files
committed
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!
1 parent 8821aff commit afb85cf

File tree

18 files changed

+233
-313
lines changed

18 files changed

+233
-313
lines changed

src/librustc/dep_graph/dep_node.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,7 @@ define_dep_nodes!( <'tcx>
575575
[] MaybeUnusedExternCrates,
576576
[] StabilityIndex,
577577
[] AllCrateNums,
578-
[] ExportedSymbols,
578+
[] ExportedSymbols(CrateNum),
579579
[] CollectAndPartitionTranslationItems,
580580
[] ExportName(DefId),
581581
[] ContainsExternIndicator(DefId),

src/librustc/middle/cstore.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -366,8 +366,9 @@ pub trait CrateLoader {
366366
// In order to get this left-to-right dependency ordering, we perform a
367367
// topological sort of all crates putting the leaves at the right-most
368368
// positions.
369-
pub fn used_crates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
370-
prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)> {
369+
pub fn used_crates(tcx: TyCtxt, prefer: LinkagePreference)
370+
-> Vec<(CrateNum, LibSource)>
371+
{
371372
let mut libs = tcx.crates()
372373
.iter()
373374
.cloned()

src/librustc/middle/exported_symbols.rs

Lines changed: 7 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use util::nodemap::{FxHashMap, NodeSet};
12-
use hir::def_id::{DefId, CrateNum};
13-
1411
/// The SymbolExportLevel of a symbols specifies from which kinds of crates
1512
/// the symbol will be exported. `C` symbols will be exported from any
1613
/// kind of crate, including cdylibs which export very few things.
@@ -22,56 +19,13 @@ pub enum SymbolExportLevel {
2219
Rust,
2320
}
2421

25-
/// The set of symbols exported from each crate in the crate graph.
26-
#[derive(Debug)]
27-
pub struct ExportedSymbols {
28-
pub export_threshold: SymbolExportLevel,
29-
exports: FxHashMap<CrateNum, Vec<(String, DefId, SymbolExportLevel)>>,
30-
local_exports: NodeSet,
31-
}
32-
33-
impl ExportedSymbols {
34-
pub fn new(export_threshold: SymbolExportLevel,
35-
exports: FxHashMap<CrateNum, Vec<(String, DefId, SymbolExportLevel)>>,
36-
local_exports: NodeSet) -> ExportedSymbols {
37-
ExportedSymbols {
38-
export_threshold,
39-
exports,
40-
local_exports,
41-
}
42-
}
43-
44-
pub fn local_exports(&self) -> &NodeSet {
45-
&self.local_exports
46-
}
47-
48-
pub fn exported_symbols(&self, cnum: CrateNum)
49-
-> &[(String, DefId, SymbolExportLevel)]
50-
{
51-
match self.exports.get(&cnum) {
52-
Some(exports) => exports,
53-
None => &[]
54-
}
55-
}
56-
57-
pub fn for_each_exported_symbol<F>(&self, cnum: CrateNum, mut f: F)
58-
where F: FnMut(&str, DefId, SymbolExportLevel)
59-
{
60-
for &(ref name, def_id, export_level) in self.exported_symbols(cnum) {
61-
if is_below_threshold(export_level, self.export_threshold) {
62-
f(&name, def_id, export_level)
63-
}
22+
impl SymbolExportLevel {
23+
pub fn is_below_threshold(self, threshold: SymbolExportLevel) -> bool {
24+
if threshold == SymbolExportLevel::Rust {
25+
// We export everything from Rust dylibs
26+
true
27+
} else {
28+
self == SymbolExportLevel::C
6429
}
6530
}
6631
}
67-
68-
pub fn is_below_threshold(level: SymbolExportLevel,
69-
threshold: SymbolExportLevel)
70-
-> bool {
71-
if threshold == SymbolExportLevel::Rust {
72-
// We export everything from Rust dylibs
73-
true
74-
} else {
75-
level == SymbolExportLevel::C
76-
}
77-
}

src/librustc/ty/context.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ use middle::cstore::EncodedMetadata;
2727
use middle::free_region::FreeRegionMap;
2828
use middle::lang_items;
2929
use middle::resolve_lifetime::{self, ObjectLifetimeDefault};
30-
use middle::exported_symbols::ExportedSymbols;
3130
use middle::stability;
3231
use mir::Mir;
3332
use mir::transform::Passes;
@@ -65,7 +64,6 @@ use std::mem;
6564
use std::ops::Deref;
6665
use std::iter;
6766
use std::rc::Rc;
68-
use std::sync::Arc;
6967
use syntax::abi;
7068
use syntax::ast::{self, Name, NodeId};
7169
use syntax::attr;
@@ -1220,10 +1218,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
12201218
pub fn crate_data_as_rc_any(self, cnum: CrateNum) -> Rc<Any> {
12211219
self.cstore.crate_data_as_rc_any(cnum)
12221220
}
1223-
1224-
pub fn exported_symbols(self) -> Arc<ExportedSymbols> {
1225-
self.exported_symbol_set(LOCAL_CRATE)
1226-
}
12271221
}
12281222

12291223
impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {

src/librustc/ty/maps.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use middle::region;
2323
use middle::resolve_lifetime::{Region, ObjectLifetimeDefault};
2424
use middle::stability::{self, DeprecationEntry};
2525
use middle::lang_items::{LanguageItems, LangItem};
26-
use middle::exported_symbols::ExportedSymbols;
26+
use middle::exported_symbols::SymbolExportLevel;
2727
use middle::trans::{TransItem, CodegenUnit};
2828
use mir;
2929
use mir::transform::{MirSuite, MirPassIndex};
@@ -748,9 +748,9 @@ impl<'tcx> QueryDescription for queries::all_crate_nums<'tcx> {
748748
}
749749
}
750750

751-
impl<'tcx> QueryDescription for queries::exported_symbol_set<'tcx> {
751+
impl<'tcx> QueryDescription for queries::exported_symbols<'tcx> {
752752
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
753-
format!("exported symbol set")
753+
format!("exported_symbols")
754754
}
755755
}
756756

@@ -1337,7 +1337,7 @@ define_maps! { <'tcx>
13371337
[] fn lint_levels: lint_levels_node(CrateNum) -> Rc<lint::LintLevelMap>,
13381338

13391339
[] fn impl_defaultness: ImplDefaultness(DefId) -> hir::Defaultness,
1340-
[] fn exported_symbol_ids: ExportedSymbolIds(CrateNum) -> Rc<Vec<DefId>>,
1340+
[] fn exported_symbol_ids: ExportedSymbolIds(CrateNum) -> Rc<DefIdSet>,
13411341
[] fn native_libraries: NativeLibraries(CrateNum) -> Rc<Vec<NativeLibrary>>,
13421342
[] fn plugin_registrar_fn: PluginRegistrarFn(CrateNum) -> Option<DefId>,
13431343
[] fn derive_registrar_fn: DeriveRegistrarFn(CrateNum) -> Option<DefId>,
@@ -1387,8 +1387,8 @@ define_maps! { <'tcx>
13871387
[] fn stability_index: stability_index_node(CrateNum) -> Rc<stability::Index<'tcx>>,
13881388
[] fn all_crate_nums: all_crate_nums_node(CrateNum) -> Rc<Vec<CrateNum>>,
13891389

1390-
[] fn exported_symbol_set: exported_symbol_set_node(CrateNum)
1391-
-> Arc<ExportedSymbols>,
1390+
[] fn exported_symbols: ExportedSymbols(CrateNum)
1391+
-> Arc<Vec<(String, DefId, SymbolExportLevel)>>,
13921392
[] fn collect_and_partition_translation_items:
13931393
collect_and_partition_translation_items_node(CrateNum)
13941394
-> (Arc<FxHashSet<TransItem<'tcx>>>, Vec<Arc<CodegenUnit<'tcx>>>),
@@ -1508,10 +1508,6 @@ fn all_crate_nums_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
15081508
DepConstructor::AllCrateNums
15091509
}
15101510

1511-
fn exported_symbol_set_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
1512-
DepConstructor::ExportedSymbols
1513-
}
1514-
15151511
fn collect_and_partition_translation_items_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
15161512
DepConstructor::CollectAndPartitionTranslationItems
15171513
}

src/librustc_metadata/decoder.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use rustc::middle::lang_items;
2424
use rustc::session::Session;
2525
use rustc::ty::{self, Ty, TyCtxt};
2626
use rustc::ty::subst::Substs;
27+
use rustc::util::nodemap::DefIdSet;
2728

2829
use rustc::mir::Mir;
2930

@@ -1017,7 +1018,7 @@ impl<'a, 'tcx> CrateMetadata {
10171018
arg_names.decode(self).collect()
10181019
}
10191020

1020-
pub fn get_exported_symbols(&self) -> Vec<DefId> {
1021+
pub fn get_exported_symbols(&self) -> DefIdSet {
10211022
self.exported_symbols
10221023
.iter()
10231024
.map(|&index| self.local_def_id(index))

src/librustc_trans/back/linker.rs

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,15 @@ use std::io::prelude::*;
1515
use std::io::{self, BufWriter};
1616
use std::path::{Path, PathBuf};
1717

18-
use context::SharedCrateContext;
19-
2018
use back::archive;
2119
use back::command::Command;
22-
use rustc::middle::dependency_format::Linkage;
23-
use rustc::middle::exported_symbols::ExportedSymbols;
20+
use back::symbol_export;
2421
use rustc::hir::def_id::{LOCAL_CRATE, CrateNum};
25-
use rustc_back::LinkerFlavor;
22+
use rustc::middle::dependency_format::Linkage;
2623
use rustc::session::Session;
2724
use rustc::session::config::{self, CrateType, OptLevel, DebugInfoLevel};
25+
use rustc::ty::TyCtxt;
26+
use rustc_back::LinkerFlavor;
2827
use serialize::{json, Encoder};
2928

3029
/// For all the linkers we support, and information they might
@@ -33,19 +32,18 @@ pub struct LinkerInfo {
3332
exports: HashMap<CrateType, Vec<String>>,
3433
}
3534

36-
impl<'a, 'tcx> LinkerInfo {
37-
pub fn new(scx: &SharedCrateContext<'a, 'tcx>) -> LinkerInfo {
38-
let exports = scx.tcx().exported_symbols();
35+
impl LinkerInfo {
36+
pub fn new(tcx: TyCtxt) -> LinkerInfo {
3937
LinkerInfo {
40-
exports: scx.sess().crate_types.borrow().iter().map(|&c| {
41-
(c, exported_symbols(scx, &exports, c))
38+
exports: tcx.sess.crate_types.borrow().iter().map(|&c| {
39+
(c, exported_symbols(tcx, c))
4240
}).collect(),
4341
}
4442
}
4543

46-
pub fn to_linker(&'a self,
47-
cmd: Command,
48-
sess: &'a Session) -> Box<Linker+'a> {
44+
pub fn to_linker<'a>(&'a self,
45+
cmd: Command,
46+
sess: &'a Session) -> Box<Linker+'a> {
4947
match sess.linker_flavor() {
5048
LinkerFlavor::Msvc => {
5149
Box::new(MsvcLinker {
@@ -734,26 +732,29 @@ impl<'a> Linker for EmLinker<'a> {
734732
}
735733
}
736734

737-
fn exported_symbols(scx: &SharedCrateContext,
738-
exported_symbols: &ExportedSymbols,
739-
crate_type: CrateType)
740-
-> Vec<String> {
735+
fn exported_symbols(tcx: TyCtxt, crate_type: CrateType) -> Vec<String> {
741736
let mut symbols = Vec::new();
742-
exported_symbols.for_each_exported_symbol(LOCAL_CRATE, |name, _, _| {
743-
symbols.push(name.to_owned());
744-
});
745737

746-
let formats = scx.sess().dependency_formats.borrow();
738+
let export_threshold = symbol_export::threshold(tcx);
739+
for &(ref name, _, level) in tcx.exported_symbols(LOCAL_CRATE).iter() {
740+
if level.is_below_threshold(export_threshold) {
741+
symbols.push(name.clone());
742+
}
743+
}
744+
745+
let formats = tcx.sess.dependency_formats.borrow();
747746
let deps = formats[&crate_type].iter();
748747

749748
for (index, dep_format) in deps.enumerate() {
750749
let cnum = CrateNum::new(index + 1);
751750
// For each dependency that we are linking to statically ...
752751
if *dep_format == Linkage::Static {
753752
// ... we add its symbol list to our export list.
754-
exported_symbols.for_each_exported_symbol(cnum, |name, _, _| {
755-
symbols.push(name.to_owned());
756-
})
753+
for &(ref name, _, level) in tcx.exported_symbols(cnum).iter() {
754+
if level.is_below_threshold(export_threshold) {
755+
symbols.push(name.clone());
756+
}
757+
}
757758
}
758759
}
759760

src/librustc_trans/back/lto.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use errors::{FatalError, Handler};
1616
use llvm;
1717
use llvm::archive_ro::ArchiveRO;
1818
use llvm::{ModuleRef, TargetMachineRef, True, False};
19-
use rustc::middle::exported_symbols;
19+
use rustc::middle::exported_symbols::SymbolExportLevel;
2020
use rustc::util::common::time;
2121
use rustc::util::common::path2cstr;
2222
use rustc::hir::def_id::LOCAL_CRATE;
@@ -68,8 +68,8 @@ pub fn run(cgcx: &CodegenContext,
6868
let export_threshold =
6969
symbol_export::crates_export_threshold(&cgcx.crate_types);
7070

71-
let symbol_filter = &|&(ref name, _, level): &(String, _, _)| {
72-
if exported_symbols::is_below_threshold(level, export_threshold) {
71+
let symbol_filter = &|&(ref name, _, level): &(String, _, SymbolExportLevel)| {
72+
if level.is_below_threshold(export_threshold) {
7373
let mut bytes = Vec::with_capacity(name.len() + 1);
7474
bytes.extend(name.bytes());
7575
Some(CString::new(bytes).unwrap())
@@ -78,8 +78,7 @@ pub fn run(cgcx: &CodegenContext,
7878
}
7979
};
8080

81-
let mut symbol_white_list: Vec<CString> = cgcx.exported_symbols
82-
.exported_symbols(LOCAL_CRATE)
81+
let mut symbol_white_list: Vec<CString> = cgcx.exported_symbols[&LOCAL_CRATE]
8382
.iter()
8483
.filter_map(symbol_filter)
8584
.collect();
@@ -89,9 +88,9 @@ pub fn run(cgcx: &CodegenContext,
8988
// module that we've got.
9089
for &(cnum, ref path) in cgcx.each_linked_rlib_for_lto.iter() {
9190
symbol_white_list.extend(
92-
cgcx.exported_symbols.exported_symbols(cnum)
93-
.iter()
94-
.filter_map(symbol_filter));
91+
cgcx.exported_symbols[&cnum]
92+
.iter()
93+
.filter_map(symbol_filter));
9594

9695
let archive = ArchiveRO::open(&path).expect("wanted an rlib");
9796
let bytecodes = archive.iter().filter_map(|child| {

0 commit comments

Comments
 (0)