1
Fork 0

Add a query type which is always marked as red if it runs

This commit is contained in:
John Kåre Alsaker 2019-01-20 05:44:02 +01:00
parent d173180116
commit 34ec9a5942
8 changed files with 106 additions and 61 deletions

View file

@ -79,6 +79,16 @@ struct DepGraphData {
loaded_from_cache: Lock<FxHashMap<DepNodeIndex, bool>>,
}
pub fn hash_result<R>(hcx: &mut StableHashingContext<'_>, result: &R) -> Option<Fingerprint>
where
R: for<'a> HashStable<StableHashingContext<'a>>,
{
let mut stable_hasher = StableHasher::new();
result.hash_stable(hcx, &mut stable_hasher);
Some(stable_hasher.finish())
}
impl DepGraph {
pub fn new(prev_graph: PreviousDepGraph,
@ -178,14 +188,16 @@ impl DepGraph {
/// `arg` parameter.
///
/// [rustc guide]: https://rust-lang.github.io/rustc-guide/incremental-compilation.html
pub fn with_task<'gcx, C, A, R>(&self,
key: DepNode,
cx: C,
arg: A,
task: fn(C, A) -> R)
-> (R, DepNodeIndex)
where C: DepGraphSafe + StableHashingContextProvider<'gcx>,
R: HashStable<StableHashingContext<'gcx>>,
pub fn with_task<'a, C, A, R>(
&self,
key: DepNode,
cx: C,
arg: A,
task: fn(C, A) -> R,
hash_result: impl FnOnce(&mut StableHashingContext<'_>, &R) -> Option<Fingerprint>,
) -> (R, DepNodeIndex)
where
C: DepGraphSafe + StableHashingContextProvider<'a>,
{
self.with_task_impl(key, cx, arg, false, task,
|_key| Some(TaskDeps {
@ -196,17 +208,18 @@ impl DepGraph {
}),
|data, key, fingerprint, task| {
data.borrow_mut().complete_task(key, task.unwrap(), fingerprint)
})
},
hash_result)
}
/// Creates a new dep-graph input with value `input`
pub fn input_task<'gcx, C, R>(&self,
pub fn input_task<'a, C, R>(&self,
key: DepNode,
cx: C,
input: R)
-> (R, DepNodeIndex)
where C: DepGraphSafe + StableHashingContextProvider<'gcx>,
R: HashStable<StableHashingContext<'gcx>>,
where C: DepGraphSafe + StableHashingContextProvider<'a>,
R: for<'b> HashStable<StableHashingContext<'b>>,
{
fn identity_fn<C, A>(_: C, arg: A) -> A {
arg
@ -216,10 +229,11 @@ impl DepGraph {
|_| None,
|data, key, fingerprint, _| {
data.borrow_mut().alloc_node(key, SmallVec::new(), fingerprint)
})
},
hash_result::<R>)
}
fn with_task_impl<'gcx, C, A, R>(
fn with_task_impl<'a, C, A, R>(
&self,
key: DepNode,
cx: C,
@ -230,11 +244,11 @@ impl DepGraph {
finish_task_and_alloc_depnode: fn(&Lock<CurrentDepGraph>,
DepNode,
Fingerprint,
Option<TaskDeps>) -> DepNodeIndex
Option<TaskDeps>) -> DepNodeIndex,
hash_result: impl FnOnce(&mut StableHashingContext<'_>, &R) -> Option<Fingerprint>,
) -> (R, DepNodeIndex)
where
C: DepGraphSafe + StableHashingContextProvider<'gcx>,
R: HashStable<StableHashingContext<'gcx>>,
C: DepGraphSafe + StableHashingContextProvider<'a>,
{
if let Some(ref data) = self.data {
let task_deps = create_task(key).map(|deps| Lock::new(deps));
@ -269,15 +283,12 @@ impl DepGraph {
profq_msg(hcx.sess(), ProfileQueriesMsg::TaskEnd)
};
let mut stable_hasher = StableHasher::new();
result.hash_stable(&mut hcx, &mut stable_hasher);
let current_fingerprint = stable_hasher.finish();
let current_fingerprint = hash_result(&mut hcx, &result);
let dep_node_index = finish_task_and_alloc_depnode(
&data.current,
key,
current_fingerprint,
current_fingerprint.unwrap_or(Fingerprint::ZERO),
task_deps.map(|lock| lock.into_inner()),
);
@ -285,15 +296,20 @@ impl DepGraph {
if let Some(prev_index) = data.previous.node_to_index_opt(&key) {
let prev_fingerprint = data.previous.fingerprint_by_index(prev_index);
let color = if current_fingerprint == prev_fingerprint {
DepNodeColor::Green(dep_node_index)
let color = if let Some(current_fingerprint) = current_fingerprint {
if current_fingerprint == prev_fingerprint {
DepNodeColor::Green(dep_node_index)
} else {
DepNodeColor::Red
}
} else {
// Mark the node as Red if we can't hash the result
DepNodeColor::Red
};
debug_assert!(data.colors.get(prev_index).is_none(),
"DepGraph::with_task() - Duplicate DepNodeColor \
insertion for {:?}", key);
"DepGraph::with_task() - Duplicate DepNodeColor \
insertion for {:?}", key);
data.colors.insert(prev_index, color);
}
@ -342,14 +358,16 @@ impl DepGraph {
/// Execute something within an "eval-always" task which is a task
// that runs whenever anything changes.
pub fn with_eval_always_task<'gcx, C, A, R>(&self,
key: DepNode,
cx: C,
arg: A,
task: fn(C, A) -> R)
-> (R, DepNodeIndex)
where C: DepGraphSafe + StableHashingContextProvider<'gcx>,
R: HashStable<StableHashingContext<'gcx>>,
pub fn with_eval_always_task<'a, C, A, R>(
&self,
key: DepNode,
cx: C,
arg: A,
task: fn(C, A) -> R,
hash_result: impl FnOnce(&mut StableHashingContext<'_>, &R) -> Option<Fingerprint>,
) -> (R, DepNodeIndex)
where
C: DepGraphSafe + StableHashingContextProvider<'a>,
{
self.with_task_impl(key, cx, arg, false, task,
|_| None,
@ -359,7 +377,8 @@ impl DepGraph {
&DepNode::new_no_params(DepKind::Krate)
];
current.alloc_node(key, smallvec![krate_idx], fingerprint)
})
},
hash_result)
}
#[inline]

