From 69dc98161a19580e95de1196f1523aa767fe1a5d Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Tue, 27 Oct 2020 15:01:03 +0100 Subject: [PATCH] Cache foreign_modules query --- compiler/rustc_codegen_llvm/src/attributes.rs | 4 ++-- compiler/rustc_codegen_ssa/src/base.rs | 2 +- compiler/rustc_metadata/src/rmeta/decoder.rs | 8 +++++--- .../src/rmeta/decoder/cstore_impl.rs | 16 +++++++++------- compiler/rustc_metadata/src/rmeta/encoder.rs | 2 +- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_passes/src/diagnostic_items.rs | 2 +- 7 files changed, 20 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 2075c2e1911..d4872aedd70 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -378,8 +378,8 @@ pub fn provide_both(providers: &mut Providers) { .collect::>(); let mut ret = FxHashMap::default(); - for lib in tcx.foreign_modules(cnum).iter() { - let module = def_id_to_native_lib.get(&lib.def_id).and_then(|s| s.wasm_import_module); + for (def_id, lib) in tcx.foreign_modules(cnum).iter() { + let module = def_id_to_native_lib.get(&def_id).and_then(|s| s.wasm_import_module); let module = match module { Some(s) => s, None => continue, diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 4d937609132..540d9fd0ca5 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -861,7 +861,7 @@ pub fn provide_both(providers: &mut Providers) { providers.dllimport_foreign_items = |tcx, krate| { let module_map = tcx.foreign_modules(krate); let module_map = - module_map.iter().map(|lib| (lib.def_id, lib)).collect::>(); + module_map.iter().map(|(def_id, lib)| (def_id, lib)).collect::>(); let dllimports = tcx .native_libraries(krate) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index b01a55b48da..c031e0e2e19 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1414,12 +1414,14 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { } } - fn get_foreign_modules(&self, tcx: TyCtxt<'tcx>) -> &'tcx [ForeignModule] { + fn get_foreign_modules(&self, tcx: TyCtxt<'tcx>) -> Lrc> { if self.root.is_proc_macro_crate() { // Proc macro crates do not have any *target* foreign modules. - &[] + Lrc::new(FxHashMap::default()) } else { - tcx.arena.alloc_from_iter(self.root.foreign_modules.decode((self, tcx.sess))) + let modules: FxHashMap = + self.root.foreign_modules.decode((self, tcx.sess)).map(|m| (m.def_id, m)).collect(); + Lrc::new(modules) } } diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 68faf9c7a62..c2092e1842f 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -6,12 +6,14 @@ use crate::rmeta::{self, encoder}; use rustc_ast as ast; use rustc_ast::expand::allocator::AllocatorKind; +use rustc_data_structures::stable_map::FxHashMap; use rustc_data_structures::svh::Svh; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_hir::definitions::{DefKey, DefPath, DefPathHash}; use rustc_middle::hir::exports::Export; +use rustc_middle::middle::cstore::ForeignModule; use rustc_middle::middle::cstore::{CrateSource, CrateStore, EncodedMetadata}; use rustc_middle::middle::exported_symbols::ExportedSymbol; use rustc_middle::middle::stability::DeprecationEntry; @@ -267,12 +269,10 @@ pub fn provide(providers: &mut Providers) { Some(id) => id, None => return false, }; - tcx.foreign_modules(id.krate) - .iter() - .find(|m| m.def_id == fm_id) - .expect("failed to find foreign module") - .foreign_items - .contains(&id) + let map = tcx.foreign_modules(id.krate); + let module = + tcx.prof.generic_activity("finding_foreign_module").run(|| map.get(&fm_id)); + module.expect("failed to find foreign module").foreign_items.contains(&id) }) .map(|l| l.kind) }, @@ -282,7 +282,9 @@ pub fn provide(providers: &mut Providers) { }, foreign_modules: |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); - &tcx.arena.alloc(foreign_modules::collect(tcx))[..] + let modules: FxHashMap = + foreign_modules::collect(tcx).into_iter().map(|m| (m.def_id, m)).collect(); + Lrc::new(modules) }, link_args: |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 7e33a479228..cd909b02bd9 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1502,7 +1502,7 @@ impl EncodeContext<'a, 'tcx> { fn encode_foreign_modules(&mut self) -> Lazy<[ForeignModule]> { empty_proc_macro!(self); let foreign_modules = self.tcx.foreign_modules(LOCAL_CRATE); - self.lazy(foreign_modules.iter().cloned()) + self.lazy(foreign_modules.iter().map(|(_, m)| m).cloned()) } fn encode_hygiene(&mut self) -> (SyntaxContextTable, ExpnDataTable) { diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 89faa97d50f..72360e219ec 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1168,7 +1168,7 @@ rustc_queries! { } Other { - query foreign_modules(_: CrateNum) -> &'tcx [ForeignModule] { + query foreign_modules(_: CrateNum) -> Lrc> { desc { "looking up the foreign modules of a linked crate" } } diff --git a/compiler/rustc_passes/src/diagnostic_items.rs b/compiler/rustc_passes/src/diagnostic_items.rs index 94592935c7f..0f4aa72d5c4 100644 --- a/compiler/rustc_passes/src/diagnostic_items.rs +++ b/compiler/rustc_passes/src/diagnostic_items.rs @@ -102,7 +102,7 @@ fn collect<'tcx>(tcx: TyCtxt<'tcx>) -> FxHashMap { tcx.hir().krate().visit_all_item_likes(&mut collector); // FIXME(visit_all_item_likes): Foreign items are not visited // here, so we have to manually look at them for now. - for foreign_module in tcx.foreign_modules(LOCAL_CRATE) { + for (_, foreign_module) in tcx.foreign_modules(LOCAL_CRATE).iter() { for &foreign_item in foreign_module.foreign_items.iter() { match tcx.hir().get(tcx.hir().local_def_id_to_hir_id(foreign_item.expect_local())) { hir::Node::ForeignItem(item) => {