Skip to content

Create QuerySideEffects and use it for diagnostics #87416

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

Merged
merged 2 commits into from
Jul 29, 2021
Merged
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
87 changes: 38 additions & 49 deletions compiler/rustc_query_impl/src/on_disk_cache.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
use crate::QueryCtxt;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
use rustc_data_structures::sync::{HashMapExt, Lock, Lrc, OnceCell};
use rustc_data_structures::thin_vec::ThinVec;
use rustc_data_structures::unhash::UnhashMap;
use rustc_errors::Diagnostic;
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, StableCrateId, LOCAL_CRATE};
use rustc_hir::definitions::DefPathHash;
use rustc_index::vec::{Idx, IndexVec};
Expand All @@ -13,7 +11,7 @@ use rustc_middle::mir::{self, interpret};
use rustc_middle::ty::codec::{RefDecodable, TyDecoder, TyEncoder};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_query_system::dep_graph::DepContext;
use rustc_query_system::query::QueryContext;
use rustc_query_system::query::{QueryContext, QuerySideEffects};
use rustc_serialize::{
opaque::{self, FileEncodeResult, FileEncoder, IntEncodedWithFixedSize},
Decodable, Decoder, Encodable, Encoder,
Expand Down Expand Up @@ -41,14 +39,14 @@ const TAG_EXPN_DATA: u8 = 1;
/// Provides an interface to incremental compilation data cached from the
/// previous compilation session. This data will eventually include the results
/// of a few selected queries (like `typeck` and `mir_optimized`) and
/// any diagnostics that have been emitted during a query.
/// any side effects that have been emitted during a query.
pub struct OnDiskCache<'sess> {
// The complete cache data in serialized form.
serialized_data: Vec<u8>,

// Collects all `Diagnostic`s emitted during the current compilation
// Collects all `QuerySideEffects` created during the current compilation
// session.
current_diagnostics: Lock<FxHashMap<DepNodeIndex, Vec<Diagnostic>>>,
current_side_effects: Lock<FxHashMap<DepNodeIndex, QuerySideEffects>>,

cnum_map: OnceCell<UnhashMap<StableCrateId, CrateNum>>,

Expand All @@ -62,9 +60,9 @@ pub struct OnDiskCache<'sess> {
// `serialized_data`.
query_result_index: FxHashMap<SerializedDepNodeIndex, AbsoluteBytePos>,

// A map from dep-node to the position of any associated diagnostics in
// A map from dep-node to the position of any associated `QuerySideEffects` in
// `serialized_data`.
prev_diagnostics_index: FxHashMap<SerializedDepNodeIndex, AbsoluteBytePos>,
prev_side_effects_index: FxHashMap<SerializedDepNodeIndex, AbsoluteBytePos>,

alloc_decoding_state: AllocDecodingState,

Expand Down Expand Up @@ -113,8 +111,8 @@ pub struct OnDiskCache<'sess> {
#[derive(Encodable, Decodable)]
struct Footer {
file_index_to_stable_id: FxHashMap<SourceFileIndex, EncodedSourceFileId>,
query_result_index: EncodedQueryResultIndex,
diagnostics_index: EncodedQueryResultIndex,
query_result_index: EncodedDepNodeIndex,
side_effects_index: EncodedDepNodeIndex,
// The location of all allocations.
interpret_alloc_index: Vec<u32>,
// See `OnDiskCache.syntax_contexts`
Expand All @@ -125,9 +123,7 @@ struct Footer {
foreign_expn_data: UnhashMap<ExpnHash, u32>,
}

pub type EncodedQueryResultIndex = Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>;
type EncodedDiagnosticsIndex = Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>;
type EncodedDiagnostics = Vec<Diagnostic>;
pub type EncodedDepNodeIndex = Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>;

#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Encodable, Decodable)]
struct SourceFileIndex(u32);
Expand Down Expand Up @@ -213,9 +209,9 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> {
file_index_to_file: Default::default(),
cnum_map: OnceCell::new(),
source_map: sess.source_map(),
current_diagnostics: Default::default(),
current_side_effects: Default::default(),
query_result_index: footer.query_result_index.into_iter().collect(),
prev_diagnostics_index: footer.diagnostics_index.into_iter().collect(),
prev_side_effects_index: footer.side_effects_index.into_iter().collect(),
alloc_decoding_state: AllocDecodingState::new(footer.interpret_alloc_index),
syntax_contexts: footer.syntax_contexts,
expn_data: footer.expn_data,
Expand All @@ -234,9 +230,9 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> {
file_index_to_file: Default::default(),
cnum_map: OnceCell::new(),
source_map,
current_diagnostics: Default::default(),
current_side_effects: Default::default(),
query_result_index: Default::default(),
prev_diagnostics_index: Default::default(),
prev_side_effects_index: Default::default(),
alloc_decoding_state: AllocDecodingState::new(Vec::new()),
syntax_contexts: FxHashMap::default(),
expn_data: UnhashMap::default(),
Expand Down Expand Up @@ -301,26 +297,24 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> {
};

// Encode query results.
let mut query_result_index = EncodedQueryResultIndex::new();
let mut query_result_index = EncodedDepNodeIndex::new();

tcx.sess.time("encode_query_results", || -> FileEncodeResult {
let enc = &mut encoder;
let qri = &mut query_result_index;
QueryCtxt::from_tcx(tcx).encode_query_results(enc, qri)
})?;

// Encode diagnostics.
let diagnostics_index: EncodedDiagnosticsIndex = self
.current_diagnostics
// Encode side effects.
let side_effects_index: EncodedDepNodeIndex = self
.current_side_effects
.borrow()
.iter()
.map(
|(dep_node_index, diagnostics)| -> Result<_, <FileEncoder as Encoder>::Error> {
|(dep_node_index, side_effects)| -> Result<_, <FileEncoder as Encoder>::Error> {
let pos = AbsoluteBytePos::new(encoder.position());
// Let's make sure we get the expected type here.
let diagnostics: &EncodedDiagnostics = diagnostics;
let dep_node_index = SerializedDepNodeIndex::new(dep_node_index.index());
encoder.encode_tagged(dep_node_index, diagnostics)?;
encoder.encode_tagged(dep_node_index, side_effects)?;

Ok((dep_node_index, pos))
},
Expand Down Expand Up @@ -386,7 +380,7 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> {
&Footer {
file_index_to_stable_id,
query_result_index,
diagnostics_index,
side_effects_index,
interpret_alloc_index,
syntax_contexts,
expn_data,
Expand Down Expand Up @@ -488,30 +482,26 @@ impl<'sess> OnDiskCache<'sess> {
self as _
}

/// Loads a diagnostic emitted during the previous compilation session.
pub fn load_diagnostics(
/// Loads a `QuerySideEffects` created during the previous compilation session.
pub fn load_side_effects(
&self,
tcx: TyCtxt<'_>,
dep_node_index: SerializedDepNodeIndex,
) -> Vec<Diagnostic> {
let diagnostics: Option<EncodedDiagnostics> =
self.load_indexed(tcx, dep_node_index, &self.prev_diagnostics_index, "diagnostics");
) -> QuerySideEffects {
let side_effects: Option<QuerySideEffects> =
self.load_indexed(tcx, dep_node_index, &self.prev_side_effects_index, "side_effects");

diagnostics.unwrap_or_default()
side_effects.unwrap_or_default()
}

/// Stores a diagnostic emitted during the current compilation session.
/// Anything stored like this will be available via `load_diagnostics` in
/// Stores a `QuerySideEffects` emitted during the current compilation session.
/// Anything stored like this will be available via `load_side_effects` in
/// the next compilation session.
#[inline(never)]
#[cold]
pub fn store_diagnostics(
&self,
dep_node_index: DepNodeIndex,
diagnostics: ThinVec<Diagnostic>,
) {
let mut current_diagnostics = self.current_diagnostics.borrow_mut();
let prev = current_diagnostics.insert(dep_node_index, diagnostics.into());
pub fn store_side_effects(&self, dep_node_index: DepNodeIndex, side_effects: QuerySideEffects) {
let mut current_side_effects = self.current_side_effects.borrow_mut();
let prev = current_side_effects.insert(dep_node_index, side_effects);
debug_assert!(prev.is_none());
}

Expand Down Expand Up @@ -539,22 +529,21 @@ impl<'sess> OnDiskCache<'sess> {
self.load_indexed(tcx, dep_node_index, &self.query_result_index, "query result")
}

/// Stores a diagnostic emitted during computation of an anonymous query.
/// Stores side effect emitted during computation of an anonymous query.
/// Since many anonymous queries can share the same `DepNode`, we aggregate
/// them -- as opposed to regular queries where we assume that there is a
/// 1:1 relationship between query-key and `DepNode`.
#[inline(never)]
#[cold]
pub fn store_diagnostics_for_anon_node(
pub fn store_side_effects_for_anon_node(
&self,
dep_node_index: DepNodeIndex,
diagnostics: ThinVec<Diagnostic>,
side_effects: QuerySideEffects,
) {
let mut current_diagnostics = self.current_diagnostics.borrow_mut();

let x = current_diagnostics.entry(dep_node_index).or_default();
let mut current_side_effects = self.current_side_effects.borrow_mut();

x.extend(Into::<Vec<_>>::into(diagnostics));
let x = current_side_effects.entry(dep_node_index).or_default();
x.append(side_effects);
}

fn load_indexed<'tcx, T>(
Expand Down Expand Up @@ -1155,7 +1144,7 @@ impl<'a, 'tcx> Encodable<CacheEncoder<'a, 'tcx, FileEncoder>> for [u8] {
pub fn encode_query_results<'a, 'tcx, CTX, Q>(
tcx: CTX,
encoder: &mut CacheEncoder<'a, 'tcx, FileEncoder>,
query_result_index: &mut EncodedQueryResultIndex,
query_result_index: &mut EncodedDepNodeIndex,
) -> FileEncodeResult
where
CTX: QueryContext + 'tcx,
Expand Down
20 changes: 11 additions & 9 deletions compiler/rustc_query_impl/src/plumbing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ use rustc_middle::dep_graph::{DepKind, DepNode, DepNodeIndex, SerializedDepNodeI
use rustc_middle::ty::tls::{self, ImplicitCtxt};
use rustc_middle::ty::{self, TyCtxt};
use rustc_query_system::dep_graph::HasDepContext;
use rustc_query_system::query::{QueryContext, QueryDescription, QueryJobId, QueryMap};
use rustc_query_system::query::{
QueryContext, QueryDescription, QueryJobId, QueryMap, QuerySideEffects,
};

use rustc_data_structures::sync::Lock;
use rustc_data_structures::thin_vec::ThinVec;
Expand Down Expand Up @@ -83,27 +85,27 @@ impl QueryContext for QueryCtxt<'tcx> {
}

// Interactions with on_disk_cache
fn load_diagnostics(&self, prev_dep_node_index: SerializedDepNodeIndex) -> Vec<Diagnostic> {
fn load_side_effects(&self, prev_dep_node_index: SerializedDepNodeIndex) -> QuerySideEffects {
self.queries
.on_disk_cache
.as_ref()
.map(|c| c.load_diagnostics(**self, prev_dep_node_index))
.map(|c| c.load_side_effects(**self, prev_dep_node_index))
.unwrap_or_default()
}

fn store_diagnostics(&self, dep_node_index: DepNodeIndex, diagnostics: ThinVec<Diagnostic>) {
fn store_side_effects(&self, dep_node_index: DepNodeIndex, side_effects: QuerySideEffects) {
if let Some(c) = self.queries.on_disk_cache.as_ref() {
c.store_diagnostics(dep_node_index, diagnostics)
c.store_side_effects(dep_node_index, side_effects)
}
}

fn store_diagnostics_for_anon_node(
fn store_side_effects_for_anon_node(
&self,
dep_node_index: DepNodeIndex,
diagnostics: ThinVec<Diagnostic>,
side_effects: QuerySideEffects,
) {
if let Some(c) = self.queries.on_disk_cache.as_ref() {
c.store_diagnostics_for_anon_node(dep_node_index, diagnostics)
c.store_side_effects_for_anon_node(dep_node_index, side_effects)
}
}

Expand Down Expand Up @@ -163,7 +165,7 @@ impl<'tcx> QueryCtxt<'tcx> {
pub(super) fn encode_query_results(
self,
encoder: &mut on_disk_cache::CacheEncoder<'a, 'tcx, opaque::FileEncoder>,
query_result_index: &mut on_disk_cache::EncodedQueryResultIndex,
query_result_index: &mut on_disk_cache::EncodedDepNodeIndex,
) -> opaque::FileEncodeResult {
macro_rules! encode_queries {
($($query:ident,)*) => {
Expand Down
Loading