Skip to content

Commit 1bfb441

Browse files
committed
Auto merge of #57770 - Zoxc:no-hash-query, r=michaelwoerister
Add a query type which is always marked as red if it runs This is useful for queries which produce results which are very likely to change if their inputs do. I also expect this to be useful for end to end queries because 1) we don't need `HashStable` impls and 2) we avoid the overhead of hashing the result of large results like the AST or the HIR map. r? @michaelwoerister
2 parents abcfc3b + b4a6f59 commit 1bfb441

26 files changed

+260
-215
lines changed

src/librustc/dep_graph/graph.rs

+54-35
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,16 @@ struct DepGraphData {
7979
loaded_from_cache: Lock<FxHashMap<DepNodeIndex, bool>>,
8080
}
8181

82+
pub fn hash_result<R>(hcx: &mut StableHashingContext<'_>, result: &R) -> Option<Fingerprint>
83+
where
84+
R: for<'a> HashStable<StableHashingContext<'a>>,
85+
{
86+
let mut stable_hasher = StableHasher::new();
87+
result.hash_stable(hcx, &mut stable_hasher);
88+
89+
Some(stable_hasher.finish())
90+
}
91+
8292
impl DepGraph {
8393

8494
pub fn new(prev_graph: PreviousDepGraph,
@@ -178,14 +188,16 @@ impl DepGraph {
178188
/// `arg` parameter.
179189
///
180190
/// [rustc guide]: https://rust-lang.github.io/rustc-guide/incremental-compilation.html
181-
pub fn with_task<'gcx, C, A, R>(&self,
182-
key: DepNode,
183-
cx: C,
184-
arg: A,
185-
task: fn(C, A) -> R)
186-
-> (R, DepNodeIndex)
187-
where C: DepGraphSafe + StableHashingContextProvider<'gcx>,
188-
R: HashStable<StableHashingContext<'gcx>>,
191+
pub fn with_task<'a, C, A, R>(
192+
&self,
193+
key: DepNode,
194+
cx: C,
195+
arg: A,
196+
task: fn(C, A) -> R,
197+
hash_result: impl FnOnce(&mut StableHashingContext<'_>, &R) -> Option<Fingerprint>,
198+
) -> (R, DepNodeIndex)
199+
where
200+
C: DepGraphSafe + StableHashingContextProvider<'a>,
189201
{
190202
self.with_task_impl(key, cx, arg, false, task,
191203
|_key| Some(TaskDeps {
@@ -196,17 +208,18 @@ impl DepGraph {
196208
}),
197209
|data, key, fingerprint, task| {
198210
data.borrow_mut().complete_task(key, task.unwrap(), fingerprint)
199-
})
211+
},
212+
hash_result)
200213
}
201214

202215
/// Creates a new dep-graph input with value `input`
203-
pub fn input_task<'gcx, C, R>(&self,
216+
pub fn input_task<'a, C, R>(&self,
204217
key: DepNode,
205218
cx: C,
206219
input: R)
207220
-> (R, DepNodeIndex)
208-
where C: DepGraphSafe + StableHashingContextProvider<'gcx>,
209-
R: HashStable<StableHashingContext<'gcx>>,
221+
where C: DepGraphSafe + StableHashingContextProvider<'a>,
222+
R: for<'b> HashStable<StableHashingContext<'b>>,
210223
{
211224
fn identity_fn<C, A>(_: C, arg: A) -> A {
212225
arg
@@ -216,10 +229,11 @@ impl DepGraph {
216229
|_| None,
217230
|data, key, fingerprint, _| {
218231
data.borrow_mut().alloc_node(key, SmallVec::new(), fingerprint)
219-
})
232+
},
233+
hash_result::<R>)
220234
}
221235

