Skip to content

Commit

Permalink
Don't create two new closures for each query
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
jyn514 committed Sep 1, 2022
1 parent 4fcc745 commit 4e09a13
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 37 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ macro_rules! arena_types {
[decode] is_late_bound_map: rustc_data_structures::fx::FxIndexSet<rustc_hir::def_id::LocalDefId>,
[decode] impl_source: rustc_middle::traits::ImplSource<'tcx, ()>,

[] dep_kind: rustc_middle::dep_graph::DepKindStruct,
[] dep_kind: rustc_middle::dep_graph::DepKindStruct<'tcx>,
]);
)
}
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_middle/src/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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<fn(tcx: TyCtxt<'_>, dep_node: DepNode) -> bool>,
pub force_from_dep_node: Option<fn(tcx: TyCtxt<'tcx>, dep_node: DepNode) -> bool>,

/// Invoke a query to put the on-disk cached value in memory.
pub try_load_from_on_disk_cache: Option<fn(TyCtxt<'_>, DepNode)>,
pub try_load_from_on_disk_cache: Option<fn(TyCtxt<'tcx>, DepNode)>,
}

impl DepKind {
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
Expand Down Expand Up @@ -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> {
Expand Down Expand Up @@ -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]
}

Expand Down
51 changes: 21 additions & 30 deletions compiler/rustc_query_impl/src/plumbing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<QueryCtxt<'tcx>>,
Q::Key: DepNodeParams<TyCtxt<'tcx>>,
{
Expand All @@ -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<QueryCtxt<'tcx>>,
Q::Key: DepNodeParams<TyCtxt<'tcx>>,
Expand All @@ -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<QueryCtxt<'tcx>>,
Q::Key: DepNodeParams<TyCtxt<'tcx>>,
Expand All @@ -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::<Q>),
try_load_from_on_disk_cache: Some(try_load_from_on_disk_cache::<Q>),
}
}

Expand Down Expand Up @@ -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)]
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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::<Q<'_>>(
|tcx, key| $crate::plumbing::try_load_from_on_disk_cache::<Q<'_>, _>(tcx, key, TyCtxt::$name),
|tcx, key| $crate::plumbing::force_from_dep_node::<Q<'_>>(tcx, key),
is_anon,
is_eval_always
$(pub(crate) fn $name<'tcx>()-> DepKindStruct<'tcx> {
$crate::plumbing::query_callback::<queries::$name<'tcx>>(
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))
}
}
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_query_system/src/query/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,7 @@ pub trait QueryDescription<CTX: QueryContext>: QueryConfig {
fn make_vtable(tcx: CTX, key: &Self::Key) -> QueryVTable<CTX, Self::Key, Self::Value>;

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;
}

0 comments on commit 4e09a13

Please sign in to comment.