incr.comp.: Determine red/green state of every new node.
This commit is contained in:
parent
9ae6ed78ac
commit
a948be81cd
@ -59,6 +59,13 @@ impl DepNodeIndex {
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum DepNodeColor {
|
||||
Red,
|
||||
Green,
|
||||
Gray
|
||||
}
|
||||
|
||||
struct DepGraphData {
|
||||
/// The old, initial encoding of the dependency graph. This will soon go
|
||||
/// away.
|
||||
@ -74,6 +81,8 @@ struct DepGraphData {
|
||||
/// nodes and edges as well as all fingerprints of nodes that have them.
|
||||
previous: PreviousDepGraph,
|
||||
|
||||
colors: RefCell<FxHashMap<DepNode, DepNodeColor>>,
|
||||
|
||||
/// When we load, there may be `.o` files, cached mir, or other such
|
||||
/// things available to us. If we find that they are not dirty, we
|
||||
/// load the path to the file storing those work-products here into
|
||||
@ -97,6 +106,7 @@ impl DepGraph {
|
||||
dep_node_debug: RefCell::new(FxHashMap()),
|
||||
current: RefCell::new(CurrentDepGraph::new()),
|
||||
previous: prev_graph,
|
||||
colors: RefCell::new(FxHashMap()),
|
||||
})),
|
||||
fingerprints: Rc::new(RefCell::new(FxHashMap())),
|
||||
}
|
||||
@ -192,11 +202,23 @@ impl DepGraph {
|
||||
let mut stable_hasher = StableHasher::new();
|
||||
result.hash_stable(&mut hcx, &mut stable_hasher);
|
||||
|
||||
let current_fingerprint = stable_hasher.finish();
|
||||
|
||||
assert!(self.fingerprints
|
||||
.borrow_mut()
|
||||
.insert(key, stable_hasher.finish())
|
||||
.insert(key, current_fingerprint)
|
||||
.is_none());
|
||||
|
||||
let prev_fingerprint = data.previous.fingerprint_of(&key);
|
||||
|
||||
let color = if Some(current_fingerprint) == prev_fingerprint {
|
||||
DepNodeColor::Green
|
||||
} else {
|
||||
DepNodeColor::Red
|
||||
};
|
||||
|
||||
assert!(data.colors.borrow_mut().insert(key, color).is_none());
|
||||
|
||||
(result, DepNodeIndex {
|
||||
legacy: dep_node_index_legacy,
|
||||
new: dep_node_index_new,
|
||||
@ -228,7 +250,16 @@ impl DepGraph {
|
||||
data.current.borrow_mut().push_anon_task();
|
||||
let result = op();
|
||||
let dep_node_index_legacy = data.edges.borrow_mut().pop_anon_task(dep_kind);
|
||||
let dep_node_index_new = data.current.borrow_mut().pop_anon_task(dep_kind);
|
||||
let (new_dep_node, dep_node_index_new) = data.current
|
||||
.borrow_mut()
|
||||
.pop_anon_task(dep_kind);
|
||||
if let Some(new_dep_node) = new_dep_node {
|
||||
assert!(data.colors
|
||||
.borrow_mut()
|
||||
.insert(new_dep_node, DepNodeColor::Red)
|
||||
.is_none());
|
||||
}
|
||||
|
||||
(result, DepNodeIndex {
|
||||
legacy: dep_node_index_legacy,
|
||||
new: dep_node_index_new,
|
||||
@ -275,10 +306,22 @@ impl DepGraph {
|
||||
self.fingerprints.borrow()[dep_node]
|
||||
}
|
||||
|
||||
pub fn prev_fingerprint_of(&self, dep_node: &DepNode) -> Fingerprint {
|
||||
pub fn prev_fingerprint_of(&self, dep_node: &DepNode) -> Option<Fingerprint> {
|
||||
self.data.as_ref().unwrap().previous.fingerprint_of(dep_node)
|
||||
}
|
||||
|
||||
pub fn node_color(&self, dep_node: &DepNode) -> DepNodeColor {
|
||||
match self.data.as_ref().unwrap().colors.borrow().get(dep_node) {
|
||||
Some(&color) => {
|
||||
debug_assert!(color != DepNodeColor::Gray);
|
||||
color
|
||||
}
|
||||
None => {
|
||||
DepNodeColor::Gray
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Indicates that a previous work product exists for `v`. This is
|
||||
/// invoked during initial start-up based on what nodes are clean
|
||||
/// (and what files exist in the incr. directory).
|
||||
@ -485,7 +528,7 @@ impl CurrentDepGraph {
|
||||
});
|
||||
}
|
||||
|
||||
fn pop_anon_task(&mut self, kind: DepKind) -> DepNodeIndexNew {
|
||||
fn pop_anon_task(&mut self, kind: DepKind) -> (Option<DepNode>, DepNodeIndexNew) {
|
||||
let popped_node = self.task_stack.pop().unwrap();
|
||||
|
||||
if let OpenTask::Anon {
|
||||
@ -514,10 +557,10 @@ impl CurrentDepGraph {
|
||||
};
|
||||
|
||||
if let Some(&index) = self.node_to_node_index.get(&target_dep_node) {
|
||||
return index;
|
||||
(None, index)
|
||||
} else {
|
||||
(Some(target_dep_node), self.alloc_node(target_dep_node, reads))
|
||||
}
|
||||
|
||||
self.alloc_node(target_dep_node, reads)
|
||||
} else {
|
||||
bug!("pop_anon_task() - Expected anonymous task to be popped")
|
||||
}
|
||||
|
@ -39,8 +39,9 @@ impl PreviousDepGraph {
|
||||
.for_each(|&index| f(&self.data.nodes[index]));
|
||||
}
|
||||
|
||||
pub fn fingerprint_of(&self, dep_node: &DepNode) -> Fingerprint {
|
||||
let node_index = self.index[dep_node];
|
||||
self.data.nodes[node_index].1
|
||||
pub fn fingerprint_of(&self, dep_node: &DepNode) -> Option<Fingerprint> {
|
||||
self.index
|
||||
.get(dep_node)
|
||||
.map(|&node_index| self.data.nodes[node_index].1)
|
||||
}
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> {
|
||||
let current_fingerprint = self.tcx.dep_graph.fingerprint_of(&dep_node);
|
||||
let prev_fingerprint = self.tcx.dep_graph.prev_fingerprint_of(&dep_node);
|
||||
|
||||
if current_fingerprint == prev_fingerprint {
|
||||
if Some(current_fingerprint) == prev_fingerprint {
|
||||
let dep_node_str = self.dep_node_str(&dep_node);
|
||||
self.tcx.sess.span_err(
|
||||
item_span,
|
||||
@ -136,7 +136,7 @@ impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> {
|
||||
let current_fingerprint = self.tcx.dep_graph.fingerprint_of(&dep_node);
|
||||
let prev_fingerprint = self.tcx.dep_graph.prev_fingerprint_of(&dep_node);
|
||||
|
||||
if current_fingerprint != prev_fingerprint {
|
||||
if Some(current_fingerprint) != prev_fingerprint {
|
||||
let dep_node_str = self.dep_node_str(&dep_node);
|
||||
self.tcx.sess.span_err(
|
||||
item_span,
|
||||
|
Loading…
Reference in New Issue
Block a user