222-
fn with_task_impl<'gcx, C, A, R>(
236+
fn with_task_impl<'a, C, A, R>(
223237
&self,
224238
key: DepNode,
225239
cx: C,
@@ -230,11 +244,11 @@ impl DepGraph {
230244
finish_task_and_alloc_depnode: fn(&Lock<CurrentDepGraph>,
231245
DepNode,
232246
Fingerprint,
233-
Option<TaskDeps>) -> DepNodeIndex
247+
Option<TaskDeps>) -> DepNodeIndex,
248+
hash_result: impl FnOnce(&mut StableHashingContext<'_>, &R) -> Option<Fingerprint>,
234249
) -> (R, DepNodeIndex)
235250
where
236-
C: DepGraphSafe + StableHashingContextProvider<'gcx>,
237-
R: HashStable<StableHashingContext<'gcx>>,
251+
C: DepGraphSafe + StableHashingContextProvider<'a>,
238252
{
239253
if let Some(ref data) = self.data {
240254
let task_deps = create_task(key).map(|deps| Lock::new(deps));
@@ -269,31 +283,33 @@ impl DepGraph {
269283
profq_msg(hcx.sess(), ProfileQueriesMsg::TaskEnd)
270284
};
271285

272-
let mut stable_hasher = StableHasher::new();
273-
result.hash_stable(&mut hcx, &mut stable_hasher);
274-
275-
let current_fingerprint = stable_hasher.finish();
286+
let current_fingerprint = hash_result(&mut hcx, &result);
276287

277288
let dep_node_index = finish_task_and_alloc_depnode(
278289
&data.current,
279290
key,
280-
current_fingerprint,
291+
current_fingerprint.unwrap_or(Fingerprint::ZERO),
281292
task_deps.map(|lock| lock.into_inner()),
282293
);
283294

284295
// Determine the color of the new DepNode.
285296
if let Some(prev_index) = data.previous.node_to_index_opt(&key) {
286297
let prev_fingerprint = data.previous.fingerprint_by_index(prev_index);
287298

288-
let color = if current_fingerprint == prev_fingerprint {
289-
DepNodeColor::Green(dep_node_index)
299+
let color = if let Some(current_fingerprint) = current_fingerprint {
300+
if current_fingerprint == prev_fingerprint {
301+
DepNodeColor::Green(dep_node_index)
302+
} else {
303+
DepNodeColor::Red
304+
}
290305
} else {
306+
// Mark the node as Red if we can't hash the result
291307
DepNodeColor::Red
292308
};
293309

294310
debug_assert!(data.colors.get(prev_index).is_none(),
295-
"DepGraph::with_task() - Duplicate DepNodeColor \
296-
insertion for {:?}", key);
311+
"DepGraph::with_task() - Duplicate DepNodeColor \
312+
insertion for {:?}", key);
297313

298314
data.colors.insert(prev_index, color);
299315
}
@@ -342,14 +358,16 @@ impl DepGraph {
342358

343359
/// Execute something within an "eval-always" task which is a task
344360
// that runs whenever anything changes.
345-
pub fn with_eval_always_task<'gcx, C, A, R>(&self,
346-
key: DepNode,
347-
cx: C,
348-
arg: A,
349-
task: fn(C, A) -> R)
350-
-> (R, DepNodeIndex)
351-
where C: DepGraphSafe + StableHashingContextProvider<'gcx>,
352-
R: HashStable<StableHashingContext<'gcx>>,
361+
pub fn with_eval_always_task<'a, C, A, R>(
362+
&self,
363+
key: DepNode,
364+
cx: C,
365+
arg: A,
366+
task: fn(C, A) -> R,
367+
hash_result: impl FnOnce(&mut StableHashingContext<'_>, &R) -> Option<Fingerprint>,
368+
) -> (R, DepNodeIndex)
369+
where
370+
C: DepGraphSafe + StableHashingContextProvider<'a>,
353371
{
354372
self.with_task_impl(key, cx, arg, false, task,
355373
|_| None,
@@ -359,7 +377,8 @@ impl DepGraph {
359377
&DepNode::new_no_params(DepKind::Krate)
360378
];
361379
current.alloc_node(key, smallvec![krate_idx], fingerprint)
362-
})
380+
},
381+
hash_result)
363382
}
364383

365384
#[inline]

src/librustc/dep_graph/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ pub mod cgu_reuse_tracker;
1010

1111
pub use self::dep_tracking_map::{DepTrackingMap, DepTrackingMapConfig};
1212
pub use self::dep_node::{DepNode, DepKind, DepConstructor, WorkProductId, label_strs};
13-
pub use self::graph::{DepGraph, WorkProduct, DepNodeIndex, DepNodeColor, TaskDeps};
13+
pub use self::graph::{DepGraph, WorkProduct, DepNodeIndex, DepNodeColor, TaskDeps, hash_result};
1414
pub use self::graph::WorkProductFileKind;
1515
pub use self::prev::PreviousDepGraph;
1616
pub use self::query::DepGraphQuery;

src/librustc/hir/map/collector.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,14 @@ pub(super) struct NodeCollector<'a, 'hir> {
4848
hir_body_nodes: Vec<(DefPathHash, Fingerprint)>,
4949
}
5050

51-
fn input_dep_node_and_hash<'a, I>(
51+
fn input_dep_node_and_hash<I>(
5252
dep_graph: &DepGraph,
53-
hcx: &mut StableHashingContext<'a>,
53+
hcx: &mut StableHashingContext<'_>,
5454
dep_node: DepNode,
5555
input: I,
5656
) -> (DepNodeIndex, Fingerprint)
5757
where
58-
I: HashStable<StableHashingContext<'a>>,
58+
I: for<'a> HashStable<StableHashingContext<'a>>,
5959
{
6060
let dep_node_index = dep_graph.input_task(dep_node, &mut *hcx, &input).1;
6161

@@ -70,15 +70,15 @@ where
7070
(dep_node_index, hash)
7171
}
7272

73-
fn alloc_hir_dep_nodes<'a, I>(
73+
fn alloc_hir_dep_nodes<I>(
7474
dep_graph: &DepGraph,
75-
hcx: &mut StableHashingContext<'a>,
75+
hcx: &mut StableHashingContext<'_>,
7676
def_path_hash: DefPathHash,
7777
item_like: I,
7878
hir_body_nodes: &mut Vec<(DefPathHash, Fingerprint)>,
7979
) -> (DepNodeIndex, DepNodeIndex)
8080
where
81-
I: HashStable<StableHashingContext<'a>>,
81+
I: for<'a> HashStable<StableHashingContext<'a>>,
8282
{
8383
let sig = dep_graph.input_task(
8484
def_path_hash.to_dep_node(DepKind::Hir),
@@ -286,7 +286,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
286286
self.parent_node = parent_node;
287287
}
288288

289-
fn with_dep_node_owner<T: HashStable<StableHashingContext<'a>>,
289+
fn with_dep_node_owner<T: for<'b> HashStable<StableHashingContext<'b>>,
290290
F: FnOnce(&mut Self)>(&mut self,
291291
dep_node_owner: DefIndex,
292292
item_like: &T,

src/librustc/ty/context.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! type context book-keeping
22
33
use crate::dep_graph::DepGraph;
4-
use crate::dep_graph::{DepNode, DepConstructor};
4+
use crate::dep_graph::{self, DepNode, DepConstructor};
55
use crate::errors::DiagnosticBuilder;
66
use crate::session::Session;
77
use crate::session::config::{BorrowckMode, OutputFilenames};
@@ -1430,7 +1430,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
14301430
self.dep_graph.with_task(dep_node,
14311431
self,
14321432
crate_hash,
1433-
|_, x| x // No transformation needed
1433+
|_, x| x, // No transformation needed
1434+
dep_graph::hash_result,
14341435
);
14351436
}
14361437
}

src/librustc/ty/query/config.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use std::hash::Hash;
2020
use std::fmt::Debug;
2121
use syntax_pos::symbol::InternedString;
2222
use rustc_data_structures::sync::Lock;
23-
use rustc_data_structures::stable_hasher::HashStable;
23+
use rustc_data_structures::fingerprint::Fingerprint;
2424
use crate::ich::StableHashingContext;
2525

2626
// Query configuration and description traits.
@@ -30,7 +30,7 @@ pub trait QueryConfig<'tcx> {
3030
const CATEGORY: ProfileCategory;
3131

3232
type Key: Eq + Hash + Clone + Debug;
33-
type Value: Clone + for<'a> HashStable<StableHashingContext<'a>>;
33+
type Value: Clone;
3434
}
3535

