From 05886e28a4c3fbb7bc22d56bf5a52ba7cfa491d9 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 29 Aug 2022 17:45:18 -0500 Subject: Further simplify the macros generated by `rustc_queries` - Add a new `rustc_query_names` macro. This allows a much simpler syntax for the matchers in the macros passed to it as a callback. - Convert `define_dep_nodes` and `alloc_once` to use `rustc_query_names`. This is possible because they only use the names (despite the quite complicated matchers in `define_dep_nodes`, none of the other arguments are used). - Get rid of `rustc_dep_node_append`. --- compiler/rustc_query_impl/src/profiling_support.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'compiler/rustc_query_impl/src/profiling_support.rs') diff --git a/compiler/rustc_query_impl/src/profiling_support.rs b/compiler/rustc_query_impl/src/profiling_support.rs index 260af0d5408..a8e0210e8d6 100644 --- a/compiler/rustc_query_impl/src/profiling_support.rs +++ b/compiler/rustc_query_impl/src/profiling_support.rs @@ -307,7 +307,7 @@ pub fn alloc_self_profile_query_strings(tcx: TyCtxt<'_>) { macro_rules! alloc_once { ( - $($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident($K:ty) -> $V:ty,)* + $($name:ident,)* ) => { $({ alloc_self_profile_query_strings_for_query_cache( @@ -320,5 +320,5 @@ pub fn alloc_self_profile_query_strings(tcx: TyCtxt<'_>) { } } - rustc_query_append! { alloc_once! } + rustc_query_names! { alloc_once! } } -- cgit 1.4.1-3-g733a5 From c630c87ceb0c49c5dc2b1a6119c67e9033dce828 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 29 Aug 2022 18:46:56 -0500 Subject: Support doc-comments in `define_dep_nodes` --- compiler/rustc_macros/src/query.rs | 8 ++++++-- compiler/rustc_middle/src/dep_graph/dep_node.rs | 8 ++++---- compiler/rustc_query_impl/src/profiling_support.rs | 4 ++-- 3 files changed, 12 insertions(+), 8 deletions(-) (limited to 'compiler/rustc_query_impl/src/profiling_support.rs') diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index 2a1bb10fdfc..046a144913e 100644 --- a/compiler/rustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs @@ -344,7 +344,6 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { #name, }); } - all_names.extend(quote! { #name, }); let mut attributes = Vec::new(); @@ -394,13 +393,18 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { // be very useful. let span = name.span(); let attribute_stream = quote_spanned! {span=> #(#attributes),*}; - let doc_comments = query.doc_comments.iter(); + let doc_comments = &query.doc_comments; // Add the query to the group query_stream.extend(quote! { #(#doc_comments)* [#attribute_stream] fn #name(#arg) #result, }); + all_names.extend(quote! { + #(#doc_comments)* + #name, + }); + add_query_description_impl(&query, &mut query_description_stream); } diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index f54d75c24e2..21d174af444 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -144,7 +144,7 @@ impl DepKind { macro_rules! define_dep_nodes { ( - $( $variant:ident, )* + $( $( #[$attr:meta] )* $variant:ident, )+ ) => ( #[macro_export] macro_rules! make_dep_kind_array { @@ -155,7 +155,7 @@ macro_rules! define_dep_nodes { #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Encodable, Decodable)] #[allow(non_camel_case_types)] pub enum DepKind { - $($variant),* + $( $( #[$attr] )* $variant),* } fn dep_kind_from_label_string(label: &str) -> Result { @@ -177,9 +177,9 @@ macro_rules! define_dep_nodes { } rustc_query_names!(define_dep_nodes![ - // We use this for most things when incr. comp. is turned off. + /// We use this for most things when incr. comp. is turned off. Null, - // We use this to create a forever-red node. + /// We use this to create a forever-red node. Red, TraitSelect, CompileCodegenUnit, diff --git a/compiler/rustc_query_impl/src/profiling_support.rs b/compiler/rustc_query_impl/src/profiling_support.rs index a8e0210e8d6..a9bb4756dbc 100644 --- a/compiler/rustc_query_impl/src/profiling_support.rs +++ b/compiler/rustc_query_impl/src/profiling_support.rs @@ -307,7 +307,7 @@ pub fn alloc_self_profile_query_strings(tcx: TyCtxt<'_>) { macro_rules! alloc_once { ( - $($name:ident,)* + $( $( #[$attr:meta] )* $name:ident, )+ ) => { $({ alloc_self_profile_query_strings_for_query_cache( @@ -316,7 +316,7 @@ pub fn alloc_self_profile_query_strings(tcx: TyCtxt<'_>) { &tcx.query_caches.$name, &mut string_cache, ); - })* + })+ } } -- cgit 1.4.1-3-g733a5 From 3a4e3c778889fdf2c4ccb7af26f1e81fc324e98b Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 6 Sep 2022 21:26:02 -0500 Subject: Get rid of the emitted `rustc_query_names` and `rustc_cached_queries` macro We can avoid these by adding slightly more information to `rustc_query_append` instead. --- compiler/rustc_macros/src/query.rs | 29 ++++++---------------- compiler/rustc_middle/src/dep_graph/dep_node.rs | 19 +++++++------- compiler/rustc_query_impl/src/plumbing.rs | 20 ++++++++++++--- compiler/rustc_query_impl/src/profiling_support.rs | 10 ++++---- 4 files changed, 38 insertions(+), 40 deletions(-) (limited to 'compiler/rustc_query_impl/src/profiling_support.rs') diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index 046a144913e..505b2d62a79 100644 --- a/compiler/rustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs @@ -328,7 +328,6 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { let mut query_stream = quote! {}; let mut query_description_stream = quote! {}; - let mut all_names = quote! {}; let mut cached_queries = quote! {}; for query in queries.0 { @@ -384,6 +383,10 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { if let Some(remap_env_constness) = &modifiers.remap_env_constness { attributes.push(quote! { (#remap_env_constness) }); } + // Pass on the const modifier + if modifiers.cache.is_some() { + attributes.push(quote! { (cache) }); + } // This uses the span of the query definition for the commas, // which can be important if we later encounter any ambiguity @@ -400,38 +403,20 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { [#attribute_stream] fn #name(#arg) #result, }); - all_names.extend(quote! { - #(#doc_comments)* - #name, - }); - add_query_description_impl(&query, &mut query_description_stream); } TokenStream::from(quote! { #[macro_export] macro_rules! rustc_query_append { - ($macro:ident!) => { + ($macro:ident! $( [$($other:tt)*] )?) => { $macro! { + $( $($other)* )? #query_stream } } } - #[macro_export] - macro_rules! rustc_query_names { - ($macro:ident! $( [$($other:tt)*] )?) => { - $macro!( - $( $($other)* )? - #all_names - ); - } - } - #[macro_export] - macro_rules! rustc_cached_queries { - ($macro:ident!) => { - $macro!(#cached_queries); - } - } + #[macro_export] macro_rules! rustc_query_description { #query_description_stream diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index 21d174af444..1fa0c6babab 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -144,8 +144,9 @@ impl DepKind { macro_rules! define_dep_nodes { ( - $( $( #[$attr:meta] )* $variant:ident, )+ - ) => ( + $($(#[$attr:meta])* + [$($modifiers:tt)*] fn $variant:ident($($K:tt)*) -> $V:ty,)*) => { + #[macro_export] macro_rules! make_dep_kind_array { ($mod:ident) => {[ $($mod::$variant()),* ]}; @@ -173,17 +174,17 @@ macro_rules! define_dep_nodes { pub const $variant: &str = stringify!($variant); )* } - ); + }; } -rustc_query_names!(define_dep_nodes![ +rustc_query_append!(define_dep_nodes![ /// We use this for most things when incr. comp. is turned off. - Null, + [] fn Null() -> (), /// We use this to create a forever-red node. - Red, - TraitSelect, - CompileCodegenUnit, - CompileMonoItem, + [] fn Red() -> (), + [] fn TraitSelect() -> (), + [] fn CompileCodegenUnit() -> (), + [] fn CompileMonoItem() -> (), ]); // WARNING: `construct` is generic and does not know that `CompileCodegenUnit` takes `Symbol`s as keys. diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 274df5b5e5e..7e48125307a 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -148,19 +148,31 @@ impl<'tcx> QueryCtxt<'tcx> { encoder: &mut on_disk_cache::CacheEncoder<'_, 'tcx>, query_result_index: &mut on_disk_cache::EncodedDepNodeIndex, ) { + macro_rules! expand_if_cached { + ([] $encode:expr) => {}; + ([(cache) $($rest:tt)*] $encode:expr) => { + $encode + }; + ([$other:tt $($modifiers:tt)*] $encode:expr) => { + expand_if_cached!([$($modifiers)*] $encode) + }; + } + macro_rules! encode_queries { - ($($query:ident,)*) => { + ( + $($(#[$attr:meta])* + [$($modifiers:tt)*] fn $query:ident($($K:tt)*) -> $V:ty,)*) => { $( - on_disk_cache::encode_query_results::<_, super::queries::$query<'_>>( + expand_if_cached!([$($modifiers)*] on_disk_cache::encode_query_results::<_, super::queries::$query<'_>>( self, encoder, query_result_index - ); + )); )* } } - rustc_cached_queries!(encode_queries!); + rustc_query_append!(encode_queries!); } pub fn try_print_query_stack( diff --git a/compiler/rustc_query_impl/src/profiling_support.rs b/compiler/rustc_query_impl/src/profiling_support.rs index a9bb4756dbc..98ec3bc0977 100644 --- a/compiler/rustc_query_impl/src/profiling_support.rs +++ b/compiler/rustc_query_impl/src/profiling_support.rs @@ -307,18 +307,18 @@ pub fn alloc_self_profile_query_strings(tcx: TyCtxt<'_>) { macro_rules! alloc_once { ( - $( $( #[$attr:meta] )* $name:ident, )+ - ) => { - $({ + $($(#[$attr:meta])* + [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => { + $( alloc_self_profile_query_strings_for_query_cache( tcx, stringify!($name), &tcx.query_caches.$name, &mut string_cache, ); - })+ + )+ } } - rustc_query_names! { alloc_once! } + rustc_query_append! { alloc_once! } } -- cgit 1.4.1-3-g733a5 From 7a8369096c27312b1beda84c8f5c2ab207d8a3c7 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 13 Sep 2022 18:32:22 -0500 Subject: Use function pointers instead of macro-unrolled loops in rustc_query_impl By making these standalone functions, we a) allow making them extensible in the future with a new `QueryStruct` b) greatly decrease the amount of code in each individual function, avoiding exponential blowup in llvm --- compiler/rustc_query_impl/src/lib.rs | 2 + compiler/rustc_query_impl/src/plumbing.rs | 124 ++++++++++++++------- compiler/rustc_query_impl/src/profiling_support.rs | 25 ++--- 3 files changed, 95 insertions(+), 56 deletions(-) (limited to 'compiler/rustc_query_impl/src/profiling_support.rs') diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index c87d26b3950..8e018d3e4a4 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -1,6 +1,8 @@ //! Support for serializing the dep-graph and reloading it. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +// 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(min_specialization)] #![feature(never_type)] #![feature(once_cell)] diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index d819f4774d5..a4d9d07bc8a 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -3,7 +3,8 @@ //! manage the caches, and so forth. use crate::keys::Key; -use crate::on_disk_cache::CacheDecoder; +use crate::on_disk_cache::{CacheDecoder, CacheEncoder, EncodedDepNodeIndex}; +use crate::profiling_support::QueryKeyStringCache; use crate::{on_disk_cache, Queries}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::{AtomicU64, Lock}; @@ -173,34 +174,14 @@ impl<'tcx> QueryCtxt<'tcx> { pub(super) fn encode_query_results( self, - encoder: &mut on_disk_cache::CacheEncoder<'_, 'tcx>, - query_result_index: &mut on_disk_cache::EncodedDepNodeIndex, + encoder: &mut CacheEncoder<'_, 'tcx>, + query_result_index: &mut EncodedDepNodeIndex, ) { - macro_rules! expand_if_cached { - ([] $encode:expr) => {}; - ([(cache) $($rest:tt)*] $encode:expr) => { - $encode - }; - ([$other:tt $($modifiers:tt)*] $encode:expr) => { - expand_if_cached!([$($modifiers)*] $encode) - }; - } - - macro_rules! encode_queries { - ( - $($(#[$attr:meta])* - [$($modifiers:tt)*] fn $query:ident($($K:tt)*) -> $V:ty,)*) => { - $( - expand_if_cached!([$($modifiers)*] on_disk_cache::encode_query_results::<_, super::queries::$query<'_>>( - self, - encoder, - query_result_index - )); - )* + for query in &self.queries.query_structs { + if let Some(encode) = query.encode_query_results { + encode(self, encoder, query_result_index); } } - - rustc_query_append!(encode_queries!); } pub fn try_print_query_stack( @@ -213,6 +194,14 @@ impl<'tcx> QueryCtxt<'tcx> { } } +#[derive(Clone, Copy)] +pub(crate) struct QueryStruct<'tcx> { + pub try_collect_active_jobs: fn(QueryCtxt<'tcx>, &mut QueryMap) -> Option<()>, + pub alloc_self_profile_query_strings: fn(TyCtxt<'tcx>, &mut QueryKeyStringCache), + pub encode_query_results: + Option, &mut CacheEncoder<'_, 'tcx>, &mut EncodedDepNodeIndex)>, +} + macro_rules! handle_cycle_error { ([]) => {{ rustc_query_system::HandleCycleError::Error @@ -420,6 +409,18 @@ where } } +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) + }; +} + // 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! define_queries { @@ -553,6 +554,59 @@ macro_rules! define_queries { })* } + mod query_structs { + use rustc_middle::ty::TyCtxt; + use $crate::plumbing::{QueryStruct, QueryCtxt}; + use $crate::profiling_support::QueryKeyStringCache; + use rustc_query_system::query::{QueryDescription, QueryMap}; + + pub(super) const fn dummy_query_struct<'tcx>() -> QueryStruct<'tcx> { + fn noop_try_collect_active_jobs(_: QueryCtxt<'_>, _: &mut QueryMap) -> Option<()> { + None + } + fn noop_alloc_self_profile_query_strings(_: TyCtxt<'_>, _: &mut QueryKeyStringCache) {} + + QueryStruct { + try_collect_active_jobs: noop_try_collect_active_jobs, + alloc_self_profile_query_strings: noop_alloc_self_profile_query_strings, + encode_query_results: None, + } + } + + pub(super) use dummy_query_struct as Null; + pub(super) use dummy_query_struct as Red; + pub(super) use dummy_query_struct as TraitSelect; + pub(super) use dummy_query_struct as CompileCodegenUnit; + pub(super) use dummy_query_struct as CompileMonoItem; + + $( + pub(super) const fn $name<'tcx>() -> QueryStruct<'tcx> { QueryStruct { + try_collect_active_jobs: |tcx, qmap| { + let make_query = |tcx, key| { + let kind = rustc_middle::dep_graph::DepKind::$name; + let name = stringify!($name); + $crate::plumbing::create_query_frame(tcx, super::queries::$name::describe, key, kind, name) + }; + tcx.queries.$name.try_collect_active_jobs( + tcx, + make_query, + qmap, + ) + }, + alloc_self_profile_query_strings: |tcx, string_cache| { + $crate::profiling_support::alloc_self_profile_query_strings_for_query_cache( + tcx, + stringify!($name), + &tcx.query_caches.$name, + string_cache, + ) + }, + encode_query_results: expand_if_cached!([$($modifiers)*], |tcx, encoder, query_result_index| + $crate::on_disk_cache::encode_query_results::<_, super::queries::$name<'_>>(tcx, encoder, query_result_index) + ), + }})* + } + pub fn query_callbacks<'tcx>(arena: &'tcx Arena<'tcx>) -> &'tcx [DepKindStruct<'tcx>] { arena.alloc_from_iter(make_dep_kind_array!(query_callbacks)) } @@ -567,9 +621,11 @@ impl<'tcx> Queries<'tcx> { extern_providers: ExternProviders, on_disk_cache: Option>, ) -> Self { + use crate::query_structs; Queries { local_providers: Box::new(local_providers), extern_providers: Box::new(extern_providers), + query_structs: make_dep_kind_array!(query_structs).to_vec(), on_disk_cache, jobs: AtomicU64::new(1), ..Queries::default() @@ -584,6 +640,7 @@ macro_rules! define_queries_struct { pub struct Queries<'tcx> { local_providers: Box, extern_providers: Box, + query_structs: Vec<$crate::plumbing::QueryStruct<'tcx>>, pub on_disk_cache: Option>, @@ -600,18 +657,9 @@ macro_rules! define_queries_struct { let tcx = QueryCtxt { tcx, queries: self }; let mut jobs = QueryMap::default(); - $( - let make_query = |tcx, key| { - let kind = dep_graph::DepKind::$name; - let name = stringify!($name); - $crate::plumbing::create_query_frame(tcx, queries::$name::describe, key, kind, name) - }; - self.$name.try_collect_active_jobs( - tcx, - make_query, - &mut jobs, - )?; - )* + for query in &self.query_structs { + (query.try_collect_active_jobs)(tcx, &mut jobs); + } Some(jobs) } diff --git a/compiler/rustc_query_impl/src/profiling_support.rs b/compiler/rustc_query_impl/src/profiling_support.rs index 98ec3bc0977..2cc311d48c8 100644 --- a/compiler/rustc_query_impl/src/profiling_support.rs +++ b/compiler/rustc_query_impl/src/profiling_support.rs @@ -1,3 +1,4 @@ +use crate::QueryCtxt; use measureme::{StringComponent, StringId}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::profiling::SelfProfiler; @@ -8,7 +9,7 @@ use rustc_query_system::query::QueryCache; use std::fmt::Debug; use std::io::Write; -struct QueryKeyStringCache { +pub(crate) struct QueryKeyStringCache { def_id_cache: FxHashMap, } @@ -226,7 +227,7 @@ where /// Allocate the self-profiling query strings for a single query cache. This /// method is called from `alloc_self_profile_query_strings` which knows all /// the queries via macro magic. -fn alloc_self_profile_query_strings_for_query_cache<'tcx, C>( +pub(crate) fn alloc_self_profile_query_strings_for_query_cache<'tcx, C>( tcx: TyCtxt<'tcx>, query_name: &'static str, query_cache: &C, @@ -298,27 +299,15 @@ fn alloc_self_profile_query_strings_for_query_cache<'tcx, C>( /// If we are recording only summary data, the ids will point to /// just the query names. If we are recording query keys too, we /// allocate the corresponding strings here. -pub fn alloc_self_profile_query_strings(tcx: TyCtxt<'_>) { +pub fn alloc_self_profile_query_strings<'tcx>(tcx: TyCtxt<'tcx>) { if !tcx.prof.enabled() { return; } let mut string_cache = QueryKeyStringCache::new(); + let queries = QueryCtxt::from_tcx(tcx); - macro_rules! alloc_once { - ( - $($(#[$attr:meta])* - [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => { - $( - alloc_self_profile_query_strings_for_query_cache( - tcx, - stringify!($name), - &tcx.query_caches.$name, - &mut string_cache, - ); - )+ - } + for query in &queries.queries.query_structs { + (query.alloc_self_profile_query_strings)(tcx, &mut string_cache); } - - rustc_query_append! { alloc_once! } } -- cgit 1.4.1-3-g733a5