Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[perf] Use Blake2 for the type-id hash #128597

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,15 @@ version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"

[[package]]
name = "blake2"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe"
dependencies = [
"digest",
]

[[package]]
name = "block-buffer"
version = "0.10.4"
Expand Down Expand Up @@ -1017,6 +1026,7 @@ checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
"subtle",
]

[[package]]
Expand Down Expand Up @@ -3227,8 +3237,10 @@ checksum = "5be1bdc7edf596692617627bbfeaba522131b18e06ca4df2b6b689e3c5d5ce84"
[[package]]
name = "rustc-stable-hash"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5c9f15eec8235d7cb775ee6f81891db79b98fd54ba1ad8fae565b88ef1ae4e2"
source = "git+https://github.com/Urgau/rustc-stable-hash.git?rev=543696a#543696a0b6299c4cc8a8c9c30651e5cc0056655a"
dependencies = [
"blake2",
]

[[package]]
name = "rustc_abi"
Expand Down Expand Up @@ -5067,6 +5079,12 @@ dependencies = [
"syn 1.0.109",
]

[[package]]
name = "subtle"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"

[[package]]
name = "suggest-tests"
version = "0.1.0"
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use std::{cmp, fmt, mem};

pub use rustc_ast_ir::{Movability, Mutability};
use rustc_data_structures::packed::Pu128;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::stable_hasher::{ExtendedHasher, GenericStableHasher, HashStable};
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_data_structures::sync::Lrc;
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
Expand Down Expand Up @@ -105,7 +105,7 @@ impl PartialEq<Symbol> for Path {
}

