From f8cb67c2491a3266acdba0ace21f7768e451832b Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Sat, 20 Jan 2024 00:34:01 +0100 Subject: [PATCH 1/2] hashmap experiment --- compiler/rustc_infer/src/infer/freshen.rs | 50 ++++++++++++----------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs index d256994d8d1fd..95d67a57c671d 100644 --- a/compiler/rustc_infer/src/infer/freshen.rs +++ b/compiler/rustc_infer/src/infer/freshen.rs @@ -31,18 +31,18 @@ //! variable only once, and it does so as soon as it can, so it is reasonable to ask what the type //! inferencer knows "so far". use super::InferCtxt; -use rustc_data_structures::fx::FxHashMap; use rustc_middle::infer::unify_key::ToType; use rustc_middle::ty::fold::TypeFolder; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeVisitableExt}; -use std::collections::hash_map::Entry; pub struct TypeFreshener<'a, 'tcx> { infcx: &'a InferCtxt<'tcx>, ty_freshen_count: u32, const_freshen_count: u32, - ty_freshen_map: FxHashMap>, - const_freshen_map: FxHashMap>, + ty_freshen_key_vec: Vec, + ty_freshen_value_vec: Vec>, + const_freshen_key_vec: Vec, + const_freshen_value_vec: Vec>, } impl<'a, 'tcx> TypeFreshener<'a, 'tcx> { @@ -51,8 +51,10 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> { infcx, ty_freshen_count: 0, const_freshen_count: 0, - ty_freshen_map: Default::default(), - const_freshen_map: Default::default(), + ty_freshen_key_vec: Vec::new(), + ty_freshen_value_vec: Vec::new(), + const_freshen_key_vec: Vec::new(), + const_freshen_value_vec: Vec::new(), } } @@ -64,15 +66,15 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> { return ty.fold_with(self); } - match self.ty_freshen_map.entry(key) { - Entry::Occupied(entry) => *entry.get(), - Entry::Vacant(entry) => { - let index = self.ty_freshen_count; - self.ty_freshen_count += 1; - let t = mk_fresh(index); - entry.insert(t); - t - } + if let Some(idx) = self.ty_freshen_key_vec.iter().position(|infty| *infty == key) { + unsafe { *self.ty_freshen_value_vec.get_unchecked(idx) } + } else { + let index = self.ty_freshen_count; + self.ty_freshen_count += 1; + let t = mk_fresh(index); + self.ty_freshen_key_vec.push(key); + self.ty_freshen_value_vec.push(t); + t } } @@ -90,15 +92,15 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> { return ct.fold_with(self); } - match self.const_freshen_map.entry(key) { - Entry::Occupied(entry) => *entry.get(), - Entry::Vacant(entry) => { - let index = self.const_freshen_count; - self.const_freshen_count += 1; - let ct = ty::Const::new_infer(self.infcx.tcx, freshener(index), ty); - entry.insert(ct); - ct - } + if let Some(idx) = self.const_freshen_key_vec.iter().position(|infty| *infty == key) { + unsafe { *self.const_freshen_value_vec.get_unchecked(idx) } + } else { + let index: u32 = self.const_freshen_count; + self.const_freshen_count += 1; + let ct = ty::Const::new_infer(self.infcx.tcx, freshener(index), ty); + self.const_freshen_key_vec.push(key); + self.const_freshen_value_vec.push(ct); + ct } } } From 7836b3b939feca8ddf241024c9b27e0a76703f9e Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Sat, 20 Jan 2024 11:36:03 +0100 Subject: [PATCH 2/2] try ahash for interners --- Cargo.lock | 14 +++--- compiler/rustc_data_structures/Cargo.toml | 1 + compiler/rustc_data_structures/src/sharded.rs | 7 ++- compiler/rustc_infer/src/infer/freshen.rs | 50 +++++++++---------- 4 files changed, 36 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f5ce875ccd428..8efbb50debbe2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -37,11 +37,12 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" dependencies = [ "cfg-if", + "getrandom", "once_cell", "version_check", "zerocopy", @@ -3663,6 +3664,7 @@ dependencies = [ name = "rustc_data_structures" version = "0.0.0" dependencies = [ + "ahash", "arrayvec", "bitflags 2.4.1", "elsa", @@ -6373,18 +6375,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.28" +version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d6f15f7ade05d2a4935e34a457b936c23dc70a05cc1d97133dc99e7a3fe0f0e" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.28" +version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbbad221e3f78500350ecbd7dfa4e63ef945c05f4c61cb7f4d3f84cd0bba649b" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index 9d598c32e6fc4..a4557df35b821 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -4,6 +4,7 @@ version = "0.0.0" edition = "2021" [dependencies] +ahash = "0.8.7" # tidy-alphabetical-start arrayvec = { version = "0.7", default-features = false } bitflags = "2.4.1" diff --git a/compiler/rustc_data_structures/src/sharded.rs b/compiler/rustc_data_structures/src/sharded.rs index 162dbd234d676..036d297dc7914 100644 --- a/compiler/rustc_data_structures/src/sharded.rs +++ b/compiler/rustc_data_structures/src/sharded.rs @@ -1,4 +1,3 @@ -use crate::fx::{FxHashMap, FxHasher}; #[cfg(parallel_compiler)] use crate::sync::{is_dyn_thread_safe, CacheAligned}; use crate::sync::{Lock, LockGuard, Mode}; @@ -6,7 +5,7 @@ use crate::sync::{Lock, LockGuard, Mode}; use itertools::Either; use std::borrow::Borrow; use std::collections::hash_map::RawEntryMut; -use std::hash::{Hash, Hasher}; +use std::hash::{Hash, Hasher, BuildHasherDefault}; use std::iter; use std::mem; @@ -158,7 +157,7 @@ pub fn shards() -> usize { 1 } -pub type ShardedHashMap = Sharded>; +pub type ShardedHashMap = Sharded>>; impl ShardedHashMap { pub fn len(&self) -> usize { @@ -224,7 +223,7 @@ impl ShardedHashMap { #[inline] pub fn make_hash(val: &K) -> u64 { - let mut state = FxHasher::default(); + let mut state = ahash::AHasher::default(); val.hash(&mut state); state.finish() } diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs index 95d67a57c671d..d256994d8d1fd 100644 --- a/compiler/rustc_infer/src/infer/freshen.rs +++ b/compiler/rustc_infer/src/infer/freshen.rs @@ -31,18 +31,18 @@ //! variable only once, and it does so as soon as it can, so it is reasonable to ask what the type //! inferencer knows "so far". use super::InferCtxt; +use rustc_data_structures::fx::FxHashMap; use rustc_middle::infer::unify_key::ToType; use rustc_middle::ty::fold::TypeFolder; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeVisitableExt}; +use std::collections::hash_map::Entry; pub struct TypeFreshener<'a, 'tcx> { infcx: &'a InferCtxt<'tcx>, ty_freshen_count: u32, const_freshen_count: u32, - ty_freshen_key_vec: Vec, - ty_freshen_value_vec: Vec>, - const_freshen_key_vec: Vec, - const_freshen_value_vec: Vec>, + ty_freshen_map: FxHashMap>, + const_freshen_map: FxHashMap>, } impl<'a, 'tcx> TypeFreshener<'a, 'tcx> { @@ -51,10 +51,8 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> { infcx, ty_freshen_count: 0, const_freshen_count: 0, - ty_freshen_key_vec: Vec::new(), - ty_freshen_value_vec: Vec::new(), - const_freshen_key_vec: Vec::new(), - const_freshen_value_vec: Vec::new(), + ty_freshen_map: Default::default(), + const_freshen_map: Default::default(), } } @@ -66,15 +64,15 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> { return ty.fold_with(self); } - if let Some(idx) = self.ty_freshen_key_vec.iter().position(|infty| *infty == key) { - unsafe { *self.ty_freshen_value_vec.get_unchecked(idx) } - } else { - let index = self.ty_freshen_count; - self.ty_freshen_count += 1; - let t = mk_fresh(index); - self.ty_freshen_key_vec.push(key); - self.ty_freshen_value_vec.push(t); - t + match self.ty_freshen_map.entry(key) { + Entry::Occupied(entry) => *entry.get(), + Entry::Vacant(entry) => { + let index = self.ty_freshen_count; + self.ty_freshen_count += 1; + let t = mk_fresh(index); + entry.insert(t); + t + } } } @@ -92,15 +90,15 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> { return ct.fold_with(self); } - if let Some(idx) = self.const_freshen_key_vec.iter().position(|infty| *infty == key) { - unsafe { *self.const_freshen_value_vec.get_unchecked(idx) } - } else { - let index: u32 = self.const_freshen_count; - self.const_freshen_count += 1; - let ct = ty::Const::new_infer(self.infcx.tcx, freshener(index), ty); - self.const_freshen_key_vec.push(key); - self.const_freshen_value_vec.push(ct); - ct + match self.const_freshen_map.entry(key) { + Entry::Occupied(entry) => *entry.get(), + Entry::Vacant(entry) => { + let index = self.const_freshen_count; + self.const_freshen_count += 1; + let ct = ty::Const::new_infer(self.infcx.tcx, freshener(index), ty); + entry.insert(ct); + ct + } } } }