3636
pub(super) trait QueryAccessors<'tcx>: QueryConfig<'tcx> {
@@ -44,6 +44,11 @@ pub(super) trait QueryAccessors<'tcx>: QueryConfig<'tcx> {
4444
// Don't use this method to compute query results, instead use the methods on TyCtxt
4545
fn compute(tcx: TyCtxt<'_, 'tcx, '_>, key: Self::Key) -> Self::Value;
4646

47+
fn hash_result(
48+
hcx: &mut StableHashingContext<'_>,
49+
result: &Self::Value
50+
) -> Option<Fingerprint>;
51+
4752
fn handle_cycle_error(tcx: TyCtxt<'_, 'tcx, '_>) -> Self::Value;
4853
}
4954

src/librustc/ty/query/mod.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::dep_graph::{DepConstructor, DepNode};
1+
use crate::dep_graph::{self, DepConstructor, DepNode};
22
use crate::errors::DiagnosticBuilder;
33
use crate::hir::def_id::{CrateNum, DefId, DefIndex};
44
use crate::hir::def::{Def, Export};
@@ -49,6 +49,7 @@ use rustc_data_structures::indexed_vec::IndexVec;
4949
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
5050
use rustc_data_structures::stable_hasher::StableVec;
5151
use rustc_data_structures::sync::Lrc;
52+
use rustc_data_structures::fingerprint::Fingerprint;
5253
use rustc_target::spec::PanicStrategy;
5354

5455
use std::borrow::Cow;
@@ -233,9 +234,9 @@ define_queries! { <'tcx>
233234
/// ready for const evaluation.
234235
///
235236
/// See the README for the `mir` module for details.
236-
[] fn mir_const: MirConst(DefId) -> &'tcx Steal<mir::Mir<'tcx>>,
237+
[no_hash] fn mir_const: MirConst(DefId) -> &'tcx Steal<mir::Mir<'tcx>>,
237238

238-
[] fn mir_validated: MirValidated(DefId) -> &'tcx Steal<mir::Mir<'tcx>>,
239+
[no_hash] fn mir_validated: MirValidated(DefId) -> &'tcx Steal<mir::Mir<'tcx>>,
239240

240241
/// MIR after our optimization passes have run. This is MIR that is ready
241242
/// for codegen. This is also the only query that can fetch non-local MIR, at present.

src/librustc/ty/query/plumbing.rs

+24-7
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
499499
dep_node: &DepNode,
500500
dep_node_index: DepNodeIndex,
501501
) {
502-
use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
503502
use crate::ich::Fingerprint;
504503

505504
assert!(Some(self.dep_graph.fingerprint_of(dep_node_index)) ==
@@ -509,11 +508,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
509508

510509
debug!("BEGIN verify_ich({:?})", dep_node);
511510
let mut hcx = self.create_stable_hashing_context();
512-
let mut hasher = StableHasher::new();
513511

514-
result.hash_stable(&mut hcx, &mut hasher);
515-
516-
let new_hash: Fingerprint = hasher.finish();
512+
let new_hash = Q::hash_result(&mut hcx, result).unwrap_or(Fingerprint::ZERO);
517513
debug!("END verify_ich({:?})", dep_node);
518514

519515
let old_hash = self.dep_graph.fingerprint_of(dep_node_index);
@@ -549,12 +545,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
549545
tcx.dep_graph.with_eval_always_task(dep_node,
550546
tcx,
551547
key,
552-
Q::compute)
548+
Q::compute,
549+
Q::hash_result)
553550
} else {
554551
tcx.dep_graph.with_task(dep_node,
555552
tcx,
556553
key,
557-
Q::compute)
554+
Q::compute,
555+
Q::hash_result)
558556
}
559557
})
560558
});
@@ -679,6 +677,18 @@ macro_rules! handle_cycle_error {
679677
};
680678
}
681679

