1
Fork 0

Only compute the crate hash when necessary.

The crate hash is needed:
- if debug assertions are enabled, or
- if incr. comp. is enabled, or
- if metadata is being generated, or
- if `-C instrumentation-coverage` is enabled.

This commit avoids computing the crate hash when these conditions are
all false, such as when doing a release build of a binary crate.

It uses `Option` to store the hashes when needed, rather than
computing them on demand, because some of them are needed in multiple
places and computing them on demand would make compilation slower.

The commit also removes `Owner::hash_without_bodies`. There is no
benefit to pre-computing that one, it can just be done in the normal
fashion.
This commit is contained in:
Nicholas Nethercote 2023-03-03 17:02:11 +11:00
parent 816f958ac3
commit 9570023ce1
10 changed files with 100 additions and 82 deletions

View file

@ -815,12 +815,13 @@ pub struct ParentedNode<'tcx> {
#[derive(Debug)]
pub struct AttributeMap<'tcx> {
pub map: SortedMap<ItemLocalId, &'tcx [Attribute]>,
pub hash: Fingerprint,
// Only present when the crate hash is needed.
pub opt_hash: Option<Fingerprint>,
}
impl<'tcx> AttributeMap<'tcx> {
pub const EMPTY: &'static AttributeMap<'static> =
&AttributeMap { map: SortedMap::new(), hash: Fingerprint::ZERO };
&AttributeMap { map: SortedMap::new(), opt_hash: Some(Fingerprint::ZERO) };
#[inline]
pub fn get(&self, id: ItemLocalId) -> &'tcx [Attribute] {
@ -832,10 +833,9 @@ impl<'tcx> AttributeMap<'tcx> {
/// These nodes are mapped by `ItemLocalId` alongside the index of their parent node.
/// The HIR tree, including bodies, is pre-hashed.
pub struct OwnerNodes<'tcx> {
/// Pre-computed hash of the full HIR.
pub hash_including_bodies: Fingerprint,
/// Pre-computed hash of the item signature, without recursing into the body.
pub hash_without_bodies: Fingerprint,
/// Pre-computed hash of the full HIR. Used in the crate hash. Only present
/// when incr. comp. is enabled.
pub opt_hash_including_bodies: Option<Fingerprint>,
/// Full HIR for the current owner.
// The zeroth node's parent should never be accessed: the owner's parent is computed by the
// hir_owner_parent query. It is set to `ItemLocalId::INVALID` to force an ICE if accidentally
@ -872,8 +872,7 @@ impl fmt::Debug for OwnerNodes<'_> {
.collect::<Vec<_>>(),
)
.field("bodies", &self.bodies)
.field("hash_without_bodies", &self.hash_without_bodies)
.field("hash_including_bodies", &self.hash_including_bodies)
.field("opt_hash_including_bodies", &self.opt_hash_including_bodies)
.finish()
}
}
@ -940,7 +939,8 @@ impl<T> MaybeOwner<T> {
#[derive(Debug)]
pub struct Crate<'hir> {
pub owners: IndexVec<LocalDefId, MaybeOwner<&'hir OwnerInfo<'hir>>>,
pub hir_hash: Fingerprint,
// Only present when incr. comp. is enabled.
pub opt_hir_hash: Option<Fingerprint>,
}
#[derive(Debug, HashStable_Generic)]

View file

@ -100,24 +100,23 @@ impl<'tcx, HirCtx: crate::HashStableContext> HashStable<HirCtx> for OwnerNodes<'
// `local_id_to_def_id` is also ignored because is dependent on the body, then just hashing
// the body satisfies the condition of two nodes being different have different
// `hash_stable` results.
let OwnerNodes { hash_including_bodies, hash_without_bodies: _, nodes: _, bodies: _ } =
*self;
hash_including_bodies.hash_stable(hcx, hasher);
let OwnerNodes { opt_hash_including_bodies, nodes: _, bodies: _ } = *self;
opt_hash_including_bodies.unwrap().hash_stable(hcx, hasher);
}
}
impl<'tcx, HirCtx: crate::HashStableContext> HashStable<HirCtx> for AttributeMap<'tcx> {
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
// We ignore the `map` since it refers to information included in `hash` which is hashed in
// the collector and used for the crate hash.
let AttributeMap { hash, map: _ } = *self;
hash.hash_stable(hcx, hasher);
// We ignore the `map` since it refers to information included in `opt_hash` which is
// hashed in the collector and used for the crate hash.
let AttributeMap { opt_hash, map: _ } = *self;
opt_hash.unwrap().hash_stable(hcx, hasher);
}
}
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for Crate<'_> {
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
let Crate { owners: _, hir_hash } = self;
hir_hash.hash_stable(hcx, hasher)
let Crate { owners: _, opt_hir_hash } = self;
opt_hir_hash.unwrap().hash_stable(hcx, hasher)
}
}