impl<CTX: rustc_span::HashStableContext> HashStable<CTX> for Path {
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
fn hash_stable<H: ExtendedHasher>(&self, hcx: &mut CTX, hasher: &mut GenericStableHasher<H>) {
self.segments.len().hash_stable(hcx, hasher);
for segment in &self.segments {
segment.ident.hash_stable(hcx, hasher);
Expand Down Expand Up @@ -1723,7 +1723,7 @@ impl<CTX> HashStable<CTX> for AttrArgs
where
CTX: crate::HashStableContext,
{
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
fn hash_stable<H: ExtendedHasher>(&self, ctx: &mut CTX, hasher: &mut GenericStableHasher<H>) {
mem::discriminant(self).hash_stable(ctx, hasher);
match self {
AttrArgs::Empty => {}
Expand Down Expand Up @@ -1759,7 +1759,7 @@ impl<CTX> HashStable<CTX> for DelimArgs
where
CTX: crate::HashStableContext,
{
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
fn hash_stable<H: ExtendedHasher>(&self, ctx: &mut CTX, hasher: &mut GenericStableHasher<H>) {
let DelimArgs { dspan, delim, tokens } = self;
dspan.hash_stable(ctx, hasher);
delim.hash_stable(ctx, hasher);
Expand Down
14 changes: 11 additions & 3 deletions compiler/rustc_ast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub mod token;
pub mod tokenstream;
pub mod visit;

use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::stable_hasher::{ExtendedHasher, GenericStableHasher, HashStable};

pub use self::ast::*;
pub use self::ast_traits::{AstDeref, AstNodeWrapper, HasAttrs, HasNodeId, HasTokens};
Expand All @@ -52,11 +52,19 @@ pub use self::ast_traits::{AstDeref, AstNodeWrapper, HasAttrs, HasNodeId, HasTok
/// This is a hack to allow using the `HashStable_Generic` derive macro
/// instead of implementing everything in `rustc_middle`.
pub trait HashStableContext: rustc_span::HashStableContext {
fn hash_attr(&mut self, _: &ast::Attribute, hasher: &mut StableHasher);
fn hash_attr<H: ExtendedHasher>(
&mut self,
_: &ast::Attribute,
hasher: &mut GenericStableHasher<H>,
);
}

impl<AstCtx: crate::HashStableContext> HashStable<AstCtx> for ast::Attribute {
fn hash_stable(&self, hcx: &mut AstCtx, hasher: &mut StableHasher) {
fn hash_stable<H: ExtendedHasher>(
&self,
hcx: &mut AstCtx,
hasher: &mut GenericStableHasher<H>,
) {
hcx.hash_attr(self, hasher)
}
}
4 changes: 2 additions & 2 deletions compiler/rustc_ast/src/ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use std::fmt::{self, Debug, Display};
use std::ops::{Deref, DerefMut};
use std::{slice, vec};

use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::stable_hasher::{ExtendedHasher, GenericStableHasher, HashStable};
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
/// An owned smart pointer.
///
Expand Down Expand Up @@ -203,7 +203,7 @@ impl<CTX, T> HashStable<CTX> for P<T>
where
T: ?Sized + HashStable<CTX>,
{
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
fn hash_stable<H: ExtendedHasher>(&self, hcx: &mut CTX, hasher: &mut GenericStableHasher<H>) {
(**self).hash_stable(hcx, hasher);
}
}
4 changes: 2 additions & 2 deletions compiler/rustc_ast/src/token.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::borrow::Cow;
use std::fmt;

use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::stable_hasher::{ExtendedHasher, GenericStableHasher, HashStable};
use rustc_data_structures::sync::Lrc;
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
use rustc_span::edition::Edition;
Expand Down Expand Up @@ -1055,7 +1055,7 @@ impl<CTX> HashStable<CTX> for Nonterminal
where
CTX: crate::HashStableContext,
{
fn hash_stable(&self, _hcx: &mut CTX, _hasher: &mut StableHasher) {
fn hash_stable<H: ExtendedHasher>(&self, _hcx: &mut CTX, _hasher: &mut GenericStableHasher<H>) {
panic!("interpolated tokens should not be present in the HIR")
}
}
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_ast/src/tokenstream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
use std::borrow::Cow;
use std::{cmp, fmt, iter};

use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::stable_hasher::{ExtendedHasher, GenericStableHasher, HashStable};
use rustc_data_structures::sync::{self, Lrc};
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
use rustc_serialize::{Decodable, Encodable};
Expand Down Expand Up @@ -99,7 +99,7 @@ impl<CTX> HashStable<CTX> for TokenStream
where
CTX: crate::HashStableContext,
{
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
fn hash_stable<H: ExtendedHasher>(&self, hcx: &mut CTX, hasher: &mut GenericStableHasher<H>) {
for sub_tt in self.trees() {
sub_tt.hash_stable(hcx, hasher);
}
Expand Down Expand Up @@ -151,7 +151,7 @@ impl<D: SpanDecoder> Decodable<D> for LazyAttrTokenStream {
}

impl<CTX> HashStable<CTX> for LazyAttrTokenStream {
fn hash_stable(&self, _hcx: &mut CTX, _hasher: &mut StableHasher) {
fn hash_stable<H: ExtendedHasher>(&self, _hcx: &mut CTX, _hasher: &mut GenericStableHasher<H>) {
panic!("Attempted to compute stable hash for LazyAttrTokenStream");
}
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_cranelift/src/driver/aot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use rustc_codegen_ssa::{
errors as ssa_errors, CodegenResults, CompiledModule, CrateInfo, ModuleKind,
};
use rustc_data_structures::profiling::SelfProfilerRef;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::stable_hasher::{ExtendedHasher, GenericStableHasher, HashStable};
use rustc_data_structures::sync::{par_map, IntoDynSyncSend};
use rustc_metadata::fs::copy_to_stdout;
use rustc_metadata::EncodedMetadata;
Expand Down Expand Up @@ -43,7 +43,7 @@ enum OngoingModuleCodegen {
}

impl<HCX> HashStable<HCX> for OngoingModuleCodegen {
fn hash_stable(&self, _: &mut HCX, _: &mut StableHasher) {
fn hash_stable<H: ExtendedHasher>(&self, _: &mut HCX, _: &mut GenericStableHasher<H>) {
// do nothing
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::cell::RefCell;

use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::stable_hasher::{HashStable, StableBlake2sHasher256};
use rustc_macros::HashStable;
use rustc_middle::bug;
use rustc_middle::ty::{ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt};
Expand Down Expand Up @@ -94,7 +94,7 @@ impl<'tcx> UniqueTypeId<'tcx> {
///
/// Right now this takes the form of a hex-encoded opaque hash value.
pub fn generate_unique_id_string(self, tcx: TyCtxt<'tcx>) -> String {
let mut hasher = StableHasher::new();
let mut hasher = StableBlake2sHasher256::new();
tcx.with_stable_hashing_context(|mut hcx| {
hcx.while_hashing_spans(false, |hcx| self.hash_stable(hcx, &mut hasher))
});
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_ssa/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,12 @@ pub enum TypeKind {
// for now we content ourselves with providing a no-op HashStable
// implementation for CGUs.
mod temp_stable_hash_impls {
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::stable_hasher::{ExtendedHasher, GenericStableHasher, HashStable};

use crate::ModuleCodegen;

impl<HCX, M> HashStable<HCX> for ModuleCodegen<M> {
fn hash_stable(&self, _: &mut HCX, _: &mut StableHasher) {
fn hash_stable<H: ExtendedHasher>(&self, _: &mut HCX, _: &mut GenericStableHasher<H>) {
// do nothing
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_data_structures/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobserver_crate = { version = "0.1.28", package = "jobserver" }
measureme = "11"
rustc-hash = "1.1.0"
rustc-rayon = { version = "0.5.0", optional = true }
rustc-stable-hash = { version = "0.1.0", features = ["nightly"] }
rustc-stable-hash = { git = "https://github.com/Urgau/rustc-stable-hash.git", rev = "543696a", features = ["nightly"] }
rustc_arena = { path = "../rustc_arena" }
rustc_graphviz = { path = "../rustc_graphviz" }
rustc_index = { path = "../rustc_index", package = "rustc_index" }
Expand Down
21 changes: 17 additions & 4 deletions compiler/rustc_data_structures/src/fingerprint.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::hash::{Hash, Hasher};

use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use rustc_stable_hash::hashers::Blake2s256Hash;

use crate::stable_hasher::{
impl_stable_traits_for_trivial_type, FromStableHash, Hash64, StableHasherHash,
Expand Down Expand Up @@ -157,15 +158,27 @@ impl FingerprintHasher for crate::unhash::Unhasher {
}
}

impl FromStableHash for Fingerprint {
type Hash = StableHasherHash;

impl FromStableHash<StableHasherHash> for Fingerprint {
#[inline]
fn from(StableHasherHash([_0, _1]): Self::Hash) -> Self {
fn from(StableHasherHash([_0, _1]): StableHasherHash) -> Self {
Fingerprint(_0, _1)
}
}

impl FromStableHash<Blake2s256Hash> for Fingerprint {
#[inline]
fn from(Blake2s256Hash(bytes): Blake2s256Hash) -> Self {
let p0 = u64::from_le_bytes(bytes[0..8].try_into().unwrap());
let p1 = u64::from_le_bytes(bytes[8..16].try_into().unwrap());
let p2 = u64::from_le_bytes(bytes[16..24].try_into().unwrap());
let p3 = u64::from_le_bytes(bytes[24..32].try_into().unwrap());

// See https://stackoverflow.com/a/27952689 on why this function is
// implemented this way.
Fingerprint(p0.wrapping_mul(3).wrapping_add(p1), p2.wrapping_mul(3).wrapping_add(p3))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am pretty sure you can just use Fingerprint(p0, p1). Blake2s is proven to be indistinguishable from a random function according to https://eprint.iacr.org/2016/827. If a prefix of the hash was biased, it wouldn't be indistinguishable from a random function. Because of the lack of bias on the low bytes, there is no need to mix in the high bytes.

}
}

impl_stable_traits_for_trivial_type!(Fingerprint);

impl<E: Encoder> Encodable<E> for Fingerprint {
Expand Down
25 changes: 17 additions & 8 deletions compiler/rustc_data_structures/src/hashes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use std::fmt;
use std::ops::BitXorAssign;

use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use rustc_stable_hash::hashers::Blake2s256Hash;

use crate::stable_hasher::{FromStableHash, StableHasherHash};

Expand Down Expand Up @@ -58,11 +59,9 @@ impl<D: Decoder> Decodable<D> for Hash64 {
}
}

impl FromStableHash for Hash64 {
type Hash = StableHasherHash;

impl FromStableHash<StableHasherHash> for Hash64 {
#[inline]
fn from(StableHasherHash([_0, __1]): Self::Hash) -> Self {
fn from(StableHasherHash([_0, __1]): StableHasherHash) -> Self {
Self { inner: _0 }
}
}
Expand Down Expand Up @@ -125,15 +124,25 @@ impl<D: Decoder> Decodable<D> for Hash128 {
}
}

impl FromStableHash for Hash128 {
type Hash = StableHasherHash;

impl FromStableHash<StableHasherHash> for Hash128 {
#[inline]
fn from(StableHasherHash([_0, _1]): Self::Hash) -> Self {
fn from(StableHasherHash([_0, _1]): StableHasherHash) -> Self {
Self { inner: u128::from(_0) | (u128::from(_1) << 64) }
}
}

impl FromStableHash<Blake2s256Hash> for Hash128 {
#[inline]
fn from(Blake2s256Hash(bytes): Blake2s256Hash) -> Self {
let p0 = u128::from_le_bytes(bytes[0..16].try_into().unwrap());
let p1 = u128::from_le_bytes(bytes[16..32].try_into().unwrap());

// See https://stackoverflow.com/a/27952689 on why this function is
// implemented this way.
Self { inner: p0.wrapping_mul(3).wrapping_add(p1) }
}
}

impl fmt::Debug for Hash128 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.inner.fmt(f)
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_data_structures/src/intern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::hash::{Hash, Hasher};
use std::ops::Deref;
use std::ptr;

use crate::stable_hasher::{HashStable, StableHasher};
use crate::stable_hasher::{ExtendedHasher, GenericStableHasher, HashStable};

mod private {
#[derive(Clone, Copy, Debug)]
Expand Down Expand Up @@ -104,7 +104,7 @@ impl<T, CTX> HashStable<CTX> for Interned<'_, T>
where
T: HashStable<CTX>,
{
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
fn hash_stable<H: ExtendedHasher>(&self, hcx: &mut CTX, hasher: &mut GenericStableHasher<H>) {
self.0.hash_stable(hcx, hasher);
}
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_data_structures/src/packed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::fmt;

use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};

use crate::stable_hasher::{HashStable, StableHasher};
use crate::stable_hasher::{ExtendedHasher, GenericStableHasher, HashStable};

/// A packed 128-bit integer. Useful for reducing the size of structures in
/// some cases.
Expand Down Expand Up @@ -55,7 +55,7 @@ impl fmt::UpperHex for Pu128 {

impl<CTX> HashStable<CTX> for Pu128 {
#[inline]
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
fn hash_stable<H: ExtendedHasher>(&self, ctx: &mut CTX, hasher: &mut GenericStableHasher<H>) {
{ self.0 }.hash_stable(ctx, hasher)
}
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_data_structures/src/sorted_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::ops::{Bound, Index, IndexMut, RangeBounds};

use rustc_macros::{Decodable_Generic, Encodable_Generic};

use crate::stable_hasher::{HashStable, StableHasher, StableOrd};
use crate::stable_hasher::{ExtendedHasher, GenericStableHasher, HashStable, StableOrd};

mod index_map;

Expand Down Expand Up @@ -311,7 +311,7 @@ impl<K: Ord, V> FromIterator<(K, V)> for SortedMap<K, V> {

impl<K: HashStable<CTX> + StableOrd, V: HashStable<CTX>, CTX> HashStable<CTX> for SortedMap<K, V> {
#[inline]
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
fn hash_stable<H: ExtendedHasher>(&self, ctx: &mut CTX, hasher: &mut GenericStableHasher<H>) {
self.data.hash_stable(ctx, hasher);
}
}
Expand Down
Loading
Loading