1
Fork 0

Split crate_hash from index_hir.

This commit is contained in:
Camille GILLOT 2021-02-28 18:58:50 +01:00
parent 553004539e
commit 323f5b2ac9
7 changed files with 99 additions and 119 deletions

View file

@ -91,7 +91,7 @@ macro_rules! arena_types {
[] predicates: rustc_middle::ty::PredicateInner<$tcx>, [] predicates: rustc_middle::ty::PredicateInner<$tcx>,
// HIR query types // HIR query types
[few] indexed_hir: rustc_middle::hir::map::IndexedHir<$tcx>, [few] indexed_hir: rustc_middle::hir::IndexedHir<$tcx>,
[few] hir_definitions: rustc_hir::definitions::Definitions, [few] hir_definitions: rustc_hir::definitions::Definitions,
[] hir_owner: rustc_middle::hir::Owner<$tcx>, [] hir_owner: rustc_middle::hir::Owner<$tcx>,
[] hir_owner_nodes: rustc_middle::hir::OwnerNodes<$tcx>, [] hir_owner_nodes: rustc_middle::hir::OwnerNodes<$tcx>,

View file

@ -2,21 +2,19 @@ use crate::arena::Arena;
use crate::hir::map::{Entry, HirOwnerData, Map}; use crate::hir::map::{Entry, HirOwnerData, Map};
use crate::hir::{Owner, OwnerNodes, ParentedNode}; use crate::hir::{Owner, OwnerNodes, ParentedNode};
use crate::ich::StableHashingContext; use crate::ich::StableHashingContext;
use crate::middle::cstore::CrateStore;
use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::svh::Svh;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::def_id::CRATE_DEF_INDEX; use rustc_hir::def_id::CRATE_DEF_INDEX;
use rustc_hir::def_id::{LocalDefId, LOCAL_CRATE}; use rustc_hir::definitions;
use rustc_hir::definitions::{self, DefPathHash};
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
use rustc_hir::*; use rustc_hir::*;
use rustc_index::vec::{Idx, IndexVec}; use rustc_index::vec::{Idx, IndexVec};
use rustc_session::{CrateDisambiguator, Session}; use rustc_session::Session;
use rustc_span::source_map::SourceMap; use rustc_span::source_map::SourceMap;
use rustc_span::{Span, Symbol, DUMMY_SP}; use rustc_span::{Span, DUMMY_SP};
use std::iter::repeat; use std::iter::repeat;
@ -40,10 +38,6 @@ pub(super) struct NodeCollector<'a, 'hir> {
definitions: &'a definitions::Definitions, definitions: &'a definitions::Definitions,
hcx: StableHashingContext<'a>, hcx: StableHashingContext<'a>,
// We are collecting HIR hashes here so we can compute the
// crate hash from them later on.
hir_body_nodes: Vec<(DefPathHash, Fingerprint)>,
} }
fn insert_vec_map<K: Idx, V: Clone>(map: &mut IndexVec<K, Option<V>>, k: K, v: V) { fn insert_vec_map<K: Idx, V: Clone>(map: &mut IndexVec<K, Option<V>>, k: K, v: V) {
@ -58,34 +52,13 @@ fn insert_vec_map<K: Idx, V: Clone>(map: &mut IndexVec<K, Option<V>>, k: K, v: V
fn hash_body( fn hash_body(
hcx: &mut StableHashingContext<'_>, hcx: &mut StableHashingContext<'_>,
def_path_hash: DefPathHash,
item_like: impl for<'a> HashStable<StableHashingContext<'a>>, item_like: impl for<'a> HashStable<StableHashingContext<'a>>,
hir_body_nodes: &mut Vec<(DefPathHash, Fingerprint)>,
) -> Fingerprint { ) -> Fingerprint {
let hash = { let mut stable_hasher = StableHasher::new();
let mut stable_hasher = StableHasher::new(); hcx.while_hashing_hir_bodies(true, |hcx| {
hcx.while_hashing_hir_bodies(true, |hcx| { item_like.hash_stable(hcx, &mut stable_hasher);
item_like.hash_stable(hcx, &mut stable_hasher); });
}); stable_hasher.finish()
stable_hasher.finish()
};
hir_body_nodes.push((def_path_hash, hash));
hash
}
fn upstream_crates(cstore: &dyn CrateStore) -> Vec<(Symbol, Fingerprint, Svh)> {
let mut upstream_crates: Vec<_> = cstore
.crates_untracked()
.iter()
.map(|&cnum| {
let name = cstore.crate_name_untracked(cnum);
let disambiguator = cstore.crate_disambiguator_untracked(cnum).to_fingerprint();
let hash = cstore.crate_hash_untracked(cnum);
(name, disambiguator, hash)
})
.collect();
upstream_crates.sort_unstable_by_key(|&(name, dis, _)| (name.as_str(), dis));
upstream_crates
} }
impl<'a, 'hir> NodeCollector<'a, 'hir> { impl<'a, 'hir> NodeCollector<'a, 'hir> {
@ -96,11 +69,6 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
definitions: &'a definitions::Definitions, definitions: &'a definitions::Definitions,
mut hcx: StableHashingContext<'a>, mut hcx: StableHashingContext<'a>,
) -> NodeCollector<'a, 'hir> { ) -> NodeCollector<'a, 'hir> {
let root_mod_def_path_hash =
definitions.def_path_hash(LocalDefId { local_def_index: CRATE_DEF_INDEX });
let mut hir_body_nodes = Vec::new();
let hash = { let hash = {
let Crate { let Crate {
ref item, ref item,
@ -120,7 +88,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
attrs: _, attrs: _,
} = *krate; } = *krate;
hash_body(&mut hcx, root_mod_def_path_hash, item, &mut hir_body_nodes) hash_body(&mut hcx, item)
}; };
let mut collector = NodeCollector { let mut collector = NodeCollector {
@ -131,7 +99,6 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
current_dep_node_owner: LocalDefId { local_def_index: CRATE_DEF_INDEX }, current_dep_node_owner: LocalDefId { local_def_index: CRATE_DEF_INDEX },
definitions, definitions,
hcx, hcx,
hir_body_nodes,
map: (0..definitions.def_index_count()) map: (0..definitions.def_index_count())
.map(|_| HirOwnerData { signature: None, with_bodies: None }) .map(|_| HirOwnerData { signature: None, with_bodies: None })
.collect(), .collect(),
@ -147,53 +114,13 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
pub(super) fn finalize_and_compute_crate_hash( pub(super) fn finalize_and_compute_crate_hash(
mut self, mut self,
crate_disambiguator: CrateDisambiguator, ) -> IndexVec<LocalDefId, HirOwnerData<'hir>> {
cstore: &dyn CrateStore,
commandline_args_hash: u64,
) -> (IndexVec<LocalDefId, HirOwnerData<'hir>>, Svh) {
// Insert bodies into the map // Insert bodies into the map
for (id, body) in self.krate.bodies.iter() { for (id, body) in self.krate.bodies.iter() {
let bodies = &mut self.map[id.hir_id.owner].with_bodies.as_mut().unwrap().bodies; let bodies = &mut self.map[id.hir_id.owner].with_bodies.as_mut().unwrap().bodies;
assert!(bodies.insert(id.hir_id.local_id, body).is_none()); assert!(bodies.insert(id.hir_id.local_id, body).is_none());
} }
self.map
self.hir_body_nodes.sort_unstable_by_key(|bn| bn.0);
let node_hashes = self.hir_body_nodes.iter().fold(
Fingerprint::ZERO,
|combined_fingerprint, &(def_path_hash, fingerprint)| {
combined_fingerprint.combine(def_path_hash.0.combine(fingerprint))
},
);
let upstream_crates = upstream_crates(cstore);
// We hash the final, remapped names of all local source files so we
// don't have to include the path prefix remapping commandline args.
// If we included the full mapping in the SVH, we could only have
// reproducible builds by compiling from the same directory. So we just
// hash the result of the mapping instead of the mapping itself.
let mut source_file_names: Vec<_> = self
.source_map
.files()
.iter()
.filter(|source_file| source_file.cnum == LOCAL_CRATE)
.map(|source_file| source_file.name_hash)
.collect();
source_file_names.sort_unstable();
let crate_hash_input = (
((node_hashes, upstream_crates), source_file_names),
(commandline_args_hash, crate_disambiguator.to_fingerprint()),
);
let mut stable_hasher = StableHasher::new();
crate_hash_input.hash_stable(&mut self.hcx, &mut stable_hasher);
let crate_hash: Fingerprint = stable_hasher.finish();
let svh = Svh::new(crate_hash.to_smaller_hash());
(self.map, svh)
} }
fn insert_entry(&mut self, id: HirId, entry: Entry<'hir>, hash: Fingerprint) { fn insert_entry(&mut self, id: HirId, entry: Entry<'hir>, hash: Fingerprint) {
@ -294,10 +221,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
f: F, f: F,
) { ) {
let prev_owner = self.current_dep_node_owner; let prev_owner = self.current_dep_node_owner;
let hash = hash_body(&mut self.hcx, item_like);
let def_path_hash = self.definitions.def_path_hash(dep_node_owner);
let hash = hash_body(&mut self.hcx, def_path_hash, item_like, &mut self.hir_body_nodes);
self.current_dep_node_owner = dep_node_owner; self.current_dep_node_owner = dep_node_owner;
f(self, hash); f(self, hash);

View file

@ -1,8 +1,11 @@
use self::collector::NodeCollector; use self::collector::NodeCollector;
use crate::hir::{Owner, OwnerNodes}; use crate::hir::{HirOwnerData, IndexedHir};
use crate::middle::cstore::CrateStore;
use crate::ty::TyCtxt; use crate::ty::TyCtxt;
use rustc_ast as ast; use rustc_ast as ast;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::svh::Svh; use rustc_data_structures::svh::Svh;
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
@ -11,7 +14,6 @@ use rustc_hir::intravisit;
use rustc_hir::intravisit::Visitor; use rustc_hir::intravisit::Visitor;
use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_hir::itemlikevisit::ItemLikeVisitor;
use rustc_hir::*; use rustc_hir::*;
use rustc_index::vec::IndexVec;
use rustc_span::hygiene::MacroKind; use rustc_span::hygiene::MacroKind;
use rustc_span::source_map::Spanned; use rustc_span::source_map::Spanned;
use rustc_span::symbol::{kw, Ident, Symbol}; use rustc_span::symbol::{kw, Ident, Symbol};
@ -86,20 +88,6 @@ fn is_body_owner<'hir>(node: Node<'hir>, hir_id: HirId) -> bool {
} }
} }
#[derive(Debug)]
pub(super) struct HirOwnerData<'hir> {
pub(super) signature: Option<&'hir Owner<'hir>>,
pub(super) with_bodies: Option<&'hir mut OwnerNodes<'hir>>,
}
#[derive(Debug)]
pub struct IndexedHir<'hir> {
/// The SVH of the local crate.
pub crate_hash: Svh,
pub(super) map: IndexVec<LocalDefId, HirOwnerData<'hir>>,
}
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct Map<'hir> { pub struct Map<'hir> {
pub(super) tcx: TyCtxt<'hir>, pub(super) tcx: TyCtxt<'hir>,
@ -935,19 +923,82 @@ pub(super) fn index_hir<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> &'tcx Indexe
let _prof_timer = tcx.sess.prof.generic_activity("build_hir_map"); let _prof_timer = tcx.sess.prof.generic_activity("build_hir_map");
let (map, crate_hash) = { let map = {
let hcx = tcx.create_stable_hashing_context(); let hcx = tcx.create_stable_hashing_context();
let mut collector = let mut collector =
NodeCollector::root(tcx.sess, &**tcx.arena, tcx.untracked_crate, &tcx.definitions, hcx); NodeCollector::root(tcx.sess, &**tcx.arena, tcx.untracked_crate, &tcx.definitions, hcx);
intravisit::walk_crate(&mut collector, tcx.untracked_crate); intravisit::walk_crate(&mut collector, tcx.untracked_crate);
let crate_disambiguator = tcx.sess.local_crate_disambiguator(); collector.finalize_and_compute_crate_hash()
let cmdline_args = tcx.sess.opts.dep_tracking_hash(true);
collector.finalize_and_compute_crate_hash(crate_disambiguator, &*tcx.cstore, cmdline_args)
}; };
tcx.arena.alloc(IndexedHir { crate_hash, map }) tcx.arena.alloc(IndexedHir { map })
}
pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
let mut hir_body_nodes: Vec<_> = tcx
.index_hir(crate_num)
.map
.iter_enumerated()
.filter_map(|(def_id, hod)| {
let def_path_hash = tcx.definitions.def_path_hash(def_id);
let hash = hod.with_bodies.as_ref()?.hash;
Some((def_path_hash, hash))
})
.collect();
hir_body_nodes.sort_unstable_by_key(|bn| bn.0);
let node_hashes = hir_body_nodes.iter().fold(
Fingerprint::ZERO,
|combined_fingerprint, &(def_path_hash, fingerprint)| {
combined_fingerprint.combine(def_path_hash.0.combine(fingerprint))
},
);
let upstream_crates = upstream_crates(&*tcx.cstore);
// We hash the final, remapped names of all local source files so we
// don't have to include the path prefix remapping commandline args.
// If we included the full mapping in the SVH, we could only have
// reproducible builds by compiling from the same directory. So we just
// hash the result of the mapping instead of the mapping itself.
let mut source_file_names: Vec<_> = tcx
.sess
.source_map()
.files()
.iter()
.filter(|source_file| source_file.cnum == LOCAL_CRATE)
.map(|source_file| source_file.name_hash)
.collect();
source_file_names.sort_unstable();
let mut hcx = tcx.create_stable_hashing_context();
let mut stable_hasher = StableHasher::new();
node_hashes.hash_stable(&mut hcx, &mut stable_hasher);
upstream_crates.hash_stable(&mut hcx, &mut stable_hasher);
source_file_names.hash_stable(&mut hcx, &mut stable_hasher);
tcx.sess.opts.dep_tracking_hash(true).hash_stable(&mut hcx, &mut stable_hasher);
tcx.sess.local_crate_disambiguator().to_fingerprint().hash_stable(&mut hcx, &mut stable_hasher);
let crate_hash: Fingerprint = stable_hasher.finish();
Svh::new(crate_hash.to_smaller_hash())
}
fn upstream_crates(cstore: &dyn CrateStore) -> Vec<(Symbol, Fingerprint, Svh)> {
let mut upstream_crates: Vec<_> = cstore
.crates_untracked()
.iter()
.map(|&cnum| {
let name = cstore.crate_name_untracked(cnum);
let disambiguator = cstore.crate_disambiguator_untracked(cnum).to_fingerprint();
let hash = cstore.crate_hash_untracked(cnum);
(name, disambiguator, hash)
})
.collect();
upstream_crates.sort_unstable_by_key(|&(name, dis, _)| (name.as_str(), dis));
upstream_crates
} }
fn hir_id_to_string(map: &Map<'_>, id: HirId) -> String { fn hir_id_to_string(map: &Map<'_>, id: HirId) -> String {

View file

@ -19,6 +19,17 @@ use rustc_index::vec::IndexVec;
use rustc_span::DUMMY_SP; use rustc_span::DUMMY_SP;
use std::collections::BTreeMap; use std::collections::BTreeMap;
#[derive(Debug)]
struct HirOwnerData<'hir> {
signature: Option<&'hir Owner<'hir>>,
with_bodies: Option<&'hir mut OwnerNodes<'hir>>,
}
#[derive(Debug)]
pub struct IndexedHir<'hir> {
map: IndexVec<LocalDefId, HirOwnerData<'hir>>,
}
#[derive(Debug)] #[derive(Debug)]
pub struct Owner<'tcx> { pub struct Owner<'tcx> {
parent: HirId, parent: HirId,
@ -117,6 +128,7 @@ pub fn provide(providers: &mut Providers) {
}; };
providers.hir_crate = |tcx, _| tcx.untracked_crate; providers.hir_crate = |tcx, _| tcx.untracked_crate;
providers.index_hir = map::index_hir; providers.index_hir = map::index_hir;
providers.crate_hash = map::crate_hash;
providers.hir_module_items = |tcx, id| &tcx.untracked_crate.modules[&id]; providers.hir_module_items = |tcx, id| &tcx.untracked_crate.modules[&id];
providers.hir_owner = |tcx, id| tcx.index_hir(LOCAL_CRATE).map[id].signature; providers.hir_owner = |tcx, id| tcx.index_hir(LOCAL_CRATE).map[id].signature;
providers.hir_owner_nodes = |tcx, id| tcx.index_hir(LOCAL_CRATE).map[id].with_bodies.as_deref(); providers.hir_owner_nodes = |tcx, id| tcx.index_hir(LOCAL_CRATE).map[id].with_bodies.as_deref();

