提交 a948be81 编写于 作者: M Michael Woerister

incr.comp.: Determine red/green state of every new node.

上级 9ae6ed78
...@@ -59,6 +59,13 @@ impl DepNodeIndex { ...@@ -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 { ...@@ -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 @@ pub fn new(prev_graph: PreviousDepGraph) -> DepGraph { ...@@ -97,6 +106,7 @@ pub fn new(prev_graph: PreviousDepGraph) -> 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 @@ pub fn with_task<C, A, R, HCX>(&self, ...@@ -192,11 +202,23 @@ pub fn with_task<C, A, R, HCX>(&self,
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 @@ pub fn with_anon_task<OP,R>(&self, dep_kind: DepKind, op: OP) -> (R, DepNodeInde ...@@ -228,7 +250,16 @@ pub fn with_anon_task<OP,R>(&self, dep_kind: DepKind, op: OP) -> (R, DepNodeInde
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 @@ pub fn fingerprint_of(&self, dep_node: &DepNode) -> Fingerprint { ...@@ -275,10 +306,22 @@ pub fn fingerprint_of(&self, dep_node: &DepNode) -> Fingerprint {
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 @@ fn push_anon_task(&mut self) { ...@@ -485,7 +528,7 @@ fn push_anon_task(&mut self) {
}); });
} }
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 @@ fn pop_anon_task(&mut self, kind: DepKind) -> DepNodeIndexNew { ...@@ -514,10 +557,10 @@ fn pop_anon_task(&mut self, kind: DepKind) -> DepNodeIndexNew {
}; };
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 @@ pub fn with_edges_from<F>(&self, dep_node: &DepNode, mut f: F) ...@@ -39,8 +39,9 @@ pub fn with_edges_from<F>(&self, dep_node: &DepNode, mut f: F)
.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 @@ fn assert_dirty(&self, item_span: Span, dep_node: DepNode) { ...@@ -122,7 +122,7 @@ fn assert_dirty(&self, item_span: Span, dep_node: DepNode) {
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 @@ fn assert_clean(&self, item_span: Span, dep_node: DepNode) { ...@@ -136,7 +136,7 @@ fn assert_clean(&self, item_span: Span, dep_node: DepNode) {
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,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册