View file

@ -10,7 +10,7 @@ pub mod cgu_reuse_tracker;
pub use self::dep_tracking_map::{DepTrackingMap, DepTrackingMapConfig};
pub use self::dep_node::{DepNode, DepKind, DepConstructor, WorkProductId, label_strs};
pub use self::graph::{DepGraph, WorkProduct, DepNodeIndex, DepNodeColor, TaskDeps};
pub use self::graph::{DepGraph, WorkProduct, DepNodeIndex, DepNodeColor, TaskDeps, hash_result};
pub use self::graph::WorkProductFileKind;
pub use self::prev::PreviousDepGraph;
pub use self::query::DepGraphQuery;

View file

@ -48,14 +48,14 @@ pub(super) struct NodeCollector<'a, 'hir> {
hir_body_nodes: Vec<(DefPathHash, Fingerprint)>,
}
fn input_dep_node_and_hash<'a, I>(
fn input_dep_node_and_hash<I>(
dep_graph: &DepGraph,
hcx: &mut StableHashingContext<'a>,
hcx: &mut StableHashingContext<'_>,
dep_node: DepNode,
input: I,
) -> (DepNodeIndex, Fingerprint)
where
I: HashStable<StableHashingContext<'a>>,
I: for<'a> HashStable<StableHashingContext<'a>>,
{
let dep_node_index = dep_graph.input_task(dep_node, &mut *hcx, &input).1;
@ -70,15 +70,15 @@ where
(dep_node_index, hash)
}
fn alloc_hir_dep_nodes<'a, I>(
fn alloc_hir_dep_nodes<I>(
dep_graph: &DepGraph,
hcx: &mut StableHashingContext<'a>,
hcx: &mut StableHashingContext<'_>,
def_path_hash: DefPathHash,
item_like: I,
hir_body_nodes: &mut Vec<(DefPathHash, Fingerprint)>,
) -> (DepNodeIndex, DepNodeIndex)
where
I: HashStable<StableHashingContext<'a>>,
I: for<'a> HashStable<StableHashingContext<'a>>,
{
let sig = dep_graph.input_task(
def_path_hash.to_dep_node(DepKind::Hir),
@ -286,7 +286,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
self.parent_node = parent_node;
}
fn with_dep_node_owner<T: HashStable<StableHashingContext<'a>>,
fn with_dep_node_owner<T: for<'b> HashStable<StableHashingContext<'b>>,
F: FnOnce(&mut Self)>(&mut self,
dep_node_owner: DefIndex,
item_like: &T,

View file

@ -1,7 +1,7 @@
//! type context book-keeping
use crate::dep_graph::DepGraph;
use crate::dep_graph::{DepNode, DepConstructor};
use crate::dep_graph::{self, DepNode, DepConstructor};
use crate::errors::DiagnosticBuilder;
use crate::session::Session;
use crate::session::config::{BorrowckMode, OutputFilenames};
@ -1435,7 +1435,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
self.dep_graph.with_task(dep_node,
self,
crate_hash,
|_, x| x // No transformation needed
|_, x| x, // No transformation needed
dep_graph::hash_result,
);
}
}

