1
Fork 0

Simplify hashing.

This commit is contained in:
Camille GILLOT 2021-02-09 18:53:38 +01:00
parent a87de890fd
commit 903f65f215
3 changed files with 26 additions and 35 deletions

View file

@ -339,12 +339,12 @@ macro_rules! define_queries {
} else {
Some(key.default_span(*tcx))
};
let hash = {
let hash = || {
let mut hcx = tcx.create_stable_hashing_context();
let mut hasher = StableHasher::new();
std::mem::discriminant(&kind).hash_stable(&mut hcx, &mut hasher);
key.hash_stable(&mut hcx, &mut hasher);
hasher.finish()
hasher.finish::<u64>()
};
QueryStackFrame::new(name, description, span, hash)

View file

@ -14,9 +14,9 @@ use std::num::NonZeroU32;
#[cfg(parallel_compiler)]
use {
crate::dep_graph::DepKind,
parking_lot::{Condvar, Mutex},
rustc_data_structures::fx::FxHashSet,
rustc_data_structures::stable_hasher::{HashStable, StableHasher},
rustc_data_structures::sync::Lock,
rustc_data_structures::sync::Lrc,
rustc_data_structures::{jobserver, OnDrop},
@ -417,30 +417,23 @@ where
// Deterministically pick an query from a list
#[cfg(parallel_compiler)]
fn pick_query<'a, CTX, T, F>(
query_map: &QueryMap<CTX::DepKind>,
tcx: CTX,
queries: &'a [T],
f: F,
) -> &'a T
fn pick_query<'a, D, T, F>(query_map: &QueryMap<D>, queries: &'a [T], f: F) -> &'a T
where
CTX: QueryContext,
F: Fn(&T) -> (Span, QueryJobId<CTX::DepKind>),
D: Copy + Clone + Eq + Hash,
F: Fn(&T) -> (Span, QueryJobId<D>),
{
// Deterministically pick an entry point
// FIXME: Sort this instead
let mut hcx = tcx.dep_context().create_stable_hashing_context();
queries
.iter()
.min_by_key(|v| {
let (span, query) = f(v);
let mut stable_hasher = StableHasher::new();
query.query(query_map).hash_stable(&mut hcx, &mut stable_hasher);
let hash = query.query(query_map).hash;
// Prefer entry points which have valid spans for nicer error messages
// We add an integer to the tuple ensuring that entry points
// with valid spans are picked first
let span_cmp = if span == DUMMY_SP { 1 } else { 0 };
(span_cmp, stable_hasher.finish::<u64>())
(span_cmp, hash)
})
.unwrap()
}
@ -451,11 +444,10 @@ where
/// If a cycle was not found, the starting query is removed from `jobs` and
/// the function returns false.
#[cfg(parallel_compiler)]
fn remove_cycle<CTX: QueryContext>(
query_map: &QueryMap<CTX::DepKind>,
jobs: &mut Vec<QueryJobId<CTX::DepKind>>,
wakelist: &mut Vec<Lrc<QueryWaiter<CTX::DepKind>>>,
tcx: CTX,
fn remove_cycle<D: DepKind>(
query_map: &QueryMap<D>,
jobs: &mut Vec<QueryJobId<D>>,
wakelist: &mut Vec<Lrc<QueryWaiter<D>>>,
) -> bool {
let mut visited = FxHashSet::default();
let mut stack = Vec::new();
@ -505,15 +497,15 @@ fn remove_cycle<CTX: QueryContext>(
None
} else {
// Deterministically pick one of the waiters to show to the user
let waiter = *pick_query(query_map, tcx, &waiters, |s| *s);
let waiter = *pick_query(query_map, &waiters, |s| *s);
Some((span, query, Some(waiter)))
}
}
})
.collect::<Vec<(Span, QueryJobId<CTX::DepKind>, Option<(Span, QueryJobId<CTX::DepKind>)>)>>();
.collect::<Vec<(Span, QueryJobId<D>, Option<(Span, QueryJobId<D>)>)>>();
// Deterministically pick an entry point
let (_, entry_point, usage) = pick_query(query_map, tcx, &entry_points, |e| (e.0, e.1));
let (_, entry_point, usage) = pick_query(query_map, &entry_points, |e| (e.0, e.1));
// Shift the stack so that our entry point is first
let entry_point_pos = stack.iter().position(|(_, query)| query == entry_point);
@ -570,7 +562,7 @@ pub fn deadlock<CTX: QueryContext>(tcx: CTX, registry: &rayon_core::Registry) {
let mut found_cycle = false;
while jobs.len() > 0 {
if remove_cycle(&query_map, &mut jobs, &mut wakelist, tcx) {
if remove_cycle(&query_map, &mut jobs, &mut wakelist) {
found_cycle = true;
}
}

View file

@ -16,8 +16,6 @@ pub use self::config::{QueryAccessors, QueryConfig, QueryDescription};
use crate::dep_graph::{DepNode, DepNodeIndex, HasDepContext, SerializedDepNodeIndex};
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::Lock;
use rustc_data_structures::thin_vec::ThinVec;
use rustc_errors::Diagnostic;
@ -34,7 +32,8 @@ pub struct QueryStackFrame {
span: Option<Span>,
/// This hash is used to deterministically pick
/// a query to remove cycles in the parallel compiler.
hash: Fingerprint,
#[cfg(parallel_compiler)]
hash: u64,
}
impl QueryStackFrame {
@ -43,9 +42,15 @@ impl QueryStackFrame {
name: &'static str,
description: String,
span: Option<Span>,
hash: Fingerprint,
_hash: impl FnOnce() -> u64,
) -> Self {
Self { name, hash, description, span }
Self {
name,
description,
span,
#[cfg(parallel_compiler)]
hash: _hash(),
}
}
// FIXME(eddyb) Get more valid `Span`s on queries.
@ -58,12 +63,6 @@ impl QueryStackFrame {
}
}
impl<CTX> HashStable<CTX> for QueryStackFrame {
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
self.hash.hash_stable(hcx, hasher)
}
}
pub trait QueryContext: HasDepContext {
/// Get string representation from DefPath.
fn def_path_str(&self, def_id: DefId) -> String;