Skip to content

Commit

Permalink
Auto merge of #82183 - michaelwoerister:lazier-defpathhash-loading2, …
Browse files Browse the repository at this point in the history
…r=wesleywiser

Simplify lazy DefPathHash decoding by using an on-disk hash table.

This PR simplifies the logic around mapping `DefPathHash` values encountered during incremental compilation to valid `DefId`s in the current session. It is able to do so by using an on-disk hash table encoding that allows for looking up values directly, i.e. without deserializing the entire table.

The main simplification comes from not having to keep track of `DefPathHashes` being used during the compilation session.
  • Loading branch information
bors committed Sep 18, 2021
2 parents 23afad6 + 4d151d9 commit d6cd2c6
Show file tree
Hide file tree
Showing 22 changed files with 279 additions and 350 deletions.
11 changes: 11 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2321,6 +2321,15 @@ dependencies = [
"rustc-std-workspace-core",
]

[[package]]
name = "odht"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b18a8d1c919d3e7b5c49708d08ef7d60bc2150a7c3a8244257c54ca3f625010"
dependencies = [
"cfg-if 1.0.0",
]

[[package]]
name = "once_cell"
version = "1.7.2"
Expand Down Expand Up @@ -3859,6 +3868,7 @@ version = "0.0.0"
name = "rustc_hir"
version = "0.0.0"
dependencies = [
"odht",
"rustc_ast",
"rustc_data_structures",
"rustc_feature",
Expand Down Expand Up @@ -4045,6 +4055,7 @@ name = "rustc_metadata"
version = "0.0.0"
dependencies = [
"libc",
"odht",
"rustc_ast",
"rustc_attr",
"rustc_data_structures",
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ rustc_serialize = { path = "../rustc_serialize" }
rustc_ast = { path = "../rustc_ast" }
tracing = "0.1"
smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
odht = { version = "0.2.1", features = ["nightly"] }
37 changes: 37 additions & 0 deletions compiler/rustc_hir/src/def_path_hash_map.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_span::def_id::{DefIndex, DefPathHash};

#[derive(Clone, Default)]
pub struct Config;

impl odht::Config for Config {
type Key = DefPathHash;
type Value = DefIndex;

type EncodedKey = [u8; 16];
type EncodedValue = [u8; 4];

type H = odht::UnHashFn;

#[inline]
fn encode_key(k: &DefPathHash) -> [u8; 16] {
k.0.to_le_bytes()
}

#[inline]
fn encode_value(v: &DefIndex) -> [u8; 4] {
v.as_u32().to_le_bytes()
}

#[inline]
fn decode_key(k: &[u8; 16]) -> DefPathHash {
DefPathHash(Fingerprint::from_le_bytes(*k))
}

#[inline]
fn decode_value(v: &[u8; 4]) -> DefIndex {
DefIndex::from_u32(u32::from_le_bytes(*v))
}
}

pub type DefPathHashMap = odht::HashTableOwned<Config>;
22 changes: 16 additions & 6 deletions compiler/rustc_hir/src/definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@

pub use crate::def_id::DefPathHash;
use crate::def_id::{CrateNum, DefIndex, LocalDefId, StableCrateId, CRATE_DEF_INDEX, LOCAL_CRATE};
use crate::def_path_hash_map::DefPathHashMap;
use crate::hir;

use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::StableHasher;
use rustc_data_structures::unhash::UnhashMap;
use rustc_index::vec::IndexVec;
use rustc_span::hygiene::ExpnId;
use rustc_span::symbol::{kw, sym, Symbol};
Expand All @@ -28,7 +28,7 @@ use tracing::debug;
pub struct DefPathTable {
index_to_key: IndexVec<DefIndex, DefKey>,
def_path_hashes: IndexVec<DefIndex, DefPathHash>,
def_path_hash_to_index: UnhashMap<DefPathHash, DefIndex>,
def_path_hash_to_index: DefPathHashMap,
}

impl DefPathTable {
Expand All @@ -44,7 +44,7 @@ impl DefPathTable {

// Check for hash collisions of DefPathHashes. These should be
// exceedingly rare.
if let Some(existing) = self.def_path_hash_to_index.insert(def_path_hash, index) {
if let Some(existing) = self.def_path_hash_to_index.insert(&def_path_hash, &index) {
let def_path1 = DefPath::make(LOCAL_CRATE, existing, |idx| self.def_key(idx));
let def_path2 = DefPath::make(LOCAL_CRATE, index, |idx| self.def_key(idx));

Expand Down Expand Up @@ -87,7 +87,7 @@ impl DefPathTable {

pub fn enumerated_keys_and_path_hashes(
&self,
) -> impl Iterator<Item = (DefIndex, &DefKey, &DefPathHash)> + '_ {
) -> impl Iterator<Item = (DefIndex, &DefKey, &DefPathHash)> + ExactSizeIterator + '_ {
self.index_to_key
.iter_enumerated()
.map(move |(index, key)| (index, key, &self.def_path_hashes[index]))
Expand All @@ -110,6 +110,9 @@ pub struct Definitions {
expansions_that_defined: FxHashMap<LocalDefId, ExpnId>,

def_id_to_span: IndexVec<LocalDefId, Span>,

/// The [StableCrateId] of the local crate.
stable_crate_id: StableCrateId,
}

/// A unique identifier that we can use to lookup a definition
Expand Down Expand Up @@ -356,6 +359,7 @@ impl Definitions {
hir_id_to_def_id: Default::default(),
expansions_that_defined: Default::default(),
def_id_to_span,
stable_crate_id,
}
}

Expand Down Expand Up @@ -439,11 +443,17 @@ impl Definitions {
}

#[inline(always)]
pub fn local_def_path_hash_to_def_id(&self, hash: DefPathHash) -> Option<LocalDefId> {
pub fn local_def_path_hash_to_def_id(&self, hash: DefPathHash) -> LocalDefId {
debug_assert!(hash.stable_crate_id() == self.stable_crate_id);
self.table
.def_path_hash_to_index
.get(&hash)
.map(|&local_def_index| LocalDefId { local_def_index })
.map(|local_def_index| LocalDefId { local_def_index })
.unwrap()
}

pub fn def_path_hash_to_def_index_map(&self) -> &DefPathHashMap {
&self.table.def_path_hash_to_index
}
}

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ extern crate rustc_data_structures;

mod arena;
pub mod def;
pub mod def_path_hash_map;
pub mod definitions;
pub use rustc_span::def_id;
mod hir;
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_metadata/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ doctest = false

[dependencies]
libc = "0.2"
odht = { version = "0.2.1", features = ["nightly"] }
snap = "1"
tracing = "0.1"
smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_metadata/src/creader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pub struct CStore {

/// This map is used to verify we get no hash conflicts between
/// `StableCrateId` values.
stable_crate_ids: FxHashMap<StableCrateId, CrateNum>,
pub(crate) stable_crate_ids: FxHashMap<StableCrateId, CrateNum>,

/// Unused externs of the crate
unused_externs: Vec<Symbol>,
Expand Down
Loading

0 comments on commit d6cd2c6

Please sign in to comment.