Skip to content

Commit a8290c6

Browse files
authored
Rollup merge of #153766 - nnethercote:try_execute_query-tweaks, r=cjgillot
`try_execute_query` tweaks Details in individual commits. r? @cjgillot
2 parents 19f7c94 + f0c2760 commit a8290c6

1 file changed

Lines changed: 61 additions & 64 deletions

File tree

compiler/rustc_query_impl/src/execution.rs

Lines changed: 61 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ fn wait_for_query<'tcx, C: QueryCache>(
240240
tcx: TyCtxt<'tcx>,
241241
span: Span,
242242
key: C::Key,
243+
key_hash: u64,
243244
latch: QueryLatch<'tcx>,
244245
current: Option<QueryJobId>,
245246
) -> (C::Value, Option<DepNodeIndex>) {
@@ -248,8 +249,7 @@ fn wait_for_query<'tcx, C: QueryCache>(
248249
// self-profiler.
249250
let query_blocked_prof_timer = tcx.prof.query_blocked();
250251

251-
// With parallel queries we might just have to wait on some other
252-
// thread.
252+
// With parallel queries we might just have to wait on some other thread.
253253
let result = latch.wait_on(tcx, current, span);
254254

255255
match result {
@@ -258,7 +258,6 @@ fn wait_for_query<'tcx, C: QueryCache>(
258258
outline(|| {
259259
// We didn't find the query result in the query cache. Check if it was
260260
// poisoned due to a panic instead.
261-
let key_hash = sharded::make_hash(&key);
262261
let shard = query.state.active.lock_shard_by_hash(key_hash);
263262
match shard.find(key_hash, equivalent_key(key)) {
264263
// The query we waited on panicked. Continue unwinding here.
@@ -311,16 +310,37 @@ fn try_execute_query<'tcx, C: QueryCache, const INCR: bool>(
311310

312311
match state_lock.entry(key_hash, equivalent_key(key), |(k, _)| sharded::make_hash(k)) {
313312
Entry::Vacant(entry) => {
314-
// Nothing has computed or is computing the query, so we start a new job and insert it in the
315-
// state map.
313+
// Nothing has computed or is computing the query, so we start a new job and insert it
314+
// in the state map.
316315
let id = next_job_id(tcx);
317316
let job = QueryJob::new(id, span, current_job_id);
318317
entry.insert((key, ActiveKeyStatus::Started(job)));
319318

320-
// Drop the lock before we start executing the query
319+
// Drop the lock before we start executing the query.
321320
drop(state_lock);
322321

323-
execute_job::<C, INCR>(query, tcx, key, key_hash, id, dep_node)
322+
// Set up a guard object that will automatically poison the query if a
323+
// panic occurs while executing the query (or any intermediate plumbing).
324+
let job_guard = ActiveJobGuard { state: &query.state, key, key_hash };
325+
326+
debug_assert_eq!(tcx.dep_graph.is_fully_enabled(), INCR);
327+
328+
// Delegate to another function to actually execute the query job.
329+
let (value, dep_node_index) = if INCR {
330+
execute_job_incr(query, tcx, key, dep_node, id)
331+
} else {
332+
execute_job_non_incr(query, tcx, key, id)
333+
};
334+
335+
if query.feedable {
336+
check_feedable_consistency(tcx, query, key, &value);
337+
}
338+
339+
// Tell the guard to insert `value` in the cache and remove the status entry from
340+
// `query.state`.
341+
job_guard.complete(&query.cache, value, dep_node_index);
342+
343+
(value, Some(dep_node_index))
324344
}
325345
Entry::Occupied(mut entry) => {
326346
match &mut entry.get_mut().1 {
@@ -332,7 +352,7 @@ fn try_execute_query<'tcx, C: QueryCache, const INCR: bool>(
332352

333353
// Only call `wait_for_query` if we're using a Rayon thread pool
334354
// as it will attempt to mark the worker thread as blocked.
335-
wait_for_query(query, tcx, span, key, latch, current_job_id)
355+
wait_for_query(query, tcx, span, key, key_hash, latch, current_job_id)
336356
} else {
337357
let id = job.id;
338358
drop(state_lock);
@@ -349,67 +369,44 @@ fn try_execute_query<'tcx, C: QueryCache, const INCR: bool>(
349369
}
350370

351371
#[inline(always)]
352-
fn execute_job<'tcx, C: QueryCache, const INCR: bool>(
353-
query: &'tcx QueryVTable<'tcx, C>,
372+
fn check_feedable_consistency<'tcx, C: QueryCache>(
354373
tcx: TyCtxt<'tcx>,
374+
query: &'tcx QueryVTable<'tcx, C>,
355375
key: C::Key,
356-
key_hash: u64,
357-
id: QueryJobId,
358-
dep_node: Option<DepNode>,
359-
) -> (C::Value, Option<DepNodeIndex>) {
360-
// Set up a guard object that will automatically poison the query if a
361-
// panic occurs while executing the query (or any intermediate plumbing).
362-
let job_guard = ActiveJobGuard { state: &query.state, key, key_hash };
363-
364-
debug_assert_eq!(tcx.dep_graph.is_fully_enabled(), INCR);
365-
366-
// Delegate to another function to actually execute the query job.
367-
let (value, dep_node_index) = if INCR {
368-
execute_job_incr(query, tcx, key, dep_node, id)
369-
} else {
370-
execute_job_non_incr(query, tcx, key, id)
376+
value: &C::Value,
377+
) {
378+
// We should not compute queries that also got a value via feeding.
379+
// This can't happen, as query feeding adds the very dependencies to the fed query
380+
// as its feeding query had. So if the fed query is red, so is its feeder, which will
381+
// get evaluated first, and re-feed the query.
382+
let Some((cached_value, _)) = query.cache.lookup(&key) else { return };
383+
384+
let Some(hash_value_fn) = query.hash_value_fn else {
385+
panic!(
386+
"no_hash fed query later has its value computed.\n\
387+
Remove `no_hash` modifier to allow recomputation.\n\
388+
The already cached value: {}",
389+
(query.format_value)(&cached_value)
390+
);
371391
};
372392

373-
let cache = &query.cache;
374-
if query.feedable {
375-
// We should not compute queries that also got a value via feeding.
376-
// This can't happen, as query feeding adds the very dependencies to the fed query
377-
// as its feeding query had. So if the fed query is red, so is its feeder, which will
378-
// get evaluated first, and re-feed the query.
379-
if let Some((cached_value, _)) = cache.lookup(&key) {
380-
let Some(hash_value_fn) = query.hash_value_fn else {
381-
panic!(
382-
"no_hash fed query later has its value computed.\n\
383-
Remove `no_hash` modifier to allow recomputation.\n\
384-
The already cached value: {}",
385-
(query.format_value)(&cached_value)
386-
);
387-
};
388-
389-
let (old_hash, new_hash) = tcx.with_stable_hashing_context(|mut hcx| {
390-
(hash_value_fn(&mut hcx, &cached_value), hash_value_fn(&mut hcx, &value))
391-
});
392-
let formatter = query.format_value;
393-
if old_hash != new_hash {
394-
// We have an inconsistency. This can happen if one of the two
395-
// results is tainted by errors.
396-
assert!(
397-
tcx.dcx().has_errors().is_some(),
398-
"Computed query value for {:?}({:?}) is inconsistent with fed value,\n\
399-
computed={:#?}\nfed={:#?}",
400-
query.dep_kind,
401-
key,
402-
formatter(&value),
403-
formatter(&cached_value),
404-
);
405-
}
406-
}
393+
let (old_hash, new_hash) = tcx.with_stable_hashing_context(|mut hcx| {
394+
(hash_value_fn(&mut hcx, &cached_value), hash_value_fn(&mut hcx, value))
395+
});
396+
let formatter = query.format_value;
397+
if old_hash != new_hash {
398+
// We have an inconsistency. This can happen if one of the two
399+
// results is tainted by errors.
400+
assert!(
401+
tcx.dcx().has_errors().is_some(),
402+
"Computed query value for {:?}({:?}) is inconsistent with fed value,\n\
403+
computed={:#?}\nfed={:#?}",
404+
query.dep_kind,
405+
key,
406+
formatter(value),
407+
formatter(&cached_value),
408+
);
407409
}
408-
409-
// Tell the guard to perform completion bookkeeping, and also to not poison the query.
410-
job_guard.complete(cache, value, dep_node_index);
411-
412-
(value, Some(dep_node_index))
413410
}
414411

415412
// Fast path for when incr. comp. is off.

0 commit comments

Comments
 (0)