Skip to content

Commit cb75345

Browse files
committed
Auto merge of #57770 - Zoxc:no-hash-query, r=<try>
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 e730697 + ffee835 commit cb75345

File tree

8 files changed

+104
-59
lines changed

8 files changed

+104
-59
lines changed

src/librustc/dep_graph/graph.rs

+54-35
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,16 @@ struct DepGraphData {
7272
loaded_from_cache: Lock<FxHashMap<DepNodeIndex, bool>>,
7373
}
7474

75+
pub fn hash_result<R>(hcx: &mut StableHashingContext<'_>, result: &R) -> Option<Fingerprint>
76+
where
77+
R: for<'a> HashStable<StableHashingContext<'a>>,
78+
{
79+
let mut stable_hasher = StableHasher::new();
80+
result.hash_stable(hcx, &mut stable_hasher);
81+
82+
Some(stable_hasher.finish())
83+
}
84+
7585
impl DepGraph {
7686

7787
pub fn new(prev_graph: PreviousDepGraph,
@@ -169,14 +179,16 @@ impl DepGraph {
169179
/// `arg` parameter.
170180
///
171181
/// [rustc guide]: https://rust-lang.github.io/rustc-guide/incremental-compilation.html
172-
pub fn with_task<'gcx, C, A, R>(&self,
173-
key: DepNode,
174-
cx: C,
175-
arg: A,
176-
task: fn(C, A) -> R)
177-
-> (R, DepNodeIndex)
178-
where C: DepGraphSafe + StableHashingContextProvider<'gcx>,
179-
R: HashStable<StableHashingContext<'gcx>>,
182+
pub fn with_task<'a, C, A, R>(
183+
&self,
184+
key: DepNode,
185+
cx: C,
186+
arg: A,
187+
task: fn(C, A) -> R,
188+
hash_result: impl FnOnce(&mut StableHashingContext<'_>, &R) -> Option<Fingerprint>,
189+
) -> (R, DepNodeIndex)
190+
where
191+
C: DepGraphSafe + StableHashingContextProvider<'a>,
180192
{
181193
self.with_task_impl(key, cx, arg, false, task,
182194
|_key| Some(TaskDeps {
@@ -187,17 +199,18 @@ impl DepGraph {
187199
}),
188200
|data, key, fingerprint, task| {
189201
data.borrow_mut().complete_task(key, task.unwrap(), fingerprint)
190-
})
202+
},
203+
hash_result)
191204
}
192205

193206
/// Creates a new dep-graph input with value `input`
194-
pub fn input_task<'gcx, C, R>(&self,
207+
pub fn input_task<'a, C, R>(&self,
195208
key: DepNode,
196209
cx: C,
197210
input: R)
198211
-> (R, DepNodeIndex)
199-
where C: DepGraphSafe + StableHashingContextProvider<'gcx>,
200-
R: HashStable<StableHashingContext<'gcx>>,
212+
where C: DepGraphSafe + StableHashingContextProvider<'a>,
213+
R: for<'b> HashStable<StableHashingContext<'b>>,
201214
{
202215
fn identity_fn<C, A>(_: C, arg: A) -> A {
203216
arg
@@ -207,10 +220,11 @@ impl DepGraph {
207220
|_| None,
208221
|data, key, fingerprint, _| {
209222
data.borrow_mut().alloc_node(key, SmallVec::new(), fingerprint)
210-
})
223+
},
224+
hash_result::<R>)
211225
}
212226

