Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 547232c

Browse files
committed
Auto merge of rust-lang#119976 - cjgillot:shallow-hash, r=<try>
Do not compute the shallow hash twice. r? `@ghost`
2 parents 665d2c6 + bcadd68 commit 547232c

File tree

7 files changed

+32
-49
lines changed

7 files changed

+32
-49
lines changed

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -659,25 +659,28 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
659659
let bodies = SortedMap::from_presorted_elements(bodies);
660660

661661
// Don't hash unless necessary, because it's expensive.
662-
let (opt_hash_including_bodies, attrs_hash) = if self.tcx.needs_crate_hash() {
662+
let (opt_hash_without_bodies, opt_bodies_hash, attrs_hash) = if self.tcx.needs_crate_hash()
663+
{
663664
self.tcx.with_stable_hashing_context(|mut hcx| {
664665
let mut stable_hasher = StableHasher::new();
665-
hcx.with_hir_bodies(node.def_id(), &bodies, |hcx| {
666-
node.hash_stable(hcx, &mut stable_hasher)
667-
});
666+
hcx.without_hir_bodies(|hcx| node.hash_stable(hcx, &mut stable_hasher));
668667
let h1 = stable_hasher.finish();
669668

670669
let mut stable_hasher = StableHasher::new();
671-
attrs.hash_stable(&mut hcx, &mut stable_hasher);
670+
hcx.without_hir_bodies(|hcx| bodies.hash_stable(hcx, &mut stable_hasher));
672671
let h2 = stable_hasher.finish();
673672

674-
(Some(h1), Some(h2))
673+
let mut stable_hasher = StableHasher::new();
674+
attrs.hash_stable(&mut hcx, &mut stable_hasher);
675+
let h3 = stable_hasher.finish();
676+
677+
(Some(h1), Some(h2), Some(h3))
675678
})
676679
} else {
677-
(None, None)
680+
(None, None, None)
678681
};
679682
let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies);
680-
let nodes = hir::OwnerNodes { opt_hash_including_bodies, nodes, bodies };
683+
let nodes = hir::OwnerNodes { opt_hash_without_bodies, opt_bodies_hash, nodes, bodies };
681684
let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash };
682685

683686
self.arena.alloc(hir::OwnerInfo { nodes, parenting, attrs, trait_map })

compiler/rustc_hir/src/hir.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -830,7 +830,11 @@ impl<'tcx> AttributeMap<'tcx> {
830830
pub struct OwnerNodes<'tcx> {
831831
/// Pre-computed hash of the full HIR. Used in the crate hash. Only present
832832
/// when incr. comp. is enabled.
833-
pub opt_hash_including_bodies: Option<Fingerprint>,
833+
pub opt_bodies_hash: Option<Fingerprint>,
834+
/// Perform a shallow hash instead using the deep hash saved in `OwnerNodes`. This lets us
835+
/// differentiate queries that depend on the full HIR tree from those that only depend on
836+
/// the item signature.
837+
pub opt_hash_without_bodies: Option<Fingerprint>,
834838
/// Full HIR for the current owner.
835839
// The zeroth node's parent should never be accessed: the owner's parent is computed by the
836840
// hir_owner_parent query. It is set to `ItemLocalId::INVALID` to force an ICE if accidentally
@@ -867,7 +871,8 @@ impl fmt::Debug for OwnerNodes<'_> {
867871
.collect::<Vec<_>>(),
868872
)
869873
.field("bodies", &self.bodies)
870-
.field("opt_hash_including_bodies", &self.opt_hash_including_bodies)
874+
.field("opt_hash_without_bodies", &self.opt_hash_without_bodies)
875+
.field("opt_bodies_hash", &self.opt_bodies_hash)
871876
.finish()
872877
}
873878
}

compiler/rustc_hir/src/stable_hash_impls.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,9 @@ impl<'tcx, HirCtx: crate::HashStableContext> HashStable<HirCtx> for OwnerNodes<'
100100
// `local_id_to_def_id` is also ignored because is dependent on the body, then just hashing
101101
// the body satisfies the condition of two nodes being different have different
102102
// `hash_stable` results.
103-
let OwnerNodes { opt_hash_including_bodies, nodes: _, bodies: _ } = *self;
104-
opt_hash_including_bodies.unwrap().hash_stable(hcx, hasher);
103+
let OwnerNodes { opt_hash_without_bodies, opt_bodies_hash, nodes: _, bodies: _ } = *self;
104+
opt_hash_without_bodies.unwrap().hash_stable(hcx, hasher);
105+
opt_bodies_hash.unwrap().hash_stable(hcx, hasher);
105106
}
106107
}
107108

compiler/rustc_middle/src/hir/mod.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ pub mod place;
88

99
use crate::query::Providers;
1010
use crate::ty::{EarlyBinder, ImplSubject, TyCtxt};
11+
use rustc_data_structures::fingerprint::Fingerprint;
1112
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
1213
use rustc_data_structures::sync::{try_par_for_each_in, DynSend, DynSync};
1314
use rustc_hir::def::DefKind;
@@ -24,15 +25,13 @@ use rustc_span::{ErrorGuaranteed, ExpnId, DUMMY_SP};
2425
#[derive(Copy, Clone, Debug)]
2526
pub struct Owner<'tcx> {
2627
node: OwnerNode<'tcx>,
28+
opt_hash_without_bodies: Option<Fingerprint>,
2729
}
2830

2931
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Owner<'tcx> {
3032
#[inline]
3133
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
32-
// Perform a shallow hash instead using the deep hash saved in `OwnerNodes`. This lets us
33-
// differentiate queries that depend on the full HIR tree from those that only depend on
34-
// the item signature.
35-
hcx.without_hir_bodies(|hcx| self.node.hash_stable(hcx, hasher));
34+
self.opt_hash_without_bodies.hash_stable(hcx, hasher)
3635
}
3736
}
3837

