Hash during lowering.

This commit is contained in:
Camille GILLOT 2021-10-09 19:44:55 +02:00
parent 457de08487
commit ed3c8e86cb
4 changed files with 35 additions and 28 deletions

View File

@ -41,7 +41,9 @@ use rustc_ast::visit;
use rustc_ast::{self as ast, *};
use rustc_ast_pretty::pprust;
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::Lrc;
use rustc_errors::{struct_span_err, Applicability};
use rustc_hir as hir;
@ -467,7 +469,30 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
}
hir::OwnerInfo { node, attrs, bodies, trait_map }
let (hash, node_hash) = self.hash_body(node, &bodies);
hir::OwnerInfo { hash, node_hash, node, attrs, bodies, trait_map }
}
/// Hash the HIR node twice, one deep and one shallow hash. This allows to differentiate
/// queries which depend on the full HIR tree and those which only depend on the item signature.
fn hash_body(
&mut self,
node: hir::OwnerNode<'hir>,
bodies: &IndexVec<hir::ItemLocalId, Option<&'hir hir::Body<'hir>>>,
) -> (Fingerprint, Fingerprint) {
let mut hcx = self.resolver.create_stable_hashing_context();
let mut stable_hasher = StableHasher::new();
hcx.with_hir_bodies(true, node.def_id(), bodies, |hcx| {
node.hash_stable(hcx, &mut stable_hasher)
});
let full_hash = stable_hasher.finish();
let mut stable_hasher = StableHasher::new();
hcx.with_hir_bodies(false, node.def_id(), bodies, |hcx| {
node.hash_stable(hcx, &mut stable_hasher)
});
let node_hash = stable_hasher.finish();
(full_hash, node_hash)
}
/// This method allocates a new `HirId` for the given `NodeId` and stores it in

View File

@ -9,6 +9,7 @@ use rustc_ast::{Attribute, FloatTy, IntTy, Label, LitKind, StrStyle, TraitObject
pub use rustc_ast::{BorrowKind, ImplPolarity, IsAuto};
pub use rustc_ast::{CaptureBy, Movability, Mutability};
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::FxHashMap;
use rustc_index::vec::IndexVec;
use rustc_macros::HashStable_Generic;
@ -670,6 +671,10 @@ pub struct OwnerInfo<'hir> {
/// Map indicating what traits are in scope for places where this
/// is relevant; generated by resolve.
pub trait_map: FxHashMap<ItemLocalId, Box<[TraitCandidate]>>,
/// Pre-computed hash of the full HIR.
pub hash: Fingerprint,
/// Pre-computed hash of the top node.
pub node_hash: Fingerprint,
}
/// The top-level data structure that stores the entire contents of

View File

@ -1,9 +1,7 @@
use crate::arena::Arena;
use crate::hir::map::Map;
use crate::hir::{IndexedHir, OwnerNodes, ParentedNode};
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::def_id::CRATE_DEF_ID;
@ -11,7 +9,6 @@ use rustc_hir::definitions;
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
use rustc_hir::*;
use rustc_index::vec::{Idx, IndexVec};
use rustc_query_system::ich::StableHashingContext;
use rustc_session::Session;
use rustc_span::source_map::SourceMap;
use rustc_span::{Span, DUMMY_SP};
@ -37,8 +34,6 @@ pub(super) struct NodeCollector<'a, 'hir> {
current_dep_node_owner: LocalDefId,
definitions: &'a definitions::Definitions,
hcx: StableHashingContext<'a>,
}
fn insert_vec_map<K: Idx, V: Clone>(map: &mut IndexVec<K, Option<V>>, k: K, v: V) {
@ -51,27 +46,12 @@ fn insert_vec_map<K: Idx, V: Clone>(map: &mut IndexVec<K, Option<V>>, k: K, v: V
map[k] = Some(v);
}
fn hash_body<'s, 'hir: 's>(
hcx: &mut StableHashingContext<'s>,
item_like: impl for<'a> HashStable<StableHashingContext<'a>>,
hash_bodies: bool,
owner: LocalDefId,
bodies: &'hir IndexVec<ItemLocalId, Option<&'hir Body<'hir>>>,
) -> Fingerprint {
let mut stable_hasher = StableHasher::new();
hcx.with_hir_bodies(hash_bodies, owner, bodies, |hcx| {
item_like.hash_stable(hcx, &mut stable_hasher)
});
stable_hasher.finish()
}
impl<'a, 'hir: 'a> NodeCollector<'a, 'hir> {
pub(super) fn root(
sess: &'a Session,
arena: &'hir Arena<'hir>,
krate: &'hir Crate<'hir>,
definitions: &'a definitions::Definitions,
hcx: StableHashingContext<'a>,
) -> NodeCollector<'a, 'hir> {
let mut collector = NodeCollector {
arena,
@ -80,7 +60,6 @@ impl<'a, 'hir: 'a> NodeCollector<'a, 'hir> {
parent_node: hir::CRATE_HIR_ID,
current_dep_node_owner: CRATE_DEF_ID,
definitions,
hcx,
map: IndexVec::from_fn_n(|_| None, definitions.def_index_count()),
parenting: FxHashMap::default(),
};
@ -97,10 +76,10 @@ impl<'a, 'hir: 'a> NodeCollector<'a, 'hir> {
let mut nodes = IndexVec::new();
nodes.push(Some(ParentedNode { parent: ItemLocalId::new(0), node: node.into() }));
let bodies = &self.krate.owners[owner].as_ref().unwrap().bodies;
let hash = hash_body(&mut self.hcx, node, true, owner, bodies);
let node_hash = hash_body(&mut self.hcx, node, false, owner, bodies);
let info = self.krate.owners[owner].as_ref().unwrap();
let hash = info.hash;
let node_hash = info.node_hash;
let bodies = &info.bodies;
debug_assert!(self.map[owner].is_none());
self.map[owner] = Some(self.arena.alloc(OwnerNodes { hash, node_hash, nodes, bodies }));

View File

@ -1071,13 +1071,11 @@ pub(super) fn index_hir<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> &'tcx IndexedHir<'tc
let _prof_timer = tcx.sess.prof.generic_activity("build_hir_map");
// We can access untracked state since we are an eval_always query.
let hcx = tcx.create_stable_hashing_context();
let mut collector = NodeCollector::root(
tcx.sess,
&**tcx.arena,
tcx.untracked_crate,
&tcx.untracked_resolutions.definitions,
hcx,
);
let top_mod = tcx.untracked_crate.module();
collector.visit_mod(top_mod, top_mod.inner, CRATE_HIR_ID);