213-
fn with_task_impl<'gcx, C, A, R>(
227+
fn with_task_impl<'a, C, A, R>(
214228
&self,
215229
key: DepNode,
216230
cx: C,
@@ -221,11 +235,11 @@ impl DepGraph {
221235
finish_task_and_alloc_depnode: fn(&Lock<CurrentDepGraph>,
222236
DepNode,
223237
Fingerprint,
224-
Option<TaskDeps>) -> DepNodeIndex
238+
Option<TaskDeps>) -> DepNodeIndex,
239+
hash_result: impl FnOnce(&mut StableHashingContext<'_>, &R) -> Option<Fingerprint>,
225240
) -> (R, DepNodeIndex)
226241
where
227-
C: DepGraphSafe + StableHashingContextProvider<'gcx>,
228-
R: HashStable<StableHashingContext<'gcx>>,
242+
C: DepGraphSafe + StableHashingContextProvider<'a>,
229243
{
230244
if let Some(ref data) = self.data {
231245
let task_deps = create_task(key).map(|deps| Lock::new(deps));
@@ -260,31 +274,33 @@ impl DepGraph {
260274
profq_msg(hcx.sess(), ProfileQueriesMsg::TaskEnd)
261275
};
262276

263-
let mut stable_hasher = StableHasher::new();
264-
result.hash_stable(&mut hcx, &mut stable_hasher);
265-
266-
let current_fingerprint = stable_hasher.finish();
277+
let current_fingerprint = hash_result(&mut hcx, &result);
267278

268279
let dep_node_index = finish_task_and_alloc_depnode(
269280
&data.current,
270281
key,
271-
current_fingerprint,
282+
current_fingerprint.unwrap_or(Fingerprint::ZERO),
272283
task_deps.map(|lock| lock.into_inner()),
273284
);
274285

275286
// Determine the color of the new DepNode.
276287
if let Some(prev_index) = data.previous.node_to_index_opt(&key) {
277288
let prev_fingerprint = data.previous.fingerprint_by_index(prev_index);
278289

279-
let color = if current_fingerprint == prev_fingerprint {
280-
DepNodeColor::Green(dep_node_index)
290+
let color = if let Some(current_fingerprint) = current_fingerprint {
291+
if current_fingerprint == prev_fingerprint {
292+
DepNodeColor::Green(dep_node_index)
293+
} else {
294+
DepNodeColor::Red
295+
}
281296
} else {
297+
// Mark the node as Red if we can't hash the result
282298
DepNodeColor::Red
283299
};
284300

285301
debug_assert!(data.colors.get(prev_index).is_none(),
286-
"DepGraph::with_task() - Duplicate DepNodeColor \
287-
insertion for {:?}", key);
302+
"DepGraph::with_task() - Duplicate DepNodeColor \
303+
insertion for {:?}", key);
288304

289305
data.colors.insert(prev_index, color);
290306
}
@@ -333,14 +349,16 @@ impl DepGraph {
333349

334350
/// Execute something within an "eval-always" task which is a task
335351
// that runs whenever anything changes.
336-
pub fn with_eval_always_task<'gcx, C, A, R>(&self,
337-
key: DepNode,
338-
cx: C,
339-
arg: A,
340-
task: fn(C, A) -> R)
341-
-> (R, DepNodeIndex)
342-
where C: DepGraphSafe + StableHashingContextProvider<'gcx>,
343-
R: HashStable<StableHashingContext<'gcx>>,
352+
pub fn with_eval_always_task<'a, C, A, R>(
353+
&self,
354+
key: DepNode,
355+
cx: C,
356+
arg: A,
357+
task: fn(C, A) -> R,
358+
hash_result: impl FnOnce(&mut StableHashingContext<'_>, &R) -> Option<Fingerprint>,
359+
) -> (R, DepNodeIndex)
360+
where
361+
C: DepGraphSafe + StableHashingContextProvider<'a>,
344362
{
345363
self.with_task_impl(key, cx, arg, false, task,
346364
|_| None,
@@ -350,7 +368,8 @@ impl DepGraph {
350368
&DepNode::new_no_params(DepKind::Krate)
351369
];
352370
current.alloc_node(key, smallvec![krate_idx], fingerprint)
353-
})
371+
},
372+
hash_result)
354373
}
355374

356375
#[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
@@ -45,14 +45,14 @@ pub(super) struct NodeCollector<'a, 'hir> {
4545
hir_body_nodes: Vec<(DefPathHash, Fingerprint)>,
4646
}
4747

48-
fn input_dep_node_and_hash<'a, I>(
48+
fn input_dep_node_and_hash<I>(
4949
dep_graph: &DepGraph,
50-
hcx: &mut StableHashingContext<'a>,
50+
hcx: &mut StableHashingContext<'_>,
5151
dep_node: DepNode,
5252
input: I,
5353
) -> (DepNodeIndex, Fingerprint)
5454
where
55-
I: HashStable<StableHashingContext<'a>>,
55+
I: for<'a> HashStable<StableHashingContext<'a>>,
5656
{
5757
let dep_node_index = dep_graph.input_task(dep_node, &mut *hcx, &input).1;
5858

@@ -67,15 +67,15 @@ where
6767
(dep_node_index, hash)
6868
}
6969

70-
fn alloc_hir_dep_nodes<'a, I>(
70+
fn alloc_hir_dep_nodes<I>(
7171
dep_graph: &DepGraph,
72-
hcx: &mut StableHashingContext<'a>,
72+
hcx: &mut StableHashingContext<'_>,
7373
def_path_hash: DefPathHash,
7474
item_like: I,
7575
hir_body_nodes: &mut Vec<(DefPathHash, Fingerprint)>,
7676
) -> (DepNodeIndex, DepNodeIndex)
7777
where
78-
I: HashStable<StableHashingContext<'a>>,
78+
I: for<'a> HashStable<StableHashingContext<'a>>,
7979
{
8080
let sig = dep_graph.input_task(
8181
def_path_hash.to_dep_node(DepKind::Hir),
@@ -280,7 +280,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
280280
self.parent_node = parent_node;
281281
}
282282

283-
fn with_dep_node_owner<T: HashStable<StableHashingContext<'a>>,
283+
fn with_dep_node_owner<T: for<'b> HashStable<StableHashingContext<'b>>,
284284
F: FnOnce(&mut Self)>(&mut self,
285285
dep_node_owner: DefIndex,
286286
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 dep_graph::DepGraph;
4-
use dep_graph::{DepNode, DepConstructor};
4+
use dep_graph::{self, DepNode, DepConstructor};
55
use errors::DiagnosticBuilder;
66
use session::Session;
77
use session::config::{BorrowckMode, OutputFilenames};
@@ -1414,7 +1414,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
14141414
self.dep_graph.with_task(dep_node,
14151415
self,
14161416
crate_hash,
1417-
|_, x| x // No transformation needed
1417+
|_, x| x, // No transformation needed
1418+
dep_graph::hash_result,
14181419
);
14191420
}
14201421
}

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 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

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use dep_graph::{DepConstructor, DepNode};
1+
use dep_graph::{self, DepConstructor, DepNode};
22
use errors::DiagnosticBuilder;
33
use hir::def_id::{CrateNum, DefId, DefIndex};
44
use 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;
@@ -227,15 +228,15 @@ define_queries! { <'tcx>
227228

228229
/// Fetch the MIR for a given def-id right after it's built - this includes
229230
/// unreachable code.
230-
[] fn mir_built: MirBuilt(DefId) -> &'tcx Steal<mir::Mir<'tcx>>,
231+
[no_hash] fn mir_built: MirBuilt(DefId) -> &'tcx Steal<mir::Mir<'tcx>>,
231232

232233
/// Fetch the MIR for a given def-id up till the point where it is
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 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<'ll, 'tcx>(tcx: TyCtxt<'ll, '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)