@@ -152,7 +151,7 @@ pub fn provide(providers: &mut Providers) {
152151
providers.hir_owner = |tcx, id| {
153152
let owner = tcx.hir_crate(()).owners.get(id.def_id)?.as_owner()?;
154153
let node = owner.node();
155-
Some(Owner { node })
154+
Some(Owner { node, opt_hash_without_bodies: owner.nodes.opt_hash_without_bodies })
156155
};
157156
providers.opt_local_def_id_to_hir_id = |tcx, id| {
158157
let owner = tcx.hir_crate(()).owners[id].map(|_| ());

compiler/rustc_mir_transform/src/coverage/mod.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use self::spans::{BcbMapping, BcbMappingKind, CoverageSpans};
1313

1414
use crate::MirPass;
1515

16+
use rustc_data_structures::fingerprint::Fingerprint;
1617
use rustc_middle::hir;
1718
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
1819
use rustc_middle::mir::coverage::*;
@@ -419,12 +420,9 @@ fn get_body_span<'tcx>(
419420
}
420421

421422
fn hash_mir_source<'tcx>(tcx: TyCtxt<'tcx>, hir_body: &'tcx rustc_hir::Body<'tcx>) -> u64 {
422-
// FIXME(cjgillot) Stop hashing HIR manually here.
423423
let owner = hir_body.id().hir_id.owner;
424-
tcx.hir_owner_nodes(owner)
425-
.unwrap()
426-
.opt_hash_including_bodies
427-
.unwrap()
424+
let owner = tcx.hir_owner_nodes(owner).unwrap();
425+
Fingerprint::combine(owner.opt_hash_without_bodies.unwrap(), owner.opt_bodies_hash.unwrap())
428426
.to_smaller_hash()
429427
.as_u64()
430428
}

compiler/rustc_query_system/src/ich/hcx.rs

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
use crate::ich;
22

33
use rustc_ast as ast;
4-
use rustc_data_structures::sorted_map::SortedMap;
54
use rustc_data_structures::stable_hasher::{HashStable, HashingControls, StableHasher};
65
use rustc_data_structures::sync::Lrc;
7-
use rustc_hir as hir;
86
use rustc_hir::def_id::{DefId, LocalDefId};
97
use rustc_hir::definitions::DefPathHash;
108
use rustc_session::cstore::Untracked;
@@ -23,7 +21,7 @@ pub struct StableHashingContext<'a> {
2321
// The value of `-Z incremental-ignore-spans`.
2422
// This field should only be used by `unstable_opts_incremental_ignore_span`
2523
incremental_ignore_spans: bool,
26-
pub(super) body_resolver: BodyResolver<'a>,
24+
pub(super) body_resolver: BodyResolver,
2725
// Very often, we are hashing something that does not need the
2826
// `CachingSourceMapView`, so we initialize it lazily.
2927
raw_source_map: &'a SourceMap,
@@ -35,13 +33,9 @@ pub struct StableHashingContext<'a> {
3533
/// We could also just store a plain reference to the `hir::Crate` but we want
3634
/// to avoid that the crate is used to get untracked access to all of the HIR.
3735
#[derive(Clone, Copy)]
38-
pub(super) enum BodyResolver<'tcx> {
36+
pub(super) enum BodyResolver {
3937
Forbidden,
4038
Ignore,
41-
Traverse {
42-
owner: hir::OwnerId,
43-
bodies: &'tcx SortedMap<hir::ItemLocalId, &'tcx hir::Body<'tcx>>,
44-
},
4539
}
4640

4741
impl<'a> StableHashingContext<'a> {
@@ -64,19 +58,6 @@ impl<'a> StableHashingContext<'a> {
6458
f(&mut StableHashingContext { body_resolver: BodyResolver::Ignore, ..self.clone() });
6559
}
6660

67-
#[inline]
68-
pub fn with_hir_bodies(
69-
&mut self,
70-
owner: hir::OwnerId,
71-
bodies: &SortedMap<hir::ItemLocalId, &hir::Body<'_>>,
72-
f: impl FnOnce(&mut StableHashingContext<'_>),
73-
) {
74-
f(&mut StableHashingContext {
75-
body_resolver: BodyResolver::Traverse { owner, bodies },
76-
..self.clone()
77-
});
78-
}
79-
8061
#[inline]
8162
pub fn while_hashing_spans<F: FnOnce(&mut Self)>(&mut self, hash_spans: bool, f: F) {
8263
let prev_hash_spans = self.hashing_controls.hash_spans;

compiler/rustc_query_system/src/ich/impls_hir.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,11 @@ use rustc_hir as hir;
88

99
impl<'ctx> rustc_hir::HashStableContext for StableHashingContext<'ctx> {
1010
#[inline]
11-
fn hash_body_id(&mut self, id: hir::BodyId, hasher: &mut StableHasher) {
11+
fn hash_body_id(&mut self, hir::BodyId { hir_id }: hir::BodyId, hasher: &mut StableHasher) {
1212
let hcx = self;
1313
match hcx.body_resolver {
1414
BodyResolver::Forbidden => panic!("Hashing HIR bodies is forbidden."),
15-
BodyResolver::Ignore => {}
16-
BodyResolver::Traverse { owner, bodies } => {
17-
assert_eq!(id.hir_id.owner, owner);
18-
bodies[&id.hir_id.local_id].hash_stable(hcx, hasher);
19-
}
15+
BodyResolver::Ignore => hir_id.hash_stable(hcx, hasher),
2016
}
2117
}
2218
}

0 commit comments

Comments
 (0)