rustc_query_system: explicitly register reused dep nodes
Register nodes that we've reused from the previous session explicitly with `OnDiskCache`. Previously, we relied on this happening as a side effect of accessing the nodes in the `PreviousDepGraph`. For the sake of performance and avoiding unintended side effects, register explictily.
This commit is contained in:
parent
eb4fc71dc9
commit
7795801902
6 changed files with 51 additions and 62 deletions
|
@ -5,7 +5,7 @@ use rustc_data_structures::profiling::SelfProfilerRef;
|
|||
use rustc_data_structures::sync::Lock;
|
||||
use rustc_data_structures::thin_vec::ThinVec;
|
||||
use rustc_errors::Diagnostic;
|
||||
use rustc_hir::def_id::{DefPathHash, LocalDefId};
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
|
||||
mod dep_node;
|
||||
|
||||
|
@ -91,9 +91,9 @@ impl<'tcx> DepContext for TyCtxt<'tcx> {
|
|||
type DepKind = DepKind;
|
||||
type StableHashingContext = StableHashingContext<'tcx>;
|
||||
|
||||
fn register_reused_dep_path_hash(&self, hash: DefPathHash) {
|
||||
fn register_reused_dep_node(&self, dep_node: &DepNode) {
|
||||
if let Some(cache) = self.queries.on_disk_cache.as_ref() {
|
||||
cache.register_reused_dep_path_hash(*self, hash)
|
||||
cache.register_reused_dep_node(*self, dep_node)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::dep_graph::{DepNodeIndex, SerializedDepNodeIndex};
|
||||
use crate::dep_graph::{DepNode, DepNodeIndex, SerializedDepNodeIndex};
|
||||
use crate::mir::interpret::{AllocDecodingSession, AllocDecodingState};
|
||||
use crate::mir::{self, interpret};
|
||||
use crate::ty::codec::{OpaqueEncoder, RefDecodable, TyDecoder, TyEncoder};
|
||||
|
@ -264,6 +264,13 @@ impl<'sess> OnDiskCache<'sess> {
|
|||
(file_to_file_index, file_index_to_stable_id)
|
||||
};
|
||||
|
||||
// Register any dep nodes that we reused from the previous session,
|
||||
// but didn't `DepNode::construct` in this session. This ensures
|
||||
// that their `DefPathHash` to `RawDefId` mappings are registered
|
||||
// in 'latest_foreign_def_path_hashes' if necessary, since that
|
||||
// normally happens in `DepNode::construct`.
|
||||
tcx.dep_graph.register_reused_dep_nodes(tcx);
|
||||
|
||||
// Load everything into memory so we can write it out to the on-disk
|
||||
// cache. The vast majority of cacheable query results should already
|
||||
// be in memory, so this should be a cheap operation.
|
||||
|
@ -467,7 +474,7 @@ impl<'sess> OnDiskCache<'sess> {
|
|||
.insert(hash, RawDefId { krate: def_id.krate.as_u32(), index: def_id.index.as_u32() });
|
||||
}
|
||||
|
||||
/// If the given `hash` still exists in the current compilation,
|
||||
/// If the given `dep_node`'s hash still exists in the current compilation,
|
||||
/// calls `store_foreign_def_id` with its current `DefId`.
|
||||
///
|
||||
/// Normally, `store_foreign_def_id_hash` can be called directly by
|
||||
|
@ -476,13 +483,22 @@ impl<'sess> OnDiskCache<'sess> {
|
|||
/// session, we only have the `DefPathHash` available. This method is used
|
||||
/// to that any `DepNode` that we re-use has a `DefPathHash` -> `RawId` written
|
||||
/// out for usage in the next compilation session.
|
||||
pub fn register_reused_dep_path_hash(&self, tcx: TyCtxt<'tcx>, hash: DefPathHash) {
|
||||
// We can't simply copy the `RawDefId` from `foreign_def_path_hashes` to
|
||||
// `latest_foreign_def_path_hashes`, since the `RawDefId` might have
|
||||
// changed in the current compilation session (e.g. we've added/removed crates,
|
||||
// or added/removed definitions before/after the target definition).
|
||||
if let Some(def_id) = self.def_path_hash_to_def_id(tcx, hash) {
|
||||
self.store_foreign_def_id_hash(def_id, hash);
|
||||
pub fn register_reused_dep_node(&self, tcx: TyCtxt<'tcx>, dep_node: &DepNode) {
|
||||
// For reused dep nodes, we only need to store the mapping if the node
|
||||
// is one whose query key we can reconstruct from the hash. We use the
|
||||
// mapping to aid that reconstruction in the next session. While we also
|
||||
// use it to decode `DefId`s we encoded in the cache as `DefPathHashes`,
|
||||
// they're already registered during `DefId` encoding.
|
||||
if dep_node.kind.can_reconstruct_query_key() {
|
||||
let hash = DefPathHash(dep_node.hash.into());
|
||||
|
||||
// We can't simply copy the `RawDefId` from `foreign_def_path_hashes` to
|
||||
// `latest_foreign_def_path_hashes`, since the `RawDefId` might have
|
||||
// changed in the current compilation session (e.g. we've added/removed crates,
|
||||
// or added/removed definitions before/after the target definition).
|
||||
if let Some(def_id) = self.def_path_hash_to_def_id(tcx, hash) {
|
||||
self.store_foreign_def_id_hash(def_id, hash);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue