Skip to content

Commit

Permalink
rustc: Convert dependency_formats to a query
Browse files Browse the repository at this point in the history
This commit converts a field of `Session`, `dependency_formats`, into a
query of `TyCtxt`. This information then also needed to be threaded
through to other remaining portions of the linker, but it's relatively
straightforward. The only change here is that instead of
`HashMap<CrateType, T>` the data structure changed to `Vec<(CrateType,
T)>` to make it easier to deal with in queries.
  • Loading branch information
alexcrichton committed Sep 23, 2019
1 parent 66bf391 commit 5d531ae
Show file tree
Hide file tree
Showing 14 changed files with 455 additions and 419 deletions.
378 changes: 6 additions & 372 deletions src/librustc/middle/dependency_format.rs

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions src/librustc/query/mod.rs
Expand Up @@ -630,6 +630,10 @@ rustc_queries! {
-> &'tcx [(CrateNum, LinkagePreference)] {
desc { "dylib dependency formats of crate" }
}

query dependency_formats(_: CrateNum) -> Lrc<crate::middle::dependency_format::Dependencies> {
desc { "get the linkage format of all dependencies" }
}
}

Codegen {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/session/config.rs
Expand Up @@ -687,7 +687,7 @@ pub enum EntryFnType {

impl_stable_hash_via_hash!(EntryFnType);

#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug)]
#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug, HashStable)]
pub enum CrateType {
Executable,
Dylib,
Expand Down
3 changes: 0 additions & 3 deletions src/librustc/session/mod.rs
Expand Up @@ -7,7 +7,6 @@ use rustc_data_structures::fingerprint::Fingerprint;

use crate::lint;
use crate::lint::builtin::BuiltinLintDiagnostics;
use crate::middle::dependency_format;
use crate::session::config::{OutputType, PrintRequest, SwitchWithOptPath};
use crate::session::search_paths::{PathKind, SearchPath};
use crate::util::nodemap::{FxHashMap, FxHashSet};
Expand Down Expand Up @@ -91,7 +90,6 @@ pub struct Session {
pub plugin_llvm_passes: OneThread<RefCell<Vec<String>>>,
pub plugin_attributes: Lock<Vec<(Symbol, AttributeType)>>,
pub crate_types: Once<Vec<config::CrateType>>,
pub dependency_formats: Once<dependency_format::Dependencies>,
/// The `crate_disambiguator` is constructed out of all the `-C metadata`
/// arguments passed to the compiler. Its value together with the crate-name
/// forms a unique global identifier for the crate. It is used to allow
Expand Down Expand Up @@ -1247,7 +1245,6 @@ fn build_session_(
plugin_llvm_passes: OneThread::new(RefCell::new(Vec::new())),
plugin_attributes: Lock::new(Vec::new()),
crate_types: Once::new(),
dependency_formats: Once::new(),
crate_disambiguator: Once::new(),
features: Once::new(),
recursion_limit: Once::new(),
Expand Down
61 changes: 39 additions & 22 deletions src/librustc_codegen_ssa/back/link.rs
Expand Up @@ -219,15 +219,24 @@ pub fn get_linker(sess: &Session, linker: &Path, flavor: LinkerFlavor) -> (PathB
(linker.to_path_buf(), cmd)
}

pub fn each_linked_rlib(sess: &Session,
info: &CrateInfo,
f: &mut dyn FnMut(CrateNum, &Path)) -> Result<(), String> {
pub fn each_linked_rlib(
info: &CrateInfo,
f: &mut dyn FnMut(CrateNum, &Path),
) -> Result<(), String> {
let crates = info.used_crates_static.iter();
let fmts = sess.dependency_formats.borrow();
let fmts = fmts.get(&config::CrateType::Executable)
.or_else(|| fmts.get(&config::CrateType::Staticlib))
.or_else(|| fmts.get(&config::CrateType::Cdylib))
.or_else(|| fmts.get(&config::CrateType::ProcMacro));
let mut fmts = None;
for (ty, list) in info.dependency_formats.iter() {
match ty {
config::CrateType::Executable |
config::CrateType::Staticlib |
config::CrateType::Cdylib |
config::CrateType::ProcMacro => {
fmts = Some(list);
break;
}
_ => {}
}
}
let fmts = match fmts {
Some(f) => f,
None => return Err("could not find formats for rlibs".to_string())
Expand Down Expand Up @@ -406,7 +415,7 @@ fn link_staticlib<'a, B: ArchiveBuilder<'a>>(sess: &'a Session,
tempdir);
let mut all_native_libs = vec![];

let res = each_linked_rlib(sess, &codegen_results.crate_info, &mut |cnum, path| {
let res = each_linked_rlib(&codegen_results.crate_info, &mut |cnum, path| {
let name = &codegen_results.crate_info.crate_name[&cnum];
let native_libs = &codegen_results.crate_info.native_libraries[&cnum];

Expand Down Expand Up @@ -1294,11 +1303,13 @@ pub fn add_local_native_libraries(cmd: &mut dyn Linker,
// Rust crates are not considered at all when creating an rlib output. All
// dependencies will be linked when producing the final output (instead of
// the intermediate rlib version)
fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>(cmd: &mut dyn Linker,
sess: &'a Session,
codegen_results: &CodegenResults,
crate_type: config::CrateType,
tmpdir: &Path) {
fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>(
cmd: &mut dyn Linker,
sess: &'a Session,
codegen_results: &CodegenResults,
crate_type: config::CrateType,
tmpdir: &Path,
) {
// All of the heavy lifting has previously been accomplished by the
// dependency_format module of the compiler. This is just crawling the
// output of that module, adding crates as necessary.
Expand All @@ -1307,8 +1318,10 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>(cmd: &mut dyn Linker,
// will slurp up the object files inside), and linking to a dynamic library
// involves just passing the right -l flag.

let formats = sess.dependency_formats.borrow();
let data = formats.get(&crate_type).unwrap();
let (_, data) = codegen_results.crate_info.dependency_formats
.iter()
.find(|(ty, _)| *ty == crate_type)
.expect("failed to find crate type in dependency format list");

// Invoke get_used_crates to ensure that we get a topological sorting of
// crates.
Expand Down Expand Up @@ -1620,10 +1633,12 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>(cmd: &mut dyn Linker,
// generic function calls a native function, then the generic function must
// be instantiated in the target crate, meaning that the native symbol must
// also be resolved in the target crate.
pub fn add_upstream_native_libraries(cmd: &mut dyn Linker,
sess: &Session,
codegen_results: &CodegenResults,
crate_type: config::CrateType) {
pub fn add_upstream_native_libraries(
cmd: &mut dyn Linker,
sess: &Session,
codegen_results: &CodegenResults,
crate_type: config::CrateType,
) {
// Be sure to use a topological sorting of crates because there may be
// interdependencies between native libraries. When passing -nodefaultlibs,
// for example, almost all native libraries depend on libc, so we have to
Expand All @@ -1633,8 +1648,10 @@ pub fn add_upstream_native_libraries(cmd: &mut dyn Linker,
// This passes RequireStatic, but the actual requirement doesn't matter,
// we're just getting an ordering of crate numbers, we're not worried about
// the paths.
let formats = sess.dependency_formats.borrow();
let data = formats.get(&crate_type).unwrap();
let (_, data) = codegen_results.crate_info.dependency_formats
.iter()
.find(|(ty, _)| *ty == crate_type)
.expect("failed to find crate type in dependency format list");

let crates = &codegen_results.crate_info.used_crates_static;
for &(cnum, _) in crates {
Expand Down
12 changes: 9 additions & 3 deletions src/librustc_codegen_ssa/back/linker.rs
Expand Up @@ -1092,10 +1092,16 @@ fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<String> {
}
}

let formats = tcx.sess.dependency_formats.borrow();
let deps = formats[&crate_type].iter();
let formats = tcx.dependency_formats(LOCAL_CRATE);
let deps = formats.iter().filter_map(|(t, list)| {
if *t == crate_type {
Some(list)
} else {
None
}
}).next().unwrap();

for (index, dep_format) in deps.enumerate() {
for (index, dep_format) in deps.iter().enumerate() {
let cnum = CrateNum::new(index + 1);
// For each dependency that we are linking to statically ...
if *dep_format == Linkage::Static {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_codegen_ssa/back/write.rs
Expand Up @@ -1048,7 +1048,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
}).expect("failed to spawn helper thread");

let mut each_linked_rlib_for_lto = Vec::new();
drop(link::each_linked_rlib(sess, crate_info, &mut |cnum, path| {
drop(link::each_linked_rlib(crate_info, &mut |cnum, path| {
if link::ignored_for_lto(sess, crate_info, cnum) {
return
}
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_codegen_ssa/base.rs
Expand Up @@ -539,7 +539,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
// linkage, then it's already got an allocator shim and we'll be using that
// one instead. If nothing exists then it's our job to generate the
// allocator!
let any_dynamic_crate = tcx.sess.dependency_formats.borrow()
let any_dynamic_crate = tcx.dependency_formats(LOCAL_CRATE)
.iter()
.any(|(_, list)| {
use rustc::middle::dependency_format::Linkage;
Expand Down Expand Up @@ -731,6 +731,7 @@ impl CrateInfo {
used_crate_source: Default::default(),
lang_item_to_crate: Default::default(),
missing_lang_items: Default::default(),
dependency_formats: tcx.dependency_formats(LOCAL_CRATE),
};
let lang_items = tcx.lang_items();

Expand Down
2 changes: 2 additions & 0 deletions src/librustc_codegen_ssa/lib.rs
Expand Up @@ -33,6 +33,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::sync::Lrc;
use rustc_data_structures::svh::Svh;
use rustc::middle::cstore::{LibSource, CrateSource, NativeLibrary};
use rustc::middle::dependency_format::Dependencies;
use syntax_pos::symbol::Symbol;

mod error_codes;
Expand Down Expand Up @@ -142,6 +143,7 @@ pub struct CrateInfo {
pub used_crates_dynamic: Vec<(CrateNum, LibSource)>,
pub lang_item_to_crate: FxHashMap<LangItem, CrateNum>,
pub missing_lang_items: FxHashMap<CrateNum, Vec<LangItem>>,
pub dependency_formats: Lrc<Dependencies>,
}


Expand Down
4 changes: 0 additions & 4 deletions src/librustc_interface/passes.rs
Expand Up @@ -1079,10 +1079,6 @@ pub fn start_codegen<'tcx>(
tcx.print_debug_stats();
}

time(tcx.sess, "resolving dependency formats", || {
middle::dependency_format::calculate(tcx)
});

let (metadata, need_metadata_module) = time(tcx.sess, "metadata encoding and writing", || {
encode_and_write_metadata(tcx, outputs)
});
Expand Down
5 changes: 5 additions & 0 deletions src/librustc_metadata/cstore_impl.rs
Expand Up @@ -370,6 +370,11 @@ pub fn provide(providers: &mut Providers<'_>) {
tcx.arena.alloc(visible_parent_map)
},

dependency_formats: |tcx, cnum| {
assert_eq!(cnum, LOCAL_CRATE);
Lrc::new(crate::dependency_format::calculate(tcx))
},

..*providers
};
}
Expand Down

0 comments on commit 5d531ae

Please sign in to comment.