View file

@ -20,7 +20,7 @@ use std::hash::Hash;
use std::fmt::Debug;
use syntax_pos::symbol::InternedString;
use rustc_data_structures::sync::Lock;
use rustc_data_structures::stable_hasher::HashStable;
use rustc_data_structures::fingerprint::Fingerprint;
use crate::ich::StableHashingContext;
// Query configuration and description traits.
@ -30,7 +30,7 @@ pub trait QueryConfig<'tcx> {
const CATEGORY: ProfileCategory;
type Key: Eq + Hash + Clone + Debug;
type Value: Clone + for<'a> HashStable<StableHashingContext<'a>>;
type Value: Clone;
}
pub(super) trait QueryAccessors<'tcx>: QueryConfig<'tcx> {
@ -44,6 +44,11 @@ pub(super) trait QueryAccessors<'tcx>: QueryConfig<'tcx> {
// Don't use this method to compute query results, instead use the methods on TyCtxt
fn compute(tcx: TyCtxt<'_, 'tcx, '_>, key: Self::Key) -> Self::Value;
fn hash_result(
hcx: &mut StableHashingContext<'_>,
result: &Self::Value
) -> Option<Fingerprint>;
fn handle_cycle_error(tcx: TyCtxt<'_, 'tcx, '_>) -> Self::Value;
}

View file

@ -1,4 +1,4 @@
use crate::dep_graph::{DepConstructor, DepNode};
use crate::dep_graph::{self, DepConstructor, DepNode};
use crate::errors::DiagnosticBuilder;
use crate::hir::def_id::{CrateNum, DefId, DefIndex};
use crate::hir::def::{Def, Export};
@ -49,6 +49,7 @@ use rustc_data_structures::indexed_vec::IndexVec;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::stable_hasher::StableVec;
use rustc_data_structures::sync::Lrc;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_target::spec::PanicStrategy;
use std::borrow::Cow;
@ -227,19 +228,19 @@ define_queries! { <'tcx>
/// Fetch the MIR for a given def-id right after it's built - this includes
/// unreachable code.
[] fn mir_built: MirBuilt(DefId) -> &'tcx Steal<mir::Mir<'tcx>>,
[no_hash] fn mir_built: MirBuilt(DefId) -> &'tcx Steal<mir::Mir<'tcx>>,
/// Fetch the MIR for a given def-id up till the point where it is
/// ready for const evaluation.
///
/// See the README for the `mir` module for details.
[] fn mir_const: MirConst(DefId) -> &'tcx Steal<mir::Mir<'tcx>>,
[no_hash] fn mir_const: MirConst(DefId) -> &'tcx Steal<mir::Mir<'tcx>>,
[] fn mir_validated: MirValidated(DefId) -> &'tcx Steal<mir::Mir<'tcx>>,
[no_hash] fn mir_validated: MirValidated(DefId) -> &'tcx Steal<mir::Mir<'tcx>>,
/// MIR after our optimization passes have run. This is MIR that is ready
/// for codegen. This is also the only query that can fetch non-local MIR, at present.
[] fn optimized_mir: MirOptimized(DefId) -> &'tcx mir::Mir<'tcx>,
[no_hash] fn optimized_mir: MirOptimized(DefId) -> &'tcx mir::Mir<'tcx>,
},
TypeChecking {
@ -282,7 +283,7 @@ define_queries! { <'tcx>
TypeChecking {
[] fn typeck_item_bodies: typeck_item_bodies_dep_node(CrateNum) -> CompileResult,
[] fn typeck_tables_of: TypeckTables(DefId) -> &'tcx ty::TypeckTables<'tcx>,
[no_hash] fn typeck_tables_of: TypeckTables(DefId) -> &'tcx ty::TypeckTables<'tcx>,
},
Other {

View file

@ -499,7 +499,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
dep_node: &DepNode,
dep_node_index: DepNodeIndex,
) {
use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
use crate::ich::Fingerprint;
assert!(Some(self.dep_graph.fingerprint_of(dep_node_index)) ==
@ -509,11 +508,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
debug!("BEGIN verify_ich({:?})", dep_node);
let mut hcx = self.create_stable_hashing_context();
let mut hasher = StableHasher::new();
result.hash_stable(&mut hcx, &mut hasher);
let new_hash: Fingerprint = hasher.finish();
let new_hash = Q::hash_result(&mut hcx, result).unwrap_or(Fingerprint::ZERO);
debug!("END verify_ich({:?})", dep_node);
let old_hash = self.dep_graph.fingerprint_of(dep_node_index);
@ -549,12 +545,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
tcx.dep_graph.with_eval_always_task(dep_node,
tcx,
key,
Q::compute)
Q::compute,
Q::hash_result)
} else {
tcx.dep_graph.with_task(dep_node,
tcx,
key,
Q::compute)
Q::compute,
Q::hash_result)
}
})
});
@ -679,6 +677,18 @@ macro_rules! handle_cycle_error {
};
}
macro_rules! hash_result {
([][$hcx:expr, $result:expr]) => {{
dep_graph::hash_result($hcx, &$result)
}};
([no_hash$(, $modifiers:ident)*][$hcx:expr, $result:expr]) => {{
None
}};
([$other:ident$(, $modifiers:ident)*][$($args:tt)*]) => {
hash_result!([$($modifiers),*][$($args)*])
};
}
macro_rules! define_queries {
(<$tcx:tt> $($category:tt {
$($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident: $node:ident($K:ty) -> $V:ty,)*
@ -966,6 +976,13 @@ macro_rules! define_queries_inner {
})
}
fn hash_result(
_hcx: &mut StableHashingContext<'_>,
_result: &Self::Value
) -> Option<Fingerprint> {
hash_result!([$($modifiers)*][_hcx, _result])
}
fn handle_cycle_error(tcx: TyCtxt<'_, 'tcx, '_>) -> Self::Value {
handle_cycle_error!([$($modifiers)*][tcx])
}

View file

@ -20,6 +20,7 @@ use super::LlvmCodegenBackend;
use llvm;
use metadata;
use rustc::dep_graph;
use rustc::mir::mono::{Linkage, Visibility, Stats};
use rustc::middle::cstore::{EncodedMetadata};
use rustc::ty::TyCtxt;
@ -145,7 +146,8 @@ pub fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let ((stats, module), _) = tcx.dep_graph.with_task(dep_node,
tcx,
cgu_name,
module_codegen);
module_codegen,
dep_graph::hash_result);
let time_to_codegen = start_time.elapsed();
// We assume that the cost to run LLVM on a CGU is proportional to