Skip to content

Some preparatory refactorings for hash-based DepNodes #42504

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

Merged
merged 4 commits into from
Jun 9, 2017
Merged
Show file tree
Hide file tree
Changes from 3 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
17 changes: 14 additions & 3 deletions src/librustc/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
// except according to those terms.

use hir::def_id::CrateNum;
use ich::Fingerprint;
use rustc_data_structures::stable_hasher::StableHasher;
use std::fmt::Debug;
use std::sync::Arc;
use std::hash::Hash;

macro_rules! try_opt {
($e:expr) => (
Expand Down Expand Up @@ -56,7 +58,7 @@ pub enum DepNode<D: Clone + Debug> {

/// Represents some artifact that we save to disk. Note that these
/// do not have a def-id as part of their identifier.
WorkProduct(Arc<WorkProductId>),
WorkProduct(WorkProductId),
Copy link
Contributor

Choose a reason for hiding this comment

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

does this make DepNode be Copy? That would be great!

Copy link
Contributor

Choose a reason for hiding this comment

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

(What is Fingerprint anyway?)

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, DepNode will be Copy.
A Fingerprint is a hash value with a "virtual uniqueness" property, i.e. there will be collisions (like with any hash) but the probability is so low that it doesn't matter. Because of this property, a Fingerprint can be used as an identifier. In terms of rustc I now use the type Fingerprint for anything that fulfills this property but sometimes I like to introduce newtypes for it, for example DefPathHash.


// Represents different phases in the compiler.
RegionMaps(D),
Expand Down Expand Up @@ -318,7 +320,16 @@ impl<D: Clone + Debug> DepNode<D> {
/// the need to be mapped or unmapped. (This ensures we can serialize
/// them even in the absence of a tcx.)
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
pub struct WorkProductId(pub String);
pub struct WorkProductId(pub Fingerprint);

impl WorkProductId {
pub fn from_cgu_name(cgu_name: &str) -> WorkProductId {
let mut hasher = StableHasher::new();
cgu_name.len().hash(&mut hasher);
cgu_name.hash(&mut hasher);
WorkProductId(hasher.finish())
}
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
pub enum GlobalMetaDataKind {
Expand Down
15 changes: 7 additions & 8 deletions src/librustc/dep_graph/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use rustc_data_structures::fx::FxHashMap;
use session::config::OutputType;
use std::cell::{Ref, RefCell};
use std::rc::Rc;
use std::sync::Arc;

use super::dep_node::{DepNode, WorkProductId};
use super::query::DepGraphQuery;
Expand All @@ -35,10 +34,10 @@ struct DepGraphData {
/// things available to us. If we find that they are not dirty, we
/// load the path to the file storing those work-products here into
/// this map. We can later look for and extract that data.
previous_work_products: RefCell<FxHashMap<Arc<WorkProductId>, WorkProduct>>,
previous_work_products: RefCell<FxHashMap<WorkProductId, WorkProduct>>,

/// Work-products that we generate in this run.
work_products: RefCell<FxHashMap<Arc<WorkProductId>, WorkProduct>>,
work_products: RefCell<FxHashMap<WorkProductId, WorkProduct>>,
}

impl DepGraph {
Expand Down Expand Up @@ -120,7 +119,7 @@ impl DepGraph {
/// Indicates that a previous work product exists for `v`. This is
/// invoked during initial start-up based on what nodes are clean
/// (and what files exist in the incr. directory).
pub fn insert_previous_work_product(&self, v: &Arc<WorkProductId>, data: WorkProduct) {
pub fn insert_previous_work_product(&self, v: &WorkProductId, data: WorkProduct) {
debug!("insert_previous_work_product({:?}, {:?})", v, data);
self.data.previous_work_products.borrow_mut()
.insert(v.clone(), data);
Expand All @@ -129,29 +128,29 @@ impl DepGraph {
/// Indicates that we created the given work-product in this run
/// for `v`. This record will be preserved and loaded in the next
/// run.
pub fn insert_work_product(&self, v: &Arc<WorkProductId>, data: WorkProduct) {
pub fn insert_work_product(&self, v: &WorkProductId, data: WorkProduct) {
debug!("insert_work_product({:?}, {:?})", v, data);
self.data.work_products.borrow_mut()
.insert(v.clone(), data);
}

/// Check whether a previous work product exists for `v` and, if
/// so, return the path that leads to it. Used to skip doing work.
pub fn previous_work_product(&self, v: &Arc<WorkProductId>) -> Option<WorkProduct> {
pub fn previous_work_product(&self, v: &WorkProductId) -> Option<WorkProduct> {
self.data.previous_work_products.borrow()
.get(v)
.cloned()
}

/// Access the map of work-products created during this run. Only
/// used during saving of the dep-graph.
pub fn work_products(&self) -> Ref<FxHashMap<Arc<WorkProductId>, WorkProduct>> {
pub fn work_products(&self) -> Ref<FxHashMap<WorkProductId, WorkProduct>> {
self.data.work_products.borrow()
}

/// Access the map of work-products created during the cached run. Only
/// used during saving of the dep-graph.
pub fn previous_work_products(&self) -> Ref<FxHashMap<Arc<WorkProductId>, WorkProduct>> {
pub fn previous_work_products(&self) -> Ref<FxHashMap<WorkProductId, WorkProduct>> {
self.data.previous_work_products.borrow()
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/ich/caching_codemap_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ pub struct CachingCodemapView<'tcx> {
time_stamp: usize,
}

impl<'tcx> CachingCodemapView<'tcx> {
pub fn new<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CachingCodemapView<'tcx> {
impl<'gcx> CachingCodemapView<'gcx> {
pub fn new<'a, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> CachingCodemapView<'gcx> {
let codemap = tcx.sess.codemap();
let files = codemap.files();
let first_file = files[0].clone();
Expand Down
74 changes: 39 additions & 35 deletions src/librustc/ich/hcx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ use rustc_data_structures::accumulate_vec::AccumulateVec;
/// enough information to transform DefIds and HirIds into stable DefPaths (i.e.
/// a reference to the TyCtxt) and it holds a few caches for speeding up various
/// things (e.g. each DefId/DefPath is only hashed once).
pub struct StableHashingContext<'a, 'tcx: 'a> {
tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
codemap: CachingCodemapView<'tcx>,
pub struct StableHashingContext<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
tcx: ty::TyCtxt<'a, 'gcx, 'tcx>,
codemap: CachingCodemapView<'gcx>,
hash_spans: bool,
hash_bodies: bool,
overflow_checks_enabled: bool,
Expand All @@ -51,9 +51,9 @@ pub enum NodeIdHashingMode {
HashTraitsInScope,
}

impl<'a, 'tcx: 'a> StableHashingContext<'a, 'tcx> {
impl<'a, 'gcx, 'tcx> StableHashingContext<'a, 'gcx, 'tcx> {

pub fn new(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>) -> Self {
pub fn new(tcx: ty::TyCtxt<'a, 'gcx, 'tcx>) -> Self {
let hash_spans_initial = tcx.sess.opts.debuginfo != NoDebugInfo;
let check_overflow_initial = tcx.sess.overflow_checks();

Expand Down Expand Up @@ -111,7 +111,7 @@ impl<'a, 'tcx: 'a> StableHashingContext<'a, 'tcx> {
}

#[inline]
pub fn tcx(&self) -> ty::TyCtxt<'a, 'tcx, 'tcx> {
pub fn tcx(&self) -> ty::TyCtxt<'a, 'gcx, 'tcx> {
self.tcx
}

Expand All @@ -131,7 +131,7 @@ impl<'a, 'tcx: 'a> StableHashingContext<'a, 'tcx> {
}

#[inline]
pub fn codemap(&mut self) -> &mut CachingCodemapView<'tcx> {
pub fn codemap(&mut self) -> &mut CachingCodemapView<'gcx> {
&mut self.codemap
}

Expand Down Expand Up @@ -195,9 +195,9 @@ impl<'a, 'tcx: 'a> StableHashingContext<'a, 'tcx> {
}


impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ast::NodeId {
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ast::NodeId {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a, 'tcx>,
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
hasher: &mut StableHasher<W>) {
match hcx.node_id_hashing_mode {
NodeIdHashingMode::Ignore => {
Expand Down Expand Up @@ -230,7 +230,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ast::NodeId {
}
}

impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for Span {
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for Span {

// Hash a span in a stable way. We can't directly hash the span's BytePos
// fields (that would be similar to hashing pointers, since those are just
Expand All @@ -242,7 +242,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for Span {
// Also, hashing filenames is expensive so we avoid doing it twice when the
// span starts and ends in the same file, which is almost always the case.
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a, 'tcx>,
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
hasher: &mut StableHasher<W>) {
use syntax_pos::Pos;

Expand Down Expand Up @@ -305,15 +305,16 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for Span {
}
}

pub fn hash_stable_hashmap<'a, 'tcx, K, V, R, SK, F, W>(hcx: &mut StableHashingContext<'a, 'tcx>,
hasher: &mut StableHasher<W>,
map: &HashMap<K, V, R>,
extract_stable_key: F)
pub fn hash_stable_hashmap<'a, 'gcx, 'tcx, K, V, R, SK, F, W>(
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
hasher: &mut StableHasher<W>,
map: &HashMap<K, V, R>,
extract_stable_key: F)
where K: Eq + std_hash::Hash,
V: HashStable<StableHashingContext<'a, 'tcx>>,
V: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>,
R: std_hash::BuildHasher,
SK: HashStable<StableHashingContext<'a, 'tcx>> + Ord + Clone,
F: Fn(&mut StableHashingContext<'a, 'tcx>, &K) -> SK,
SK: HashStable<StableHashingContext<'a, 'gcx, 'tcx>> + Ord + Clone,
F: Fn(&mut StableHashingContext<'a, 'gcx, 'tcx>, &K) -> SK,
W: StableHasherResult,
{
let mut keys: Vec<_> = map.keys()
Expand All @@ -327,14 +328,15 @@ pub fn hash_stable_hashmap<'a, 'tcx, K, V, R, SK, F, W>(hcx: &mut StableHashingC
}
}

pub fn hash_stable_hashset<'a, 'tcx, K, R, SK, F, W>(hcx: &mut StableHashingContext<'a, 'tcx>,
hasher: &mut StableHasher<W>,
set: &HashSet<K, R>,
extract_stable_key: F)
pub fn hash_stable_hashset<'a, 'tcx, 'gcx, K, R, SK, F, W>(
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
hasher: &mut StableHasher<W>,
set: &HashSet<K, R>,
extract_stable_key: F)
where K: Eq + std_hash::Hash,
R: std_hash::BuildHasher,
SK: HashStable<StableHashingContext<'a, 'tcx>> + Ord + Clone,
F: Fn(&mut StableHashingContext<'a, 'tcx>, &K) -> SK,
SK: HashStable<StableHashingContext<'a, 'gcx, 'tcx>> + Ord + Clone,
F: Fn(&mut StableHashingContext<'a, 'gcx, 'tcx>, &K) -> SK,
W: StableHasherResult,
{
let mut keys: Vec<_> = set.iter()
Expand All @@ -344,10 +346,11 @@ pub fn hash_stable_hashset<'a, 'tcx, K, R, SK, F, W>(hcx: &mut StableHashingCont
keys.hash_stable(hcx, hasher);
}

pub fn hash_stable_nodemap<'a, 'tcx, V, W>(hcx: &mut StableHashingContext<'a, 'tcx>,
hasher: &mut StableHasher<W>,
map: &NodeMap<V>)
where V: HashStable<StableHashingContext<'a, 'tcx>>,
pub fn hash_stable_nodemap<'a, 'tcx, 'gcx, V, W>(
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
hasher: &mut StableHasher<W>,
map: &NodeMap<V>)
where V: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>,
W: StableHasherResult,
{
hash_stable_hashmap(hcx, hasher, map, |hcx, node_id| {
Expand All @@ -356,14 +359,15 @@ pub fn hash_stable_nodemap<'a, 'tcx, V, W>(hcx: &mut StableHashingContext<'a, 't
}


pub fn hash_stable_btreemap<'a, 'tcx, K, V, SK, F, W>(hcx: &mut StableHashingContext<'a, 'tcx>,
hasher: &mut StableHasher<W>,
map: &BTreeMap<K, V>,
extract_stable_key: F)
pub fn hash_stable_btreemap<'a, 'tcx, 'gcx, K, V, SK, F, W>(
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
hasher: &mut StableHasher<W>,
map: &BTreeMap<K, V>,
extract_stable_key: F)
where K: Eq + Ord,
V: HashStable<StableHashingContext<'a, 'tcx>>,
SK: HashStable<StableHashingContext<'a, 'tcx>> + Ord + Clone,
F: Fn(&mut StableHashingContext<'a, 'tcx>, &K) -> SK,
V: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>,
SK: HashStable<StableHashingContext<'a, 'gcx, 'tcx>> + Ord + Clone,
F: Fn(&mut StableHashingContext<'a, 'gcx, 'tcx>, &K) -> SK,
W: StableHasherResult,
{
let mut keys: Vec<_> = map.keys()
Expand Down
Loading