Skip to content

Commit 63087b6

Browse files
committed
Parametrise by try_collect_active_jobs.
1 parent 232364a commit 63087b6

File tree

3 files changed

+78
-69
lines changed

3 files changed

+78
-69
lines changed

src/librustc/ty/query/config.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22
33
use crate::dep_graph::SerializedDepNodeIndex;
44
use crate::ty::query::caches::QueryCache;
5-
use crate::ty::query::job::QueryJobId;
5+
use crate::ty::query::job::{QueryJobId, QueryJobInfo};
66
use crate::ty::query::plumbing::CycleError;
77
use crate::ty::query::QueryState;
88
use rustc_data_structures::profiling::ProfileCategory;
99
use rustc_hir::def_id::DefId;
1010

1111
use rustc_data_structures::fingerprint::Fingerprint;
12+
use rustc_data_structures::fx::FxHashMap;
1213
use rustc_query_system::dep_graph::{DepContext, DepNode};
1314
use rustc_session::Session;
1415
use std::borrow::Cow;
@@ -24,7 +25,7 @@ pub trait QueryConfig<CTX> {
2425
}
2526

2627
pub trait QueryContext: DepContext {
27-
type Query;
28+
type Query: Clone;
2829

2930
/// Access the session.
3031
fn session(&self) -> &Session;
@@ -34,6 +35,10 @@ pub trait QueryContext: DepContext {
3435

3536
/// Get the query information from the TLS context.
3637
fn read_query_job<R>(&self, op: impl FnOnce(Option<QueryJobId<Self::DepKind>>) -> R) -> R;
38+
39+
fn try_collect_active_jobs(
40+
&self,
41+
) -> Option<FxHashMap<QueryJobId<Self::DepKind>, QueryJobInfo<Self>>>;
3742
}
3843

3944
pub(crate) trait QueryAccessors<CTX: QueryContext>: QueryConfig<CTX> {
@@ -56,7 +61,7 @@ pub(crate) trait QueryAccessors<CTX: QueryContext>: QueryConfig<CTX> {
5661
result: &Self::Value,
5762
) -> Option<Fingerprint>;
5863

59-
fn handle_cycle_error(tcx: CTX, error: CycleError<CTX>) -> Self::Value;
64+
fn handle_cycle_error(tcx: CTX, error: CycleError<CTX::Query>) -> Self::Value;
6065
}
6166

6267
pub(crate) trait QueryDescription<CTX: QueryContext>: QueryAccessors<CTX> {

src/librustc/ty/query/job.rs

Lines changed: 59 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
use crate::dep_graph::DepKind;
2-
use crate::ty::context::TyCtxt;
31
use crate::ty::query::config::QueryContext;
42
use crate::ty::query::plumbing::CycleError;
5-
use crate::ty::query::Query;
3+
#[cfg(parallel_compiler)]
64
use crate::ty::tls;
75

86
use rustc_data_structures::fx::FxHashMap;
7+
use rustc_query_system::dep_graph::DepContext;
98
use rustc_span::Span;
109

1110
use std::convert::TryFrom;
@@ -28,13 +27,13 @@ use {
2827

2928
/// Represents a span and a query key.
3029
#[derive(Clone, Debug)]
31-
pub struct QueryInfo<CTX: QueryContext> {
30+
pub struct QueryInfo<Q> {
3231
/// The span corresponding to the reason for which this query was required.
3332
pub span: Span,
34-
pub query: CTX::Query,
33+
pub query: Q,
3534
}
3635

37-
type QueryMap<'tcx> = FxHashMap<QueryJobId<DepKind>, QueryJobInfo<TyCtxt<'tcx>>>;
36+
type QueryMap<CTX> = FxHashMap<QueryJobId<<CTX as DepContext>::DepKind>, QueryJobInfo<CTX>>;
3837

3938
/// A value uniquely identifiying an active query job within a shard in the query cache.
4039
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
@@ -53,35 +52,36 @@ pub struct QueryJobId<K> {
5352
pub kind: K,
5453
}
5554

56-
impl<K> QueryJobId<K> {
55+
impl<K: rustc_query_system::dep_graph::DepKind> QueryJobId<K> {
5756
pub fn new(job: QueryShardJobId, shard: usize, kind: K) -> Self {
5857
QueryJobId { job, shard: u16::try_from(shard).unwrap(), kind }
5958
}
60-
}
6159

62-
impl QueryJobId<DepKind> {
63-
fn query<'tcx>(self, map: &QueryMap<'tcx>) -> Query<'tcx> {
60+
fn query<CTX: QueryContext<DepKind = K>>(self, map: &QueryMap<CTX>) -> CTX::Query {
6461
map.get(&self).unwrap().info.query.clone()
6562
}
6663

6764
#[cfg(parallel_compiler)]
68-
fn span(self, map: &QueryMap<'_>) -> Span {
65+
fn span<CTX: QueryContext<DepKind = K>>(self, map: &QueryMap<CTX>) -> Span {
6966
map.get(&self).unwrap().job.span
7067
}
7168

7269
#[cfg(parallel_compiler)]
73-
fn parent(self, map: &QueryMap<'_>) -> Option<QueryJobId<DepKind>> {
70+
fn parent<CTX: QueryContext<DepKind = K>>(self, map: &QueryMap<CTX>) -> Option<QueryJobId<K>> {
7471
map.get(&self).unwrap().job.parent
7572
}
7673

7774
#[cfg(parallel_compiler)]
78-
fn latch<'a, 'tcx>(self, map: &'a QueryMap<'tcx>) -> Option<&'a QueryLatch<TyCtxt<'tcx>>> {
75+
fn latch<'a, CTX: QueryContext<DepKind = K>>(
76+
self,
77+
map: &'a QueryMap<CTX>,
78+
) -> Option<&'a QueryLatch<CTX>> {
7979
map.get(&self).unwrap().job.latch.as_ref()
8080
}
8181
}
8282

8383
pub struct QueryJobInfo<CTX: QueryContext> {
84-
pub info: QueryInfo<CTX>,
84+
pub info: QueryInfo<CTX::Query>,
8585
pub job: QueryJob<CTX>,
8686
}
8787

@@ -147,16 +147,12 @@ pub(super) struct QueryLatch<CTX: QueryContext> {
147147
}
148148

149149
#[cfg(not(parallel_compiler))]
150-
impl<'tcx> QueryLatch<TyCtxt<'tcx>> {
151-
pub(super) fn find_cycle_in_stack(
152-
&self,
153-
tcx: TyCtxt<'tcx>,
154-
span: Span,
155-
) -> CycleError<TyCtxt<'tcx>> {
156-
let query_map = tcx.queries.try_collect_active_jobs().unwrap();
150+
impl<CTX: QueryContext> QueryLatch<CTX> {
151+
pub(super) fn find_cycle_in_stack(&self, tcx: CTX, span: Span) -> CycleError<CTX::Query> {
152+
let query_map = tcx.try_collect_active_jobs().unwrap();
157153

158154
// Get the current executing query (waiter) and find the waitee amongst its parents
159-
let mut current_job = tls::with_related_context(tcx, |icx| icx.query);
155+
let mut current_job = tcx.read_query_job(|query| query);
160156
let mut cycle = Vec::new();
161157

162158
while let Some(job) = current_job {
@@ -192,7 +188,7 @@ struct QueryWaiter<CTX: QueryContext> {
192188
query: Option<QueryJobId<CTX::DepKind>>,
193189
condvar: Condvar,
194190
span: Span,
195-
cycle: Lock<Option<CycleError<CTX>>>,
191+
cycle: Lock<Option<CycleError<CTX::Query>>>,
196192
}
197193

198194
#[cfg(parallel_compiler)]
@@ -225,13 +221,9 @@ impl<CTX: QueryContext> QueryLatch<CTX> {
225221
}
226222

227223
#[cfg(parallel_compiler)]
228-
impl<K, CTX> QueryLatch<CTX>
229-
where
230-
K: rustc_query_system::dep_graph::DepKind,
231-
CTX: QueryContext<DepKind = K>,
232-
{
224+
impl<CTX: QueryContext> QueryLatch<CTX> {
233225
/// Awaits for the query job to complete.
234-
pub(super) fn wait_on(&self, tcx: CTX, span: Span) -> Result<(), CycleError<CTX>> {
226+
pub(super) fn wait_on(&self, tcx: CTX, span: Span) -> Result<(), CycleError<CTX::Query>> {
235227
tcx.read_query_job(move |query| {
236228
let waiter = Lrc::new(QueryWaiter {
237229
query,
@@ -299,7 +291,7 @@ impl<CTX: QueryContext> QueryLatch<CTX> {
299291

300292
/// A resumable waiter of a query. The usize is the index into waiters in the query's latch
301293
#[cfg(parallel_compiler)]
302-
type Waiter = (QueryJobId<DepKind>, usize);
294+
type Waiter<K> = (QueryJobId<K>, usize);
303295

304296
/// Visits all the non-resumable and resumable waiters of a query.
305297
/// Only waiters in a query are visited.
@@ -311,13 +303,13 @@ type Waiter = (QueryJobId<DepKind>, usize);
311303
/// required information to resume the waiter.
312304
/// If all `visit` calls returns None, this function also returns None.
313305
#[cfg(parallel_compiler)]
314-
fn visit_waiters<'tcx, F>(
315-
query_map: &QueryMap<'tcx>,
316-
query: QueryJobId<DepKind>,
306+
fn visit_waiters<CTX: QueryContext, F>(
307+
query_map: &QueryMap<CTX>,
308+
query: QueryJobId<CTX::DepKind>,
317309
mut visit: F,
318-
) -> Option<Option<Waiter>>
310+
) -> Option<Option<Waiter<CTX::DepKind>>>
319311
where
320-
F: FnMut(Span, QueryJobId<DepKind>) -> Option<Option<Waiter>>,
312+
F: FnMut(Span, QueryJobId<CTX::DepKind>) -> Option<Option<Waiter<CTX::DepKind>>>,
321313
{
322314
// Visit the parent query which is a non-resumable waiter since it's on the same stack
323315
if let Some(parent) = query.parent(query_map) {
@@ -346,13 +338,13 @@ where
346338
/// If a cycle is detected, this initial value is replaced with the span causing
347339
/// the cycle.
348340
#[cfg(parallel_compiler)]
349-
fn cycle_check<'tcx>(
350-
query_map: &QueryMap<'tcx>,
351-
query: QueryJobId<DepKind>,
341+
fn cycle_check<CTX: QueryContext>(
342+
query_map: &QueryMap<CTX>,
343+
query: QueryJobId<CTX::DepKind>,
352344
span: Span,
353-
stack: &mut Vec<(Span, QueryJobId<DepKind>)>,
354-
visited: &mut FxHashSet<QueryJobId<DepKind>>,
355-
) -> Option<Option<Waiter>> {
345+
stack: &mut Vec<(Span, QueryJobId<CTX::DepKind>)>,
346+
visited: &mut FxHashSet<QueryJobId<CTX::DepKind>>,
347+
) -> Option<Option<Waiter<CTX::DepKind>>> {
356348
if !visited.insert(query) {
357349
return if let Some(p) = stack.iter().position(|q| q.1 == query) {
358350
// We detected a query cycle, fix up the initial span and return Some
@@ -387,10 +379,10 @@ fn cycle_check<'tcx>(
387379
/// from `query` without going through any of the queries in `visited`.
388380
/// This is achieved with a depth first search.
389381
#[cfg(parallel_compiler)]
390-
fn connected_to_root<'tcx>(
391-
query_map: &QueryMap<'tcx>,
392-
query: QueryJobId<DepKind>,
393-
visited: &mut FxHashSet<QueryJobId<DepKind>>,
382+
fn connected_to_root<CTX: QueryContext>(
383+
query_map: &QueryMap<CTX>,
384+
query: QueryJobId<CTX::DepKind>,
385+
visited: &mut FxHashSet<QueryJobId<CTX::DepKind>>,
394386
) -> bool {
395387
// We already visited this or we're deliberately ignoring it
396388
if !visited.insert(query) {
@@ -410,12 +402,12 @@ fn connected_to_root<'tcx>(
410402

411403
// Deterministically pick an query from a list
412404
#[cfg(parallel_compiler)]
413-
fn pick_query<'a, 'tcx, T, F: Fn(&T) -> (Span, QueryJobId<DepKind>)>(
414-
query_map: &QueryMap<'tcx>,
415-
tcx: TyCtxt<'tcx>,
416-
queries: &'a [T],
417-
f: F,
418-
) -> &'a T {
405+
fn pick_query<'a, CTX, T, F>(query_map: &QueryMap<CTX>, tcx: CTX, queries: &'a [T], f: F) -> &'a T
406+
where
407+
CTX: QueryContext,
408+
CTX::Query: HashStable<CTX::StableHashingContext>,
409+
F: Fn(&T) -> (Span, QueryJobId<CTX::DepKind>),
410+
{
419411
// Deterministically pick an entry point
420412
// FIXME: Sort this instead
421413
let mut hcx = tcx.create_stable_hashing_context();
@@ -440,12 +432,15 @@ fn pick_query<'a, 'tcx, T, F: Fn(&T) -> (Span, QueryJobId<DepKind>)>(
440432
/// If a cycle was not found, the starting query is removed from `jobs` and
441433
/// the function returns false.
442434
#[cfg(parallel_compiler)]
443-
fn remove_cycle<'tcx>(
444-
query_map: &QueryMap<'tcx>,
445-
jobs: &mut Vec<QueryJobId<DepKind>>,
446-
wakelist: &mut Vec<Lrc<QueryWaiter<TyCtxt<'tcx>>>>,
447-
tcx: TyCtxt<'tcx>,
448-
) -> bool {
435+
fn remove_cycle<CTX: QueryContext>(
436+
query_map: &QueryMap<CTX>,
437+
jobs: &mut Vec<QueryJobId<CTX::DepKind>>,
438+
wakelist: &mut Vec<Lrc<QueryWaiter<CTX>>>,
439+
tcx: CTX,
440+
) -> bool
441+
where
442+
CTX::Query: HashStable<CTX::StableHashingContext>,
443+
{
449444
let mut visited = FxHashSet::default();
450445
let mut stack = Vec::new();
451446
// Look for a cycle starting with the last query in `jobs`
@@ -497,7 +492,7 @@ fn remove_cycle<'tcx>(
497492
}
498493
}
499494
})
500-
.collect::<Vec<(Span, QueryJobId<DepKind>, Option<(Span, QueryJobId<DepKind>)>)>>();
495+
.collect::<Vec<(Span, QueryJobId<CTX::DepKind>, Option<(Span, QueryJobId<CTX::DepKind>)>)>>();
501496

502497
// Deterministically pick an entry point
503498
let (_, entry_point, usage) = pick_query(query_map, tcx, &entry_points, |e| (e.0, e.1));
@@ -569,15 +564,18 @@ pub unsafe fn handle_deadlock() {
569564
/// There may be multiple cycles involved in a deadlock, so this searches
570565
/// all active queries for cycles before finally resuming all the waiters at once.
571566
#[cfg(parallel_compiler)]
572-
fn deadlock(tcx: TyCtxt<'_>, registry: &rayon_core::Registry) {
567+
fn deadlock<CTX: QueryContext>(tcx: CTX, registry: &rayon_core::Registry)
568+
where
569+
CTX::Query: HashStable<CTX::StableHashingContext>,
570+
{
573571
let on_panic = OnDrop(|| {
574572
eprintln!("deadlock handler panicked, aborting process");
575573
process::abort();
576574
});
577575

578576
let mut wakelist = Vec::new();
579-
let query_map = tcx.queries.try_collect_active_jobs().unwrap();
580-
let mut jobs: Vec<QueryJobId<DepKind>> = query_map.keys().cloned().collect();
577+
let query_map = tcx.try_collect_active_jobs().unwrap();
578+
let mut jobs: Vec<QueryJobId<CTX::DepKind>> = query_map.keys().cloned().collect();
581579

582580
let mut found_cycle = false;
583581

src/librustc/ty/query/plumbing.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -332,10 +332,10 @@ where
332332
}
333333

334334
#[derive(Clone)]
335-
pub(crate) struct CycleError<CTX: QueryContext> {
335+
pub(crate) struct CycleError<Q> {
336336
/// The query and related span that uses the cycle.
337-
pub(super) usage: Option<(Span, CTX::Query)>,
338-
pub(super) cycle: Vec<QueryInfo<CTX>>,
337+
pub(super) usage: Option<(Span, Q)>,
338+
pub(super) cycle: Vec<QueryInfo<Q>>,
339339
}
340340

341341
/// The result of `try_start`.
@@ -371,6 +371,12 @@ impl QueryContext for TyCtxt<'tcx> {
371371
fn read_query_job<R>(&self, op: impl FnOnce(Option<QueryJobId<Self::DepKind>>) -> R) -> R {
372372
tls::with_related_context(*self, move |icx| op(icx.query))
373373
}
374+
375+
fn try_collect_active_jobs(
376+
&self,
377+
) -> Option<FxHashMap<QueryJobId<Self::DepKind>, QueryJobInfo<Self>>> {
378+
self.queries.try_collect_active_jobs()
379+
}
374380
}
375381

376382
impl<'tcx> TyCtxt<'tcx> {
@@ -409,7 +415,7 @@ impl<'tcx> TyCtxt<'tcx> {
409415
#[cold]
410416
pub(super) fn report_cycle(
411417
self,
412-
CycleError { usage, cycle: stack }: CycleError<TyCtxt<'tcx>>,
418+
CycleError { usage, cycle: stack }: CycleError<Query<'tcx>>,
413419
) -> DiagnosticBuilder<'tcx> {
414420
assert!(!stack.is_empty());
415421

@@ -1033,7 +1039,7 @@ macro_rules! define_queries_inner {
10331039

10341040
fn handle_cycle_error(
10351041
tcx: TyCtxt<'tcx>,
1036-
error: CycleError<TyCtxt<'tcx>>
1042+
error: CycleError<Query<'tcx>>
10371043
) -> Self::Value {
10381044
handle_cycle_error!([$($modifiers)*][tcx, error])
10391045
}

0 commit comments

Comments
 (0)