Skip to content
Open
Show file tree
Hide file tree
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
21 changes: 7 additions & 14 deletions compiler/rustc_middle/src/query/inner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
use crate::dep_graph;
use crate::dep_graph::DepNodeKey;
use crate::query::erase::{self, Erasable, Erased};
use crate::query::{EnsureMode, QueryCache, QueryMode, QueryVTable};
use crate::query::{QueryCache, QueryMode, QueryVTable};
use crate::ty::TyCtxt;

/// Checks whether there is already a value for this key in the in-memory
Expand All @@ -28,8 +28,8 @@ where
}
}

/// Shared implementation of `tcx.$query(..)` and `tcx.at(span).$query(..)`
/// for all queries.
/// Shared implementation of `tcx.$query(..)`, `tcx.at(span).$query(..)` and
/// `tcx.ensure_done().$query(..)` for all queries.
#[inline(always)]
pub(crate) fn query_get_at<'tcx, C>(
tcx: TyCtxt<'tcx>,
Expand All @@ -46,21 +46,19 @@ where
}
}

/// Shared implementation of `tcx.ensure_ok().$query(..)` and
/// `tcx.ensure_done().$query(..)` for all queries.
/// Implementation of `tcx.ensure_ok().$query(..)` for all queries.
#[inline]
pub(crate) fn query_ensure_ok_or_done<'tcx, C>(
pub(crate) fn query_ensure_ok<'tcx, C>(
tcx: TyCtxt<'tcx>,
query: &'tcx QueryVTable<'tcx, C>,
key: C::Key,
ensure_mode: EnsureMode,
) where
C: QueryCache,
{
match try_get_cached(tcx, &query.cache, key) {
Some(_value) => {}
None => {
(query.execute_query_fn)(tcx, DUMMY_SP, key, QueryMode::Ensure { ensure_mode });
(query.execute_query_fn)(tcx, DUMMY_SP, key, QueryMode::Ensure);
}
}
}
Expand All @@ -87,12 +85,7 @@ where
match try_get_cached(tcx, &query.cache, key) {
Some(value) => convert(value),
None => {
match (query.execute_query_fn)(
tcx,
DUMMY_SP,
key,
QueryMode::Ensure { ensure_mode: EnsureMode::Ok },
) {
match (query.execute_query_fn)(tcx, DUMMY_SP, key, QueryMode::Ensure) {
// We executed the query. Convert the successful result.
Some(res) => convert(res),

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ pub use self::into_query_key::IntoQueryKey;
pub use self::job::{QueryJob, QueryJobId, QueryLatch, QueryWaiter};
pub use self::keys::{AsLocalQueryKey, LocalCrate, QueryKey};
pub use self::plumbing::{
ActiveKeyStatus, CycleError, EnsureMode, QueryMode, QueryState, QuerySystem, QueryVTable,
TyCtxtAt, TyCtxtEnsureDone, TyCtxtEnsureOk, TyCtxtEnsureResult,
ActiveKeyStatus, CycleError, QueryMode, QueryState, QuerySystem, QueryVTable, TyCtxtAt,
TyCtxtEnsureDone, TyCtxtEnsureOk, TyCtxtEnsureResult,
};
pub use self::stack::QueryStackFrame;
pub use crate::queries::Providers;
Expand Down
25 changes: 8 additions & 17 deletions compiler/rustc_middle/src/query/plumbing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,20 +57,10 @@ pub struct CycleError<'tcx> {

#[derive(Debug)]
pub enum QueryMode {
/// This is a normal query call to `tcx.$query(..)` or `tcx.at(span).$query(..)`.
/// This is a query call to `tcx.$query(..)`, `tcx.at(span).$query(..)`or `tcx.ensure_done().$query(..)`.
Get,
/// This is a call to `tcx.ensure_ok().$query(..)` or `tcx.ensure_done().$query(..)`.
Ensure { ensure_mode: EnsureMode },
}

/// Distinguishes between `tcx.ensure_ok()` and `tcx.ensure_done()` in shared
/// code paths that handle both modes.
#[derive(Debug)]
pub enum EnsureMode {
/// Corresponds to [`TyCtxt::ensure_ok`].
Ok,
/// Corresponds to [`TyCtxt::ensure_done`].
Done,
/// This is a call to `tcx.ensure_ok().$query(..)`.
Ensure,
}

/// Stores data and metadata (e.g. function pointers) for a particular query.
Expand Down Expand Up @@ -578,11 +568,10 @@ macro_rules! define_callbacks {
$(#[$attr])*
#[inline(always)]
pub fn $name(self, key: maybe_into_query_key!($($K)*)) {
$crate::query::inner::query_ensure_ok_or_done(
$crate::query::inner::query_ensure_ok(
self.tcx,
&self.tcx.query_system.query_vtables.$name,
$crate::query::IntoQueryKey::into_query_key(key),
$crate::query::EnsureMode::Ok,
)
}
)*
Expand Down Expand Up @@ -612,11 +601,13 @@ macro_rules! define_callbacks {
$(#[$attr])*
#[inline(always)]
pub fn $name(self, key: maybe_into_query_key!($($K)*)) {
$crate::query::inner::query_ensure_ok_or_done(
// This has the same implementation as `tcx.$query(..)` as it isn't currently
// beneficial to have an optimized variant due to how promotion works.
$crate::query::inner::query_get_at(
self.tcx,
DUMMY_SP,
&self.tcx.query_system.query_vtables.$name,
$crate::query::IntoQueryKey::into_query_key(key),
$crate::query::EnsureMode::Done,
);
}
)*
Expand Down
36 changes: 11 additions & 25 deletions compiler/rustc_query_impl/src/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use rustc_data_structures::{outline, sharded, sync};
use rustc_errors::FatalError;
use rustc_middle::dep_graph::{DepGraphData, DepNodeKey, SerializedDepNodeIndex};
use rustc_middle::query::{
ActiveKeyStatus, CycleError, EnsureMode, QueryCache, QueryJob, QueryJobId, QueryKey,
QueryLatch, QueryMode, QueryState, QueryVTable,
ActiveKeyStatus, CycleError, QueryCache, QueryJob, QueryJobId, QueryKey, QueryLatch, QueryMode,
QueryState, QueryVTable,
};
use rustc_middle::ty::TyCtxt;
use rustc_middle::verify_ich::incremental_verify_ich;
Expand All @@ -18,7 +18,7 @@ use tracing::warn;

use crate::dep_graph::{DepNode, DepNodeIndex};
use crate::job::{QueryJobInfo, QueryJobMap, find_cycle_in_stack, report_cycle};
use crate::plumbing::{current_query_job, loadable_from_disk, next_job_id, start_query};
use crate::plumbing::{current_query_job, next_job_id, start_query};
use crate::query_impl::for_each_query_vtable;

#[inline]
Expand Down Expand Up @@ -546,15 +546,15 @@ fn load_from_disk_or_invoke_provider_green<'tcx, C: QueryCache>(

/// Return value struct for [`check_if_ensure_can_skip_execution`].
struct EnsureCanSkip {
/// If true, the current `tcx.ensure_ok()` or `tcx.ensure_done()` query
/// If true, the current `tcx.ensure_ok()` query
/// can return early without actually trying to execute.
skip_execution: bool,
/// A dep node that was prepared while checking whether execution can be
/// skipped, to be reused by execution itself if _not_ skipped.
dep_node: Option<DepNode>,
}

/// Checks whether a `tcx.ensure_ok()` or `tcx.ensure_done()` query call can
/// Checks whether a `tcx.ensure_ok()` query call can
/// return early without actually trying to execute.
///
/// This only makes sense during incremental compilation, because it relies
Expand All @@ -565,7 +565,6 @@ fn check_if_ensure_can_skip_execution<'tcx, C: QueryCache>(
query: &'tcx QueryVTable<'tcx, C>,
tcx: TyCtxt<'tcx>,
key: C::Key,
ensure_mode: EnsureMode,
) -> EnsureCanSkip {
// Queries with `eval_always` should never skip execution.
if query.eval_always {
Expand All @@ -574,38 +573,25 @@ fn check_if_ensure_can_skip_execution<'tcx, C: QueryCache>(

let dep_node = DepNode::construct(tcx, query.dep_kind, &key);

let serialized_dep_node_index = match tcx.dep_graph.try_mark_green(tcx, &dep_node) {
match tcx.dep_graph.try_mark_green(tcx, &dep_node) {
None => {
// A None return from `try_mark_green` means that this is either
// a new dep node or that the dep node has already been marked red.
// Either way, we can't call `dep_graph.read()` as we don't have the
// DepNodeIndex. We must invoke the query itself. The performance cost
// this introduces should be negligible as we'll immediately hit the
// in-memory cache, or another query down the line will.
return EnsureCanSkip { skip_execution: false, dep_node: Some(dep_node) };
EnsureCanSkip { skip_execution: false, dep_node: Some(dep_node) }
}
Some((serialized_dep_node_index, dep_node_index)) => {
Some((_, dep_node_index)) => {
tcx.dep_graph.read_index(dep_node_index);
tcx.prof.query_cache_hit(dep_node_index.into());
serialized_dep_node_index
}
};

match ensure_mode {
EnsureMode::Ok => {
// In ensure-ok mode, we can skip execution for this key if the node
// is green. It must have succeeded in the previous session, and
// therefore would succeed in the current session if executed.
EnsureCanSkip { skip_execution: true, dep_node: None }
}
EnsureMode::Done => {
// In ensure-done mode, we can only skip execution for this key if
// there's a disk-cached value available to load later if needed,
// which guarantees the query provider will never run for this key.
let is_loadable = (query.will_cache_on_disk_for_key_fn)(tcx, key)
&& loadable_from_disk(tcx, serialized_dep_node_index);
EnsureCanSkip { skip_execution: is_loadable, dep_node: Some(dep_node) }
}
}
}

Expand Down Expand Up @@ -635,13 +621,13 @@ pub(super) fn execute_query_incr_inner<'tcx, C: QueryCache>(
) -> Option<C::Value> {
debug_assert!(tcx.dep_graph.is_fully_enabled());

// Check if query execution can be skipped, for `ensure_ok` or `ensure_done`.
// Check if query execution can be skipped, for `ensure_ok`.
// This might have the side-effect of creating a suitable DepNode, which
// we should reuse for execution instead of creating a new one.
let dep_node: Option<DepNode> = match mode {
QueryMode::Ensure { ensure_mode } => {
QueryMode::Ensure => {
let EnsureCanSkip { skip_execution, dep_node } =
check_if_ensure_can_skip_execution(query, tcx, key, ensure_mode);
check_if_ensure_can_skip_execution(query, tcx, key);
if skip_execution {
// Return early to skip execution.
return None;
Expand Down
8 changes: 0 additions & 8 deletions compiler/rustc_query_impl/src/plumbing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,14 +189,6 @@ pub(crate) fn promote_from_disk_inner<'tcx, Q: GetQueryVTable<'tcx>>(
}
}

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,
Expand Down
Loading