From 4e09a13bb848a64acf6bb20359f582e813e74764 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 29 Aug 2022 10:20:14 -0500 Subject: [PATCH] Don't create two new closures for each query - Parameterize DepKindStruct over `'tcx` This allows passing in an invariant function pointer in `query_callback`, rather than having to try and make it work for any lifetime. - Add a new `execute_query` function to `QueryDescription` so we can call `tcx.$name` without needing to be in a macro context --- compiler/rustc_middle/src/arena.rs | 2 +- .../rustc_middle/src/dep_graph/dep_node.rs | 6 +-- compiler/rustc_middle/src/ty/context.rs | 6 +-- compiler/rustc_query_impl/src/plumbing.rs | 51 ++++++++----------- .../rustc_query_system/src/query/config.rs | 3 ++ 5 files changed, 31 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index b94de537dc8..65d5f755f72 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -100,7 +100,7 @@ macro_rules! arena_types { [decode] is_late_bound_map: rustc_data_structures::fx::FxIndexSet, [decode] impl_source: rustc_middle::traits::ImplSource<'tcx, ()>, - [] dep_kind: rustc_middle::dep_graph::DepKindStruct, + [] dep_kind: rustc_middle::dep_graph::DepKindStruct<'tcx>, ]); ) } diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index 65fc8a2e9cf..7718906ac4e 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -74,7 +74,7 @@ pub use rustc_query_system::dep_graph::{DepContext, DepNodeParams}; /// Information is retrieved by indexing the `DEP_KINDS` array using the integer value /// of the `DepKind`. Overall, this allows to implement `DepContext` using this manual /// jump table instead of large matches. -pub struct DepKindStruct { +pub struct DepKindStruct<'tcx> { /// Anonymous queries cannot be replayed from one compiler invocation to the next. /// When their result is needed, it is recomputed. They are useful for fine-grained /// dependency tracking, and caching within one compiler invocation. @@ -124,10 +124,10 @@ pub struct DepKindStruct { /// with kind `MirValidated`, we know that the GUID/fingerprint of the `DepNode` /// is actually a `DefPathHash`, and can therefore just look up the corresponding /// `DefId` in `tcx.def_path_hash_to_def_id`. - pub force_from_dep_node: Option, dep_node: DepNode) -> bool>, + pub force_from_dep_node: Option, dep_node: DepNode) -> bool>, /// Invoke a query to put the on-disk cached value in memory. - pub try_load_from_on_disk_cache: Option, DepNode)>, + pub try_load_from_on_disk_cache: Option, DepNode)>, } impl DepKind { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 052bb1263c9..7a990773ab8 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1089,7 +1089,7 @@ pub struct GlobalCtxt<'tcx> { pub queries: &'tcx dyn query::QueryEngine<'tcx>, pub query_caches: query::QueryCaches<'tcx>, - query_kinds: &'tcx [DepKindStruct], + query_kinds: &'tcx [DepKindStruct<'tcx>], // Internal caches for metadata decoding. No need to track deps on this. pub ty_rcache: Lock>>, @@ -1246,7 +1246,7 @@ impl<'tcx> TyCtxt<'tcx> { dep_graph: DepGraph, on_disk_cache: Option<&'tcx dyn OnDiskCache<'tcx>>, queries: &'tcx dyn query::QueryEngine<'tcx>, - query_kinds: &'tcx [DepKindStruct], + query_kinds: &'tcx [DepKindStruct<'tcx>], crate_name: &str, output_filenames: OutputFilenames, ) -> GlobalCtxt<'tcx> { @@ -1296,7 +1296,7 @@ impl<'tcx> TyCtxt<'tcx> { } } - pub(crate) fn query_kind(self, k: DepKind) -> &'tcx DepKindStruct { + pub(crate) fn query_kind(self, k: DepKind) -> &'tcx DepKindStruct<'tcx> { &self.query_kinds[k as usize] } diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index cc7e0765171..274df5b5e5e 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -301,11 +301,8 @@ pub(crate) fn create_query_frame< QueryStackFrame::new(name, description, span, def_kind, hash) } -pub(crate) fn try_load_from_on_disk_cache<'tcx, Q, V>( - tcx: TyCtxt<'tcx>, - dep_node: DepNode, - cache_query_deps: fn(TyCtxt<'tcx>, Q::Key) -> V, -) where +fn try_load_from_on_disk_cache<'tcx, Q>(tcx: TyCtxt<'tcx>, dep_node: DepNode) +where Q: QueryDescription>, Q::Key: DepNodeParams>, { @@ -315,11 +312,11 @@ pub(crate) fn try_load_from_on_disk_cache<'tcx, Q, V>( panic!("Failed to recover key for {:?} with hash {}", dep_node, dep_node.hash) }); if Q::cache_on_disk(tcx, &key) { - let _ = cache_query_deps(tcx, key); + let _ = Q::execute_query(tcx, key); } } -pub(crate) fn force_from_dep_node<'tcx, Q>(tcx: TyCtxt<'tcx>, dep_node: DepNode) -> bool +fn force_from_dep_node<'tcx, Q>(tcx: TyCtxt<'tcx>, dep_node: DepNode) -> bool where Q: QueryDescription>, Q::Key: DepNodeParams>, @@ -336,13 +333,9 @@ where } pub(crate) fn query_callback<'tcx, Q: QueryConfig>( - // NOTE: we can't remove these function pointers, because `recover` is invariant -> `try_load_from_on_disk_cache` takes a concrete lifetime, not a universal lifetime. - // Instead, we infer the correct lifetime at the callsite, so we can pass in a HRTB function pointer to the DepKindStruct. - try_load_from_on_disk_cache: fn(TyCtxt<'_>, DepNode), - force_from_dep_node: fn(TyCtxt<'_>, DepNode) -> bool, is_anon: bool, is_eval_always: bool, -) -> DepKindStruct +) -> DepKindStruct<'tcx> where Q: QueryDescription>, Q::Key: DepNodeParams>, @@ -363,8 +356,8 @@ where is_anon, is_eval_always, fingerprint_style, - force_from_dep_node: Some(force_from_dep_node), - try_load_from_on_disk_cache: Some(try_load_from_on_disk_cache), + force_from_dep_node: Some(force_from_dep_node::), + try_load_from_on_disk_cache: Some(try_load_from_on_disk_cache::), } } @@ -431,6 +424,10 @@ macro_rules! define_queries { try_load_from_disk: Self::TRY_LOAD_FROM_DISK, } } + + fn execute_query(tcx: TyCtxt<'tcx>, k: Self::Key) -> Self::Stored { + tcx.$name(k) + } })* #[allow(nonstandard_style)] @@ -439,7 +436,7 @@ macro_rules! define_queries { use rustc_query_system::dep_graph::FingerprintStyle; // We use this for most things when incr. comp. is turned off. - pub fn Null() -> DepKindStruct { + pub fn Null<'tcx>() -> DepKindStruct<'tcx> { DepKindStruct { is_anon: false, is_eval_always: false, @@ -450,7 +447,7 @@ macro_rules! define_queries { } // We use this for the forever-red node. - pub fn Red() -> DepKindStruct { + pub fn Red<'tcx>() -> DepKindStruct<'tcx> { DepKindStruct { is_anon: false, is_eval_always: false, @@ -460,7 +457,7 @@ macro_rules! define_queries { } } - pub fn TraitSelect() -> DepKindStruct { + pub fn TraitSelect<'tcx>() -> DepKindStruct<'tcx> { DepKindStruct { is_anon: true, is_eval_always: false, @@ -470,7 +467,7 @@ macro_rules! define_queries { } } - pub fn CompileCodegenUnit() -> DepKindStruct { + pub fn CompileCodegenUnit<'tcx>() -> DepKindStruct<'tcx> { DepKindStruct { is_anon: false, is_eval_always: false, @@ -480,7 +477,7 @@ macro_rules! define_queries { } } - pub fn CompileMonoItem() -> DepKindStruct { + pub fn CompileMonoItem<'tcx>() -> DepKindStruct<'tcx> { DepKindStruct { is_anon: false, is_eval_always: false, @@ -490,21 +487,15 @@ macro_rules! define_queries { } } - $(pub(crate) fn $name()-> DepKindStruct { - let is_anon = is_anon!([$($modifiers)*]); - let is_eval_always = is_eval_always!([$($modifiers)*]); - type Q<'tcx> = queries::$name<'tcx>; - - $crate::plumbing::query_callback::>( - |tcx, key| $crate::plumbing::try_load_from_on_disk_cache::, _>(tcx, key, TyCtxt::$name), - |tcx, key| $crate::plumbing::force_from_dep_node::>(tcx, key), - is_anon, - is_eval_always + $(pub(crate) fn $name<'tcx>()-> DepKindStruct<'tcx> { + $crate::plumbing::query_callback::>( + is_anon!([$($modifiers)*]), + is_eval_always!([$($modifiers)*]), ) })* } - pub fn query_callbacks<'tcx>(arena: &'tcx Arena<'tcx>) -> &'tcx [DepKindStruct] { + pub fn query_callbacks<'tcx>(arena: &'tcx Arena<'tcx>) -> &'tcx [DepKindStruct<'tcx>] { arena.alloc_from_iter(make_dep_kind_array!(query_callbacks)) } } diff --git a/compiler/rustc_query_system/src/query/config.rs b/compiler/rustc_query_system/src/query/config.rs index bd0fd7ac350..ea38df836cb 100644 --- a/compiler/rustc_query_system/src/query/config.rs +++ b/compiler/rustc_query_system/src/query/config.rs @@ -73,4 +73,7 @@ pub trait QueryDescription: QueryConfig { fn make_vtable(tcx: CTX, key: &Self::Key) -> QueryVTable; fn cache_on_disk(tcx: CTX::DepContext, key: &Self::Key) -> bool; + + // Don't use this method to compute query results, instead use the methods on TyCtxt + fn execute_query(tcx: CTX::DepContext, k: Self::Key) -> Self::Stored; }