View file

@ -28,7 +28,7 @@ rustc_queries! {
/// The indexed HIR. This can be conveniently accessed by `tcx.hir()`. /// The indexed HIR. This can be conveniently accessed by `tcx.hir()`.
/// Avoid calling this query directly. /// Avoid calling this query directly.
query index_hir(_: CrateNum) -> &'tcx map::IndexedHir<'tcx> { query index_hir(_: CrateNum) -> &'tcx crate::hir::IndexedHir<'tcx> {
eval_always eval_always
no_hash no_hash
desc { "index HIR" } desc { "index HIR" }

View file

@ -1,6 +1,5 @@
use crate::dep_graph; use crate::dep_graph;
use crate::hir::exports::Export; use crate::hir::exports::Export;
use crate::hir::map;
use crate::infer::canonical::{self, Canonical}; use crate::infer::canonical::{self, Canonical};
use crate::lint::LintLevelMap; use crate::lint::LintLevelMap;
use crate::middle::codegen_fn_attrs::CodegenFnAttrs; use crate::middle::codegen_fn_attrs::CodegenFnAttrs;

View file

@ -1,5 +1,4 @@
use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::fx::FxIndexSet;
use rustc_data_structures::svh::Svh;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
use rustc_middle::hir::map as hir_map; use rustc_middle::hir::map as hir_map;
@ -400,10 +399,6 @@ fn original_crate_name(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Symbol {
tcx.crate_name tcx.crate_name
} }
fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
tcx.index_hir(crate_num).crate_hash
}
fn instance_def_size_estimate<'tcx>( fn instance_def_size_estimate<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
instance_def: ty::InstanceDef<'tcx>, instance_def: ty::InstanceDef<'tcx>,
@ -551,7 +546,6 @@ pub fn provide(providers: &mut ty::query::Providers) {
trait_of_item, trait_of_item,
crate_disambiguator, crate_disambiguator,
original_crate_name, original_crate_name,
crate_hash,
instance_def_size_estimate, instance_def_size_estimate,
issue33140_self_ty, issue33140_self_ty,
impl_defaultness, impl_defaultness,