From 52cedcab9221bd63a67f4de4cd9c577518ed0d3b Mon Sep 17 00:00:00 2001 From: Julian Wollersberger Date: Mon, 12 Oct 2020 16:29:41 +0200 Subject: Remove in a bunch of places. It was only needed by `find_cycle_in_stack()` in job.rs, but needed to be forwarded through dozens of types. --- compiler/rustc_query_system/src/query/job.rs | 170 +++++++++++++++------------ 1 file changed, 98 insertions(+), 72 deletions(-) (limited to 'compiler/rustc_query_system/src/query/job.rs') diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs index 190312bb330..c1d3210b617 100644 --- a/compiler/rustc_query_system/src/query/job.rs +++ b/compiler/rustc_query_system/src/query/job.rs @@ -1,16 +1,16 @@ -use crate::dep_graph::{DepContext, DepKind}; use crate::query::plumbing::CycleError; -use crate::query::QueryContext; use rustc_data_structures::fx::FxHashMap; use rustc_span::Span; use std::convert::TryFrom; +use std::hash::Hash; use std::marker::PhantomData; use std::num::NonZeroU32; #[cfg(parallel_compiler)] use { + super::QueryContext, parking_lot::{Condvar, Mutex}, rustc_data_structures::fx::FxHashSet, rustc_data_structures::stable_hasher::{HashStable, StableHasher}, @@ -31,7 +31,7 @@ pub struct QueryInfo { pub query: Q, } -type QueryMap = FxHashMap::DepKind>, QueryJobInfo>; +pub(crate) type QueryMap = FxHashMap, QueryJobInfo>; /// A value uniquely identifiying an active query job within a shard in the query cache. #[derive(Copy, Clone, Eq, PartialEq, Hash)] @@ -39,71 +39,75 @@ pub struct QueryShardJobId(pub NonZeroU32); /// A value uniquely identifiying an active query job. #[derive(Copy, Clone, Eq, PartialEq, Hash)] -pub struct QueryJobId { +pub struct QueryJobId { /// Which job within a shard is this pub job: QueryShardJobId, /// In which shard is this job pub shard: u16, - /// What kind of query this job is - pub kind: K, + /// What kind of query this job is. + pub kind: D, } -impl QueryJobId { - pub fn new(job: QueryShardJobId, shard: usize, kind: K) -> Self { +impl QueryJobId +where + D: Copy + Clone + Eq + Hash, +{ + pub fn new(job: QueryShardJobId, shard: usize, kind: D) -> Self { QueryJobId { job, shard: u16::try_from(shard).unwrap(), kind } } - fn query>(self, map: &QueryMap) -> CTX::Query { + fn query(self, map: &QueryMap) -> Q { map.get(&self).unwrap().info.query.clone() } #[cfg(parallel_compiler)] - fn span>(self, map: &QueryMap) -> Span { + fn span(self, map: &QueryMap) -> Span { map.get(&self).unwrap().job.span } #[cfg(parallel_compiler)] - fn parent>(self, map: &QueryMap) -> Option> { + fn parent(self, map: &QueryMap) -> Option> { map.get(&self).unwrap().job.parent } #[cfg(parallel_compiler)] - fn latch<'a, CTX: QueryContext>( - self, - map: &'a QueryMap, - ) -> Option<&'a QueryLatch> { + fn latch<'a, Q: Clone>(self, map: &'a QueryMap) -> Option<&'a QueryLatch> { map.get(&self).unwrap().job.latch.as_ref() } } -pub struct QueryJobInfo { - pub info: QueryInfo, - pub job: QueryJob, +pub struct QueryJobInfo { + pub info: QueryInfo, + pub job: QueryJob, } /// Represents an active query job. #[derive(Clone)] -pub struct QueryJob { +pub struct QueryJob { pub id: QueryShardJobId, /// The span corresponding to the reason for which this query was required. pub span: Span, /// The parent query job which created this job and is implicitly waiting on it. - pub parent: Option>, + pub parent: Option>, /// The latch that is used to wait on this job. #[cfg(parallel_compiler)] - latch: Option>, + latch: Option>, - dummy: PhantomData>, + dummy: PhantomData>, } -impl QueryJob { +impl QueryJob +where + D: Copy + Clone + Eq + Hash, + Q: Clone, +{ /// Creates a new query job. - pub fn new(id: QueryShardJobId, span: Span, parent: Option>) -> Self { + pub fn new(id: QueryShardJobId, span: Span, parent: Option>) -> Self { QueryJob { id, span, @@ -115,7 +119,7 @@ impl QueryJob { } #[cfg(parallel_compiler)] - pub(super) fn latch(&mut self, _id: QueryJobId) -> QueryLatch { + pub(super) fn latch(&mut self, _id: QueryJobId) -> QueryLatch { if self.latch.is_none() { self.latch = Some(QueryLatch::new()); } @@ -123,7 +127,7 @@ impl QueryJob { } #[cfg(not(parallel_compiler))] - pub(super) fn latch(&mut self, id: QueryJobId) -> QueryLatch { + pub(super) fn latch(&mut self, id: QueryJobId) -> QueryLatch { QueryLatch { id, dummy: PhantomData } } @@ -143,19 +147,26 @@ impl QueryJob { #[cfg(not(parallel_compiler))] #[derive(Clone)] -pub(super) struct QueryLatch { - id: QueryJobId, - dummy: PhantomData, +pub(super) struct QueryLatch { + id: QueryJobId, + dummy: PhantomData, } #[cfg(not(parallel_compiler))] -impl QueryLatch { - pub(super) fn find_cycle_in_stack(&self, tcx: CTX, span: Span) -> CycleError { - let query_map = tcx.try_collect_active_jobs().unwrap(); - - // Get the current executing query (waiter) and find the waitee amongst its parents - let mut current_job = tcx.current_query_job(); +impl QueryLatch +where + D: Copy + Clone + Eq + Hash, + Q: Clone, +{ + pub(super) fn find_cycle_in_stack( + &self, + query_map: QueryMap, + current_job: &Option>, + span: Span, + ) -> CycleError { + // Find the waitee amongst `current_job` parents let mut cycle = Vec::new(); + let mut current_job = Option::clone(current_job); while let Some(job) = current_job { let info = query_map.get(&job).unwrap(); @@ -186,15 +197,15 @@ impl QueryLatch { } #[cfg(parallel_compiler)] -struct QueryWaiter { - query: Option>, +struct QueryWaiter { + query: Option>, condvar: Condvar, span: Span, - cycle: Lock>>, + cycle: Lock>>, } #[cfg(parallel_compiler)] -impl QueryWaiter { +impl QueryWaiter { fn notify(&self, registry: &rayon_core::Registry) { rayon_core::mark_unblocked(registry); self.condvar.notify_one(); @@ -202,19 +213,19 @@ impl QueryWaiter { } #[cfg(parallel_compiler)] -struct QueryLatchInfo { +struct QueryLatchInfo { complete: bool, - waiters: Vec>>, + waiters: Vec>>, } #[cfg(parallel_compiler)] #[derive(Clone)] -pub(super) struct QueryLatch { - info: Lrc>>, +pub(super) struct QueryLatch { + info: Lrc>>, } #[cfg(parallel_compiler)] -impl QueryLatch { +impl QueryLatch { fn new() -> Self { QueryLatch { info: Lrc::new(Mutex::new(QueryLatchInfo { complete: false, waiters: Vec::new() })), @@ -223,10 +234,13 @@ impl QueryLatch { } #[cfg(parallel_compiler)] -impl QueryLatch { +impl QueryLatch { /// Awaits for the query job to complete. - pub(super) fn wait_on(&self, tcx: CTX, span: Span) -> Result<(), CycleError> { - let query = tcx.current_query_job(); + pub(super) fn wait_on( + &self, + query: Option>, + span: Span, + ) -> Result<(), CycleError> { let waiter = Lrc::new(QueryWaiter { query, span, cycle: Lock::new(None), condvar: Condvar::new() }); self.wait_on_inner(&waiter); @@ -239,12 +253,9 @@ impl QueryLatch { Some(cycle) => Err(cycle), } } -} -#[cfg(parallel_compiler)] -impl QueryLatch { /// Awaits the caller on this latch by blocking the current thread. - fn wait_on_inner(&self, waiter: &Lrc>) { + fn wait_on_inner(&self, waiter: &Lrc>) { let mut info = self.info.lock(); if !info.complete { // We push the waiter on to the `waiters` list. It can be accessed inside @@ -278,7 +289,7 @@ impl QueryLatch { /// Removes a single waiter from the list of waiters. /// This is used to break query cycles. - fn extract_waiter(&self, waiter: usize) -> Lrc> { + fn extract_waiter(&self, waiter: usize) -> Lrc> { let mut info = self.info.lock(); debug_assert!(!info.complete); // Remove the waiter from the list of waiters @@ -288,7 +299,7 @@ impl QueryLatch { /// A resumable waiter of a query. The usize is the index into waiters in the query's latch #[cfg(parallel_compiler)] -type Waiter = (QueryJobId, usize); +type Waiter = (QueryJobId, usize); /// Visits all the non-resumable and resumable waiters of a query. /// Only waiters in a query are visited. @@ -300,13 +311,15 @@ type Waiter = (QueryJobId, usize); /// required information to resume the waiter. /// If all `visit` calls returns None, this function also returns None. #[cfg(parallel_compiler)] -fn visit_waiters( - query_map: &QueryMap, - query: QueryJobId, +fn visit_waiters( + query_map: &QueryMap, + query: QueryJobId, mut visit: F, -) -> Option>> +) -> Option>> where - F: FnMut(Span, QueryJobId) -> Option>>, + D: Copy + Clone + Eq + Hash, + Q: Clone, + F: FnMut(Span, QueryJobId) -> Option>>, { // Visit the parent query which is a non-resumable waiter since it's on the same stack if let Some(parent) = query.parent(query_map) { @@ -335,13 +348,17 @@ where /// If a cycle is detected, this initial value is replaced with the span causing /// the cycle. #[cfg(parallel_compiler)] -fn cycle_check( - query_map: &QueryMap, - query: QueryJobId, +fn cycle_check( + query_map: &QueryMap, + query: QueryJobId, span: Span, - stack: &mut Vec<(Span, QueryJobId)>, - visited: &mut FxHashSet>, -) -> Option>> { + stack: &mut Vec<(Span, QueryJobId)>, + visited: &mut FxHashSet>, +) -> Option>> +where + D: Copy + Clone + Eq + Hash, + Q: Clone, +{ if !visited.insert(query) { return if let Some(p) = stack.iter().position(|q| q.1 == query) { // We detected a query cycle, fix up the initial span and return Some @@ -376,11 +393,15 @@ fn cycle_check( /// from `query` without going through any of the queries in `visited`. /// This is achieved with a depth first search. #[cfg(parallel_compiler)] -fn connected_to_root( - query_map: &QueryMap, - query: QueryJobId, - visited: &mut FxHashSet>, -) -> bool { +fn connected_to_root( + query_map: &QueryMap, + query: QueryJobId, + visited: &mut FxHashSet>, +) -> bool +where + D: Copy + Clone + Eq + Hash, + Q: Clone, +{ // We already visited this or we're deliberately ignoring it if !visited.insert(query) { return false; @@ -399,7 +420,12 @@ fn connected_to_root( // Deterministically pick an query from a list #[cfg(parallel_compiler)] -fn pick_query<'a, CTX, T, F>(query_map: &QueryMap, tcx: CTX, queries: &'a [T], f: F) -> &'a T +fn pick_query<'a, CTX, T, F>( + query_map: &QueryMap, + tcx: CTX, + queries: &'a [T], + f: F, +) -> &'a T where CTX: QueryContext, F: Fn(&T) -> (Span, QueryJobId), @@ -429,9 +455,9 @@ where /// the function returns false. #[cfg(parallel_compiler)] fn remove_cycle( - query_map: &QueryMap, + query_map: &QueryMap, jobs: &mut Vec>, - wakelist: &mut Vec>>, + wakelist: &mut Vec>>, tcx: CTX, ) -> bool { let mut visited = FxHashSet::default(); -- cgit 1.4.1-3-g733a5