680+
macro_rules! hash_result {
681+
([][$hcx:expr, $result:expr]) => {{
682+
dep_graph::hash_result($hcx, &$result)
683+
}};
684+
([no_hash$(, $modifiers:ident)*][$hcx:expr, $result:expr]) => {{
685+
None
686+
}};
687+
([$other:ident$(, $modifiers:ident)*][$($args:tt)*]) => {
688+
hash_result!([$($modifiers),*][$($args)*])
689+
};
690+
}
691+
682692
macro_rules! define_queries {
683693
(<$tcx:tt> $($category:tt {
684694
$($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident: $node:ident($K:ty) -> $V:ty,)*
@@ -966,6 +976,13 @@ macro_rules! define_queries_inner {
966976
})
967977
}
968978

979+
fn hash_result(
980+
_hcx: &mut StableHashingContext<'_>,
981+
_result: &Self::Value
982+
) -> Option<Fingerprint> {
983+
hash_result!([$($modifiers)*][_hcx, _result])
984+
}
985+
969986
fn handle_cycle_error(tcx: TyCtxt<'_, 'tcx, '_>) -> Self::Value {
970987
handle_cycle_error!([$($modifiers)*][tcx])
971988
}

src/librustc_codegen_llvm/base.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use super::LlvmCodegenBackend;
2020

2121
use llvm;
2222
use metadata;
23+
use rustc::dep_graph;
2324
use rustc::mir::mono::{Linkage, Visibility, Stats};
2425
use rustc::middle::cstore::{EncodedMetadata};
2526
use rustc::ty::TyCtxt;
@@ -145,7 +146,8 @@ pub fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
145146
let ((stats, module), _) = tcx.dep_graph.with_task(dep_node,
146147
tcx,
147148
cgu_name,
148-
module_codegen);
149+
module_codegen,
150+
dep_graph::hash_result);
149151
let time_to_codegen = start_time.elapsed();
150152

151153
// We assume that the cost to run LLVM on a CGU is proportional to

0 commit comments

Comments
 (0)