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