Skip to content

Commit 1b006b7

Browse files
authored
Rollup merge of rust-lang#41141 - michaelwoerister:direct-metadata-ich-final, r=nikomatsakis
ICH: Replace old, transitive metadata hashing with direct hashing approach. This PR replaces the old crate metadata hashing strategy with a new one that directly (but stably) hashes all values we encode into the metadata. Previously we would track what data got accessed during metadata encoding and then hash the input nodes (HIR and upstream metadata) that were transitively reachable from the accessed data. While this strategy was sound, it had two major downsides: 1. It was susceptible to generating false positives, i.e. some input node might have changed without actually affecting the content of the metadata. That metadata entry would still show up as changed. 2. It was susceptible to quadratic blow-up when many metadata nodes shared the same input nodes, which would then get hashed over and over again. The new method does not have these disadvantages and it's also a first step towards caching more intermediate results in the compiler. Metadata hashing/cross-crate incremental compilation is still kept behind the `-Zincremental-cc` flag even after this PR. Once the new method has proven itself with more tests, we can remove the flag and enable cross-crate support by default again. r? @nikomatsakis cc @rust-lang/compiler
2 parents 918e35a + ca2dce9 commit 1b006b7

36 files changed

+1241
-377
lines changed

src/librustc/ich/hcx.rs

+52
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ use hir::def_id::DefId;
1313
use ich::{self, CachingCodemapView};
1414
use session::config::DebugInfoLevel::NoDebugInfo;
1515
use ty;
16+
use util::nodemap::NodeMap;
1617

1718
use std::hash as std_hash;
19+
use std::collections::{HashMap, HashSet};
1820

1921
use syntax::ast;
2022
use syntax::attr;
@@ -296,3 +298,53 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for Span {
296298
}
297299
}
298300
}
301+
302+
pub fn hash_stable_hashmap<'a, 'tcx, K, V, R, SK, F, W>(hcx: &mut StableHashingContext<'a, 'tcx>,
303+
hasher: &mut StableHasher<W>,
304+
map: &HashMap<K, V, R>,
305+
extract_stable_key: F)
306+
where K: Eq + std_hash::Hash,
307+
V: HashStable<StableHashingContext<'a, 'tcx>>,
308+
R: std_hash::BuildHasher,
309+
SK: HashStable<StableHashingContext<'a, 'tcx>> + Ord + Clone,
310+
F: Fn(&mut StableHashingContext<'a, 'tcx>, &K) -> SK,
311+
W: StableHasherResult,
312+
{
313+
let mut keys: Vec<_> = map.keys()
314+
.map(|k| (extract_stable_key(hcx, k), k))
315+
.collect();
316+
keys.sort_unstable_by_key(|&(ref stable_key, _)| stable_key.clone());
317+
keys.len().hash_stable(hcx, hasher);
318+
for (stable_key, key) in keys {
319+
stable_key.hash_stable(hcx, hasher);
320+
map[key].hash_stable(hcx, hasher);
321+
}
322+
}
323+
324+
pub fn hash_stable_hashset<'a, 'tcx, K, R, SK, F, W>(hcx: &mut StableHashingContext<'a, 'tcx>,
325+
hasher: &mut StableHasher<W>,
326+
set: &HashSet<K, R>,
327+
extract_stable_key: F)
328+
where K: Eq + std_hash::Hash,
329+
R: std_hash::BuildHasher,
330+
SK: HashStable<StableHashingContext<'a, 'tcx>> + Ord + Clone,
331+
F: Fn(&mut StableHashingContext<'a, 'tcx>, &K) -> SK,
332+
W: StableHasherResult,
333+
{
334+
let mut keys: Vec<_> = set.iter()
335+
.map(|k| extract_stable_key(hcx, k))
336+
.collect();
337+
keys.sort_unstable();
338+
keys.hash_stable(hcx, hasher);
339+
}
340+
341+
pub fn hash_stable_nodemap<'a, 'tcx, V, W>(hcx: &mut StableHashingContext<'a, 'tcx>,
342+
hasher: &mut StableHasher<W>,
343+
map: &NodeMap<V>)
344+
where V: HashStable<StableHashingContext<'a, 'tcx>>,
345+
W: StableHasherResult,
346+
{
347+
hash_stable_hashmap(hcx, hasher, map, |hcx, node_id| {
348+
hcx.tcx.hir.definitions().node_to_hir_id(*node_id).local_id
349+
});
350+
}

0 commit comments

Comments
 (0)