From bb1d8544c948b99a9eb0cf5d850703b1720951ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Tue, 22 Aug 2023 21:47:54 +0200 Subject: [PATCH] Extract suitable code from rustc_query_impl into a new crate rustc_query_misc --- Cargo.lock | 17 +- compiler/rustc_interface/Cargo.toml | 1 + compiler/rustc_interface/src/queries.rs | 2 +- compiler/rustc_query_impl/Cargo.toml | 2 +- compiler/rustc_query_impl/src/lib.rs | 14 +- compiler/rustc_query_impl/src/plumbing.rs | 183 +----------- compiler/rustc_query_misc/Cargo.toml | 16 ++ compiler/rustc_query_misc/src/README.md | 3 + compiler/rustc_query_misc/src/lib.rs | 263 ++++++++++++++++++ .../src/profiling_support.rs | 0 10 files changed, 315 insertions(+), 186 deletions(-) create mode 100644 compiler/rustc_query_misc/Cargo.toml create mode 100644 compiler/rustc_query_misc/src/README.md create mode 100644 compiler/rustc_query_misc/src/lib.rs rename compiler/{rustc_query_impl => rustc_query_misc}/src/profiling_support.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index bdbafb8623bb8..c69261017480f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3880,6 +3880,7 @@ dependencies = [ "rustc_plugin_impl", "rustc_privacy", "rustc_query_impl", + "rustc_query_misc", "rustc_query_system", "rustc_resolve", "rustc_session", @@ -4225,7 +4226,6 @@ name = "rustc_query_impl" version = "0.0.0" dependencies = [ "field-offset", - "measureme", "memoffset", "rustc-rayon-core", "rustc_data_structures", @@ -4234,6 +4234,7 @@ dependencies = [ "rustc_index", "rustc_macros", "rustc_middle", + "rustc_query_misc", "rustc_query_system", "rustc_serialize", "rustc_session", @@ -4242,6 +4243,20 @@ dependencies = [ "tracing", ] +[[package]] +name = "rustc_query_misc" +version = "0.0.0" +dependencies = [ + "measureme", + "rustc_data_structures", + "rustc_hir", + "rustc_index", + "rustc_middle", + "rustc_query_system", + "rustc_serialize", + "rustc_span", +] + [[package]] name = "rustc_query_system" version = "0.0.0" diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml index ae008674d0127..435ffcea29ca4 100644 --- a/compiler/rustc_interface/Cargo.toml +++ b/compiler/rustc_interface/Cargo.toml @@ -47,6 +47,7 @@ rustc_plugin_impl = { path = "../rustc_plugin_impl" } rustc_privacy = { path = "../rustc_privacy" } rustc_query_system = { path = "../rustc_query_system" } rustc_query_impl = { path = "../rustc_query_impl" } +rustc_query_misc = { path = "../rustc_query_misc" } rustc_resolve = { path = "../rustc_resolve" } rustc_target = { path = "../rustc_target" } rustc_trait_selection = { path = "../rustc_trait_selection" } diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 2db7aa0e36710..55c72203083c9 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -379,7 +379,7 @@ impl Compiler { { let _prof_timer = queries.session().prof.generic_activity("self_profile_alloc_query_strings"); - gcx.enter(rustc_query_impl::alloc_self_profile_query_strings); + gcx.enter(rustc_query_misc::alloc_self_profile_query_strings); } self.session() diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml index a44dd5ede2fd2..f54bc53a5e7bf 100644 --- a/compiler/rustc_query_impl/Cargo.toml +++ b/compiler/rustc_query_impl/Cargo.toml @@ -8,7 +8,6 @@ edition = "2021" [dependencies] field-offset = "0.3.5" -measureme = "10.0.0" rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_hir = { path = "../rustc_hir" } @@ -16,6 +15,7 @@ rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } rustc_query_system = { path = "../rustc_query_system" } +rustc_query_misc = { path = "../rustc_query_misc" } rustc-rayon-core = { version = "0.5.0", optional = true } rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 9a0fcbb37a724..15191fac2ca2c 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -4,7 +4,6 @@ // this shouldn't be necessary, but the check for `&mut _` is too naive and denies returning a function pointer that takes a mut ref #![feature(const_mut_refs)] #![feature(const_refs_to_cell)] -#![feature(min_specialization)] #![feature(never_type)] #![feature(rustc_attrs)] #![recursion_limit = "256"] @@ -16,7 +15,7 @@ #[macro_use] extern crate rustc_middle; -use crate::plumbing::{__rust_begin_short_backtrace, encode_all_query_results, try_mark_green}; +use crate::plumbing::{__rust_begin_short_backtrace, try_mark_green}; use field_offset::offset_of; use rustc_data_structures::stable_hasher::HashStable; use rustc_data_structures::sync::AtomicU64; @@ -24,15 +23,14 @@ use rustc_middle::arena::Arena; use rustc_middle::dep_graph::DepNodeIndex; use rustc_middle::dep_graph::{self, DepKind, DepKindStruct}; use rustc_middle::query::erase::{erase, restore, Erase}; -use rustc_middle::query::on_disk_cache::{CacheEncoder, EncodedDepNodeIndex, OnDiskCache}; -use rustc_middle::query::plumbing::{ - DynamicQuery, QueryKeyStringCache, QuerySystem, QuerySystemFns, -}; +use rustc_middle::query::on_disk_cache::OnDiskCache; +use rustc_middle::query::plumbing::{DynamicQuery, QuerySystem, QuerySystemFns}; use rustc_middle::query::AsLocalKey; use rustc_middle::query::{ queries, DynamicQueries, ExternProviders, Providers, QueryCaches, QueryEngine, QueryStates, }; use rustc_middle::ty::TyCtxt; +use rustc_query_misc::{encode_all_query_results, query_utils}; use rustc_query_system::dep_graph::SerializedDepNodeIndex; use rustc_query_system::ich::StableHashingContext; use rustc_query_system::query::{ @@ -40,16 +38,12 @@ use rustc_query_system::query::{ QueryMode, QueryState, }; use rustc_query_system::HandleCycleError; -use rustc_query_system::Value; use rustc_span::{ErrorGuaranteed, Span}; #[macro_use] mod plumbing; pub use crate::plumbing::QueryCtxt; -mod profiling_support; -pub use self::profiling_support::alloc_self_profile_query_strings; - struct DynamicConfig< 'tcx, C: QueryCache, diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index a30ea7c1ddcaf..a34cf47fb7095 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -2,30 +2,22 @@ //! generate the actual methods on tcx which find and execute the provider, //! manage the caches, and so forth. -use crate::rustc_middle::dep_graph::DepContext; -use crate::rustc_middle::ty::TyEncoder; use crate::QueryConfigRestored; use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher}; use rustc_data_structures::sync::Lock; use rustc_errors::Diagnostic; -use rustc_index::Idx; use rustc_middle::dep_graph::{ self, DepKind, DepKindStruct, DepNode, DepNodeIndex, SerializedDepNodeIndex, }; -use rustc_middle::query::on_disk_cache::AbsoluteBytePos; -use rustc_middle::query::on_disk_cache::{CacheDecoder, CacheEncoder, EncodedDepNodeIndex}; use rustc_middle::query::Key; use rustc_middle::ty::tls::{self, ImplicitCtxt}; use rustc_middle::ty::{self, print::with_no_queries, TyCtxt}; use rustc_query_system::dep_graph::{DepNodeParams, HasDepContext}; use rustc_query_system::ich::StableHashingContext; use rustc_query_system::query::{ - force_query, QueryCache, QueryConfig, QueryContext, QueryJobId, QueryMap, QuerySideEffects, - QueryStackFrame, + force_query, QueryConfig, QueryContext, QueryJobId, QueryMap, QuerySideEffects, QueryStackFrame, }; use rustc_query_system::{LayoutOfDepth, QueryOverflow}; -use rustc_serialize::Decodable; -use rustc_serialize::Encodable; use rustc_session::Limit; use rustc_span::def_id::LOCAL_CRATE; use std::num::NonZeroU64; @@ -178,16 +170,6 @@ pub(super) fn try_mark_green<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepN tcx.dep_graph.try_mark_green(QueryCtxt::new(tcx), dep_node).is_some() } -pub(super) fn encode_all_query_results<'tcx>( - tcx: TyCtxt<'tcx>, - encoder: &mut CacheEncoder<'_, 'tcx>, - query_result_index: &mut EncodedDepNodeIndex, -) { - for encode in super::ENCODE_QUERY_RESULTS.iter().copied().flatten() { - encode(tcx, encoder, query_result_index); - } -} - macro_rules! handle_cycle_error { ([]) => {{ rustc_query_system::HandleCycleError::Error @@ -252,10 +234,10 @@ macro_rules! feedable { } macro_rules! hash_result { - ([][$V:ty]) => {{ - Some(|hcx, result| dep_graph::hash_result(hcx, &restore::<$V>(*result))) + ([][$f:path]) => {{ + Some($f) }}; - ([(no_hash) $($rest:tt)*][$V:ty]) => {{ + ([(no_hash) $($rest:tt)*]$args:tt) => {{ None }}; ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => { @@ -339,34 +321,6 @@ pub(crate) fn create_query_frame< QueryStackFrame::new(description, span, def_id, def_kind, kind, ty_adt_id, hash) } -pub(crate) fn encode_query_results<'a, 'tcx, Q>( - query: Q::Config, - qcx: QueryCtxt<'tcx>, - encoder: &mut CacheEncoder<'a, 'tcx>, - query_result_index: &mut EncodedDepNodeIndex, -) where - Q: super::QueryConfigRestored<'tcx>, - Q::RestoredValue: Encodable>, -{ - let _timer = - qcx.profiler().verbose_generic_activity_with_arg("encode_query_results_for", query.name()); - - assert!(query.query_state(qcx).all_inactive()); - let cache = query.query_cache(qcx); - cache.iter(&mut |key, value, dep_node| { - if query.cache_on_disk(qcx.tcx, &key) { - let dep_node = SerializedDepNodeIndex::new(dep_node.index()); - - // Record position of the cache entry. - query_result_index.push((dep_node, AbsoluteBytePos::new(encoder.position()))); - - // Encode the type check tables with the `SerializedDepNodeIndex` - // as tag. - encoder.encode_tagged(dep_node, &Q::restore(*value)); - } - }); -} - fn try_load_from_on_disk_cache<'tcx, Q>(query: Q, tcx: TyCtxt<'tcx>, dep_node: DepNode) where Q: QueryConfig>, @@ -381,38 +335,6 @@ where } } -pub(crate) fn loadable_from_disk<'tcx>(tcx: TyCtxt<'tcx>, id: SerializedDepNodeIndex) -> bool { - if let Some(cache) = tcx.query_system.on_disk_cache.as_ref() { - cache.loadable_from_disk(id) - } else { - false - } -} - -pub(crate) fn try_load_from_disk<'tcx, V>( - tcx: TyCtxt<'tcx>, - prev_index: SerializedDepNodeIndex, - index: DepNodeIndex, -) -> Option -where - V: for<'a> Decodable>, -{ - let on_disk_cache = tcx.query_system.on_disk_cache.as_ref()?; - - let prof_timer = tcx.prof.incr_cache_loading(); - - // The call to `with_query_deserialization` enforces that no new `DepNodes` - // are created during deserialization. See the docs of that method for more - // details. - let value = tcx - .dep_graph - .with_query_deserialization(|| on_disk_cache.try_load_query_result(tcx, prev_index)); - - prof_timer.finish_with_query_invocation_id(index.into()); - - value -} - fn force_from_dep_node<'tcx, Q>(query: Q, tcx: TyCtxt<'tcx>, dep_node: DepNode) -> bool where Q: QueryConfig>, @@ -474,28 +396,6 @@ where } } -macro_rules! item_if_cached { - ([] $tokens:tt) => {}; - ([(cache) $($rest:tt)*] { $($tokens:tt)* }) => { - $($tokens)* - }; - ([$other:tt $($modifiers:tt)*] $tokens:tt) => { - item_if_cached! { [$($modifiers)*] $tokens } - }; -} - -macro_rules! expand_if_cached { - ([], $tokens:expr) => {{ - None - }}; - ([(cache) $($rest:tt)*], $tokens:expr) => {{ - Some($tokens) - }}; - ([$other:tt $($modifiers:tt)*], $tokens:expr) => { - expand_if_cached!([$($modifiers)*], $tokens) - }; -} - /// Don't show the backtrace for query system by default /// use `RUST_BACKTRACE=full` to show all the backtraces #[inline(never)] @@ -587,38 +487,11 @@ macro_rules! define_queries { ) }, can_load_from_disk: should_ever_cache_on_disk!([$($modifiers)*] true false), - try_load_from_disk: should_ever_cache_on_disk!([$($modifiers)*] { - |tcx, key, prev_index, index| { - if ::rustc_middle::query::cached::$name(tcx, key) { - let value = $crate::plumbing::try_load_from_disk::< - queries::$name::ProvidedValue<'tcx> - >( - tcx, - prev_index, - index, - ); - value.map(|value| queries::$name::provided_to_erased(tcx, value)) - } else { - None - } - } - } { - |_tcx, _key, _prev_index, _index| None - }), - value_from_cycle_error: |tcx, cycle, guar| { - let result: queries::$name::Value<'tcx> = Value::from_cycle_error(tcx, cycle, guar); - erase(result) - }, - loadable_from_disk: |_tcx, _key, _index| { - should_ever_cache_on_disk!([$($modifiers)*] { - ::rustc_middle::query::cached::$name(_tcx, _key) && - $crate::plumbing::loadable_from_disk(_tcx, _index) - } { - false - }) - }, - hash_result: hash_result!([$($modifiers)*][queries::$name::Value<'tcx>]), - format_value: |value| format!("{:?}", restore::>(*value)), + try_load_from_disk: query_utils::$name::try_load_from_disk, + loadable_from_disk: query_utils::$name::loadable_from_disk, + value_from_cycle_error: query_utils::$name::value_from_cycle_error, + hash_result: hash_result!([$($modifiers)*][query_utils::$name::hash_result]), + format_value: query_utils::$name::format_value, } } @@ -662,30 +535,6 @@ macro_rules! define_queries { qmap, ).unwrap(); } - - pub fn alloc_self_profile_query_strings<'tcx>(tcx: TyCtxt<'tcx>, string_cache: &mut QueryKeyStringCache) { - $crate::profiling_support::alloc_self_profile_query_strings_for_query_cache( - tcx, - stringify!($name), - &tcx.query_system.caches.$name, - string_cache, - ) - } - - item_if_cached! { [$($modifiers)*] { - pub fn encode_query_results<'tcx>( - tcx: TyCtxt<'tcx>, - encoder: &mut CacheEncoder<'_, 'tcx>, - query_result_index: &mut EncodedDepNodeIndex - ) { - $crate::plumbing::encode_query_results::>( - query_impl::$name::QueryType::config(tcx), - QueryCtxt::new(tcx), - encoder, - query_result_index, - ) - } - }} })*} pub(crate) fn engine(incremental: bool) -> QueryEngine { @@ -708,23 +557,11 @@ macro_rules! define_queries { } } - // These arrays are used for iteration and can't be indexed by `DepKind`. + // This array is used for iteration and can't be indexed by `DepKind`. const TRY_COLLECT_ACTIVE_JOBS: &[for<'tcx> fn(TyCtxt<'tcx>, &mut QueryMap)] = &[$(query_impl::$name::try_collect_active_jobs),*]; - const ALLOC_SELF_PROFILE_QUERY_STRINGS: &[ - for<'tcx> fn(TyCtxt<'tcx>, &mut QueryKeyStringCache) - ] = &[$(query_impl::$name::alloc_self_profile_query_strings),*]; - - const ENCODE_QUERY_RESULTS: &[ - Option fn( - TyCtxt<'tcx>, - &mut CacheEncoder<'_, 'tcx>, - &mut EncodedDepNodeIndex) - > - ] = &[$(expand_if_cached!([$($modifiers)*], query_impl::$name::encode_query_results)),*]; - #[allow(nonstandard_style)] mod query_callbacks { use super::*; diff --git a/compiler/rustc_query_misc/Cargo.toml b/compiler/rustc_query_misc/Cargo.toml new file mode 100644 index 0000000000000..0564504f5d79a --- /dev/null +++ b/compiler/rustc_query_misc/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "rustc_query_misc" +version = "0.0.0" +edition = "2021" + +[lib] + +[dependencies] +measureme = "10.0.0" +rustc_data_structures = { path = "../rustc_data_structures" } +rustc_hir = { path = "../rustc_hir" } +rustc_index = { path = "../rustc_index" } +rustc_middle = { path = "../rustc_middle" } +rustc_query_system = { path = "../rustc_query_system" } +rustc_serialize = { path = "../rustc_serialize" } +rustc_span = { path = "../rustc_span" } diff --git a/compiler/rustc_query_misc/src/README.md b/compiler/rustc_query_misc/src/README.md new file mode 100644 index 0000000000000..8ec07b9fdeb78 --- /dev/null +++ b/compiler/rustc_query_misc/src/README.md @@ -0,0 +1,3 @@ +For more information about how the query system works, see the [rustc dev guide]. + +[rustc dev guide]: https://rustc-dev-guide.rust-lang.org/query.html diff --git a/compiler/rustc_query_misc/src/lib.rs b/compiler/rustc_query_misc/src/lib.rs new file mode 100644 index 0000000000000..e335ee02008a0 --- /dev/null +++ b/compiler/rustc_query_misc/src/lib.rs @@ -0,0 +1,263 @@ +//! This crate provides miscellaneous functions for use in rustc_query_impl crate to avoid +//! code generation for it to grow too large. + +#![feature(min_specialization)] +#![feature(rustc_attrs)] +#![allow(internal_features)] + +#[macro_use] +extern crate rustc_middle; + +use crate::rustc_middle::ty::TyEncoder; +use rustc_data_structures::fingerprint::Fingerprint; +use rustc_index::Idx; +use rustc_middle::dep_graph; +use rustc_middle::dep_graph::DepKind; +use rustc_middle::query::cached; +use rustc_middle::query::erase::{erase, restore, Erase, EraseType}; +use rustc_middle::query::on_disk_cache::AbsoluteBytePos; +use rustc_middle::query::on_disk_cache::CacheDecoder; +use rustc_middle::query::on_disk_cache::{CacheEncoder, EncodedDepNodeIndex}; +use rustc_middle::query::plumbing::QueryKeyStringCache; +use rustc_middle::query::queries; +use rustc_middle::ty::TyCtxt; +use rustc_query_system::dep_graph::DepNodeIndex; +use rustc_query_system::dep_graph::SerializedDepNodeIndex; +use rustc_query_system::ich::StableHashingContext; +use rustc_query_system::query::{QueryCache, QueryInfo, QueryState}; +use rustc_query_system::Value; +use rustc_serialize::Decodable; +use rustc_serialize::Encodable; +use rustc_span::ErrorGuaranteed; + +mod profiling_support; +pub use self::profiling_support::alloc_self_profile_query_strings; + +macro_rules! item_if_hashable { + ([] { $($tokens:tt)* }) => { + $($tokens)*}; + ([(no_hash) $($rest:tt)*] $tokens:tt) => {}; + ([$other:tt $($modifiers:tt)*] $tokens:tt) => { + item_if_hashable! { [$($modifiers)*] $tokens } + }; +} + +macro_rules! if_can_cache { + ([]$yes:tt $no:tt) => {{ + $no + }}; + ([(cache) $($rest:tt)*]$yes:tt $no:tt) => {{ + $yes + }}; + ([$other:tt $($modifiers:tt)*]$yes:tt $no:tt) => { + if_can_cache!([$($modifiers)*]$yes $no) + }; +} + +macro_rules! item_if_can_cache { + ([] $tokens:tt) => {}; + ([(cache) $($rest:tt)*] { $($tokens:tt)* }) => { + $($tokens)* + }; + ([$other:tt $($modifiers:tt)*] $tokens:tt) => { + item_if_can_cache! { [$($modifiers)*] $tokens } + }; +} + +macro_rules! expand_if_can_cache { + ([], $tokens:expr) => {{ + None + }}; + ([(cache) $($rest:tt)*], $tokens:expr) => {{ + Some($tokens) + }}; + ([$other:tt $($modifiers:tt)*], $tokens:expr) => { + expand_if_can_cache!([$($modifiers)*], $tokens) + }; +} + +// NOTE: `$V` isn't used here, but we still need to match on it so it can be passed to other macros +// invoked by `rustc_query_append`. +macro_rules! query_functions { + ( + $($(#[$attr:meta])* + [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => { + + pub mod query_utils { $(pub mod $name { + // Actually used + #[allow(unused_imports)] + use super::super::*; + + pub fn try_load_from_disk<'tcx>( + _tcx: TyCtxt<'tcx>, + _key: &queries::$name::Key<'tcx>, + _prev_index: SerializedDepNodeIndex, + _index: DepNodeIndex, + ) -> Option>> { + if_can_cache!([$($modifiers)*] { + if cached::$name(_tcx, _key) { + let value = try_load_from_disk_impl::>( + _tcx, + _prev_index, + _index, + ); + value.map(|value| queries::$name::provided_to_erased(_tcx, value)) + } else { + None + } + } { + None + }) + } + + pub fn loadable_from_disk<'tcx>( + _tcx: TyCtxt<'tcx>, + _key: &queries::$name::Key<'tcx>, + _index: SerializedDepNodeIndex, + ) -> bool { + if_can_cache!([$($modifiers)*] { + cached::$name(_tcx, _key) && loadable_from_disk_impl(_tcx, _index) + } { + false + }) + } + + pub fn value_from_cycle_error<'tcx>( + tcx: TyCtxt<'tcx>, + cycle: &[QueryInfo], + guar: ErrorGuaranteed, + ) -> Erase> { + let result: queries::$name::Value<'tcx> = Value::from_cycle_error(tcx, cycle, guar); + erase(result) + } + + pub fn format_value<'tcx>(value: &Erase>) -> String { + format!("{:?}", restore::>(*value)) + } + + pub fn alloc_self_profile_query_strings<'tcx>(tcx: TyCtxt<'tcx>, string_cache: &mut QueryKeyStringCache) { + profiling_support::alloc_self_profile_query_strings_for_query_cache( + tcx, + stringify!($name), + &tcx.query_system.caches.$name, + string_cache, + ) + } + + item_if_hashable! { [$($modifiers)*] { + pub fn hash_result<'tcx>( + hcx: &mut StableHashingContext<'_>, + value: &Erase> + ) -> Fingerprint { + dep_graph::hash_result(hcx, &restore::>(*value)) + } + }} + + item_if_can_cache! { [$($modifiers)*] { + #[inline(never)] + pub(crate) fn encode_query_results<'tcx>( + tcx: TyCtxt<'tcx>, + encoder: &mut CacheEncoder<'_, 'tcx>, + query_result_index: &mut EncodedDepNodeIndex + ) { + encode_query_results_impl::<_, queries::$name::Value<'tcx>>( + tcx, + stringify!($name), + cached::$name, + &tcx.query_system.caches.$name, + &tcx.query_system.states.$name, + encoder, + query_result_index, + ) + } + }} + })*} + + // These arrays are used for iteration and can't be indexed by `DepKind`. + + const ALLOC_SELF_PROFILE_QUERY_STRINGS: &[ + for<'tcx> fn(TyCtxt<'tcx>, &mut QueryKeyStringCache) + ] = &[$(query_utils::$name::alloc_self_profile_query_strings),*]; + + const ENCODE_QUERY_RESULTS: &[ + Option fn( + TyCtxt<'tcx>, + &mut CacheEncoder<'_, 'tcx>, + &mut EncodedDepNodeIndex) + > + ] = &[$(expand_if_can_cache!([$($modifiers)*], query_utils::$name::encode_query_results)),*]; + } +} + +rustc_query_append! { query_functions! } + +fn loadable_from_disk_impl<'tcx>(tcx: TyCtxt<'tcx>, id: SerializedDepNodeIndex) -> bool { + if let Some(cache) = tcx.query_system.on_disk_cache.as_ref() { + cache.loadable_from_disk(id) + } else { + false + } +} + +fn try_load_from_disk_impl<'tcx, V>( + tcx: TyCtxt<'tcx>, + prev_index: SerializedDepNodeIndex, + index: DepNodeIndex, +) -> Option +where + V: for<'a> Decodable>, +{ + let on_disk_cache = tcx.query_system.on_disk_cache.as_ref()?; + + let prof_timer = tcx.prof.incr_cache_loading(); + + // The call to `with_query_deserialization` enforces that no new `DepNodes` + // are created during deserialization. See the docs of that method for more + // details. + let value = tcx + .dep_graph + .with_query_deserialization(|| on_disk_cache.try_load_query_result(tcx, prev_index)); + + prof_timer.finish_with_query_invocation_id(index.into()); + + value +} + +#[inline(always)] +fn encode_query_results_impl<'tcx, C: QueryCache>, V>( + tcx: TyCtxt<'tcx>, + name: &'static str, + cache_on_disk: impl Fn(TyCtxt<'tcx>, &C::Key) -> bool, + cache: &C, + state: &QueryState, + encoder: &mut CacheEncoder<'_, 'tcx>, + query_result_index: &mut EncodedDepNodeIndex, +) where + V: EraseType + for<'a> Encodable>, +{ + let _timer = tcx.prof.generic_activity_with_arg("encode_query_results_for", name); + + assert!(state.all_inactive()); + cache.iter(&mut |key, value, dep_node| { + if cache_on_disk(tcx, &key) { + let dep_node = SerializedDepNodeIndex::new(dep_node.index()); + + // Record position of the cache entry. + query_result_index.push((dep_node, AbsoluteBytePos::new(encoder.position()))); + + // Encode the type check tables with the `SerializedDepNodeIndex` + // as tag. + encoder.encode_tagged(dep_node, &restore::(*value)); + } + }); +} + +pub fn encode_all_query_results<'tcx>( + tcx: TyCtxt<'tcx>, + encoder: &mut CacheEncoder<'_, 'tcx>, + query_result_index: &mut EncodedDepNodeIndex, +) { + for encode in ENCODE_QUERY_RESULTS.iter().copied().flatten() { + encode(tcx, encoder, query_result_index); + } +} diff --git a/compiler/rustc_query_impl/src/profiling_support.rs b/compiler/rustc_query_misc/src/profiling_support.rs similarity index 100% rename from compiler/rustc_query_impl/src/profiling_support.rs rename to compiler/rustc_query_misc/src/profiling_support.rs