Skip to content
Permalink
Browse files

Inform the query system about properties of queries at compile time

  • Loading branch information...
Zoxc committed Jun 24, 2019
1 parent c877989 commit 11221d120f8f79ff8e6ad35256874f30a942908b
@@ -142,9 +142,6 @@ macro_rules! define_dep_nodes {
}
}

// FIXME: Make `is_anon`, `is_eval_always` and `has_params` properties
// of queries
#[inline(always)]
pub fn is_anon(&self) -> bool {
match *self {
$(
@@ -163,7 +160,6 @@ macro_rules! define_dep_nodes {
}

#[allow(unreachable_code)]
#[inline(always)]
pub fn has_params(&self) -> bool {
match *self {
$(
@@ -1,5 +1,5 @@
use crate::dep_graph::SerializedDepNodeIndex;
use crate::dep_graph::DepNode;
use crate::dep_graph::{DepKind, DepNode};
use crate::hir::def_id::{CrateNum, DefId};
use crate::ty::TyCtxt;
use crate::ty::query::queries;
@@ -28,13 +28,18 @@ pub trait QueryConfig<'tcx> {
}

pub(crate) trait QueryAccessors<'tcx>: QueryConfig<'tcx> {
const ANON: bool;
const EVAL_ALWAYS: bool;

fn query(key: Self::Key) -> Query<'tcx>;

// Don't use this method to access query results, instead use the methods on TyCtxt
fn query_cache<'a>(tcx: TyCtxt<'tcx>) -> &'a Lock<QueryCache<'tcx, Self>>;

fn to_dep_node(tcx: TyCtxt<'tcx>, key: &Self::Key) -> DepNode;

fn dep_kind() -> DepKind;

// Don't use this method to compute query results, instead use the methods on TyCtxt
fn compute(tcx: TyCtxt<'tcx>, key: Self::Key) -> Self::Value;

@@ -101,6 +101,6 @@ pub use self::on_disk_cache::OnDiskCache;
rustc_query_append! { [define_queries!][ <'tcx>
Other {
/// Runs analysis passes on the crate.
[] fn analysis: Analysis(CrateNum) -> Result<(), ErrorReported>,
[eval_always] fn analysis: Analysis(CrateNum) -> Result<(), ErrorReported>,
},
]}
@@ -376,15 +376,13 @@ impl<'tcx> TyCtxt<'tcx> {
return self.force_query_with_job::<Q>(key, job, null_dep_node).0;
}

let dep_node = Q::to_dep_node(self, &key);

if dep_node.kind.is_anon() {
if Q::ANON {
profq_msg!(self, ProfileQueriesMsg::ProviderBegin);
self.sess.profiler(|p| p.start_query(Q::NAME));

let ((result, dep_node_index), diagnostics) = with_diagnostics(|diagnostics| {
self.start_query(job.job.clone(), diagnostics, |tcx| {
tcx.dep_graph.with_anon_task(dep_node.kind, || {
tcx.dep_graph.with_anon_task(Q::dep_kind(), || {
Q::compute(tcx.global_tcx(), key)
})
})
@@ -405,7 +403,9 @@ impl<'tcx> TyCtxt<'tcx> {
return result;
}

if !dep_node.kind.is_eval_always() {
let dep_node = Q::to_dep_node(self, &key);

if !Q::EVAL_ALWAYS {
// The diagnostics for this query will be
// promoted to the current session during
// try_mark_green(), so we can ignore them here.
@@ -546,7 +546,7 @@ impl<'tcx> TyCtxt<'tcx> {

let ((result, dep_node_index), diagnostics) = with_diagnostics(|diagnostics| {
self.start_query(job.job.clone(), diagnostics, |tcx| {
if dep_node.kind.is_eval_always() {
if Q::EVAL_ALWAYS {
tcx.dep_graph.with_eval_always_task(dep_node,
tcx,
key,
@@ -569,8 +569,8 @@ impl<'tcx> TyCtxt<'tcx> {
self.dep_graph.mark_loaded_from_cache(dep_node_index, false);
}

if dep_node.kind != crate::dep_graph::DepKind::Null {
if unlikely!(!diagnostics.is_empty()) {
if unlikely!(!diagnostics.is_empty()) {
if dep_node.kind != crate::dep_graph::DepKind::Null {
self.queries.on_disk_cache
.store_diagnostics(dep_node_index, diagnostics);
}
@@ -589,15 +589,16 @@ impl<'tcx> TyCtxt<'tcx> {
///
/// Note: The optimization is only available during incr. comp.
pub(super) fn ensure_query<Q: QueryDescription<'tcx>>(self, key: Q::Key) -> () {
let dep_node = Q::to_dep_node(self, &key);

if dep_node.kind.is_eval_always() {
if Q::EVAL_ALWAYS {
let _ = self.get_query::<Q>(DUMMY_SP, key);
return;
}

// Ensuring an anonymous query makes no sense
assert!(!dep_node.kind.is_anon());
assert!(!Q::ANON);

let dep_node = Q::to_dep_node(self, &key);

if self.dep_graph.try_mark_green_and_read(self, &dep_node).is_none() {
// A None return from `try_mark_green_and_read` means that this is either
// a new dep node or that the dep node has already been marked red.
@@ -653,6 +654,30 @@ macro_rules! handle_cycle_error {
};
}

macro_rules! is_anon {
([]) => {{
false
}};
([anon$(, $modifiers:ident)*]) => {{
true
}};
([$other:ident$(, $modifiers:ident)*]) => {
is_anon!([$($modifiers),*])
};
}

macro_rules! is_eval_always {
([]) => {{
false
}};
([eval_always$(, $modifiers:ident)*]) => {{
true
}};
([$other:ident$(, $modifiers:ident)*]) => {
is_eval_always!([$($modifiers),*])
};
}

macro_rules! hash_result {
([][$hcx:expr, $result:expr]) => {{
dep_graph::hash_result($hcx, &$result)
@@ -933,6 +958,9 @@ macro_rules! define_queries_inner {
}

impl<$tcx> QueryAccessors<$tcx> for queries::$name<$tcx> {
const ANON: bool = is_anon!([$($modifiers)*]);
const EVAL_ALWAYS: bool = is_eval_always!([$($modifiers)*]);

#[inline(always)]
fn query(key: Self::Key) -> Query<'tcx> {
Query::$name(key)
@@ -951,6 +979,11 @@ macro_rules! define_queries_inner {
DepNode::new(tcx, $node(*key))
}

#[inline(always)]
fn dep_kind() -> dep_graph::DepKind {
dep_graph::DepKind::$node
}

#[inline]
fn compute(tcx: TyCtxt<'tcx>, key: Self::Key) -> Self::Value {
__query_compute::$name(move || {
@@ -423,20 +423,6 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
if modifiers.no_hash {
attributes.push(quote! { no_hash });
};

let mut attribute_stream = quote! {};

for e in attributes.into_iter().intersperse(quote! {,}) {
attribute_stream.extend(e);
}

// Add the query to the group
group_stream.extend(quote! {
[#attribute_stream] fn #name: #name(#arg) #result,
});

let mut attributes = Vec::new();

// Pass on the anon modifier
if modifiers.anon {
attributes.push(quote! { anon });
@@ -450,6 +436,12 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
for e in attributes.into_iter().intersperse(quote! {,}) {
attribute_stream.extend(e);
}

// Add the query to the group
group_stream.extend(quote! {
[#attribute_stream] fn #name: #name(#arg) #result,
});

// Create a dep node for the query
dep_node_def_stream.extend(quote! {
[#attribute_stream] #name(#arg),

0 comments on commit 11221d1

Please sign in to comment.
You can’t perform that action at this time.