Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inform the query system about properties of queries at compile time #62104

Merged
merged 2 commits into from
Jun 29, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions src/librustc/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
@@ -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 {
$(
7 changes: 6 additions & 1 deletion src/librustc/ty/query/config.rs
Original file line number Diff line number Diff line change
@@ -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;

2 changes: 1 addition & 1 deletion src/librustc/ty/query/mod.rs
Original file line number Diff line number Diff line change
@@ -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>,
},
]}
57 changes: 45 additions & 12 deletions src/librustc/ty/query/plumbing.rs
Original file line number Diff line number Diff line change
@@ -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 || {
20 changes: 6 additions & 14 deletions src/librustc_macros/src/query.rs
Original file line number Diff line number Diff line change
@@ -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),
3 changes: 3 additions & 0 deletions src/libsyntax_pos/symbol.rs
Original file line number Diff line number Diff line change
@@ -1131,6 +1131,7 @@ impl LocalInternedString {
}
}

#[inline]
pub fn get(&self) -> &str {
// This returns a valid string since we ensure that `self` outlives the interner
// by creating the interner on a thread which outlives threads which can access it.
@@ -1144,6 +1145,7 @@ impl<U: ?Sized> std::convert::AsRef<U> for LocalInternedString
where
str: std::convert::AsRef<U>
{
#[inline]
fn as_ref(&self) -> &U {
self.string.as_ref()
}
@@ -1184,6 +1186,7 @@ impl !Sync for LocalInternedString {}

impl std::ops::Deref for LocalInternedString {
type Target = str;
#[inline]
fn deref(&self) -> &str { self.string }
}