Skip to content

Commit f89041b

Browse files
committed
identify inputs of MetaData(X) nodes
Generate a second hash file that contains the metadata for an X node.
1 parent bc02a54 commit f89041b

File tree

10 files changed

+221
-83
lines changed

10 files changed

+221
-83
lines changed

src/librustc/cfg/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ impl CFG {
6464
}
6565

6666
pub fn node_is_reachable(&self, id: ast::NodeId) -> bool {
67-
self.graph.depth_traverse(self.entry)
67+
self.graph.depth_traverse(self.entry, graph::OUTGOING)
6868
.any(|idx| self.graph.node_data(idx).id() == id)
6969
}
7070
}

src/librustc/dep_graph/query.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// except according to those terms.
1010

1111
use rustc_data_structures::fnv::FnvHashMap;
12-
use rustc_data_structures::graph::{Graph, NodeIndex};
12+
use rustc_data_structures::graph::{Direction, INCOMING, Graph, NodeIndex, OUTGOING};
1313
use std::fmt::Debug;
1414
use std::hash::Hash;
1515

@@ -63,20 +63,29 @@ impl<D: Clone + Debug + Hash + Eq> DepGraphQuery<D> {
6363
.collect()
6464
}
6565

66-
/// All nodes reachable from `node`. In other words, things that
67-
/// will have to be recomputed if `node` changes.
68-
pub fn transitive_dependents(&self, node: DepNode<D>) -> Vec<DepNode<D>> {
66+
fn reachable_nodes(&self, node: DepNode<D>, direction: Direction) -> Vec<DepNode<D>> {
6967
if let Some(&index) = self.indices.get(&node) {
70-
self.graph.depth_traverse(index)
68+
self.graph.depth_traverse(index, direction)
7169
.map(|s| self.graph.node_data(s).clone())
7270
.collect()
7371
} else {
7472
vec![]
7573
}
7674
}
7775

76+
/// All nodes reachable from `node`. In other words, things that
77+
/// will have to be recomputed if `node` changes.
78+
pub fn transitive_successors(&self, node: DepNode<D>) -> Vec<DepNode<D>> {
79+
self.reachable_nodes(node, OUTGOING)
80+
}
81+
82+
/// All nodes that can reach `node`.
83+
pub fn transitive_predecessors(&self, node: DepNode<D>) -> Vec<DepNode<D>> {
84+
self.reachable_nodes(node, INCOMING)
85+
}
86+
7887
/// Just the outgoing edges from `node`.
79-
pub fn immediate_dependents(&self, node: DepNode<D>) -> Vec<DepNode<D>> {
88+
pub fn immediate_successors(&self, node: DepNode<D>) -> Vec<DepNode<D>> {
8089
if let Some(&index) = self.indices.get(&node) {
8190
self.graph.successor_nodes(index)
8291
.map(|s| self.graph.node_data(s).clone())

src/librustc/infer/region_inference/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub use self::VarValue::*;
2020
use super::{RegionVariableOrigin, SubregionOrigin, MiscVariable};
2121
use super::unify_key;
2222

23-
use rustc_data_structures::graph::{self, Direction, NodeIndex};
23+
use rustc_data_structures::graph::{self, Direction, NodeIndex, OUTGOING};
2424
use rustc_data_structures::unify::{self, UnificationTable};
2525
use middle::free_region::FreeRegionMap;
2626
use ty::{self, Ty, TyCtxt};
@@ -872,7 +872,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
872872
let seeds: Vec<_> = givens.iter().cloned().collect();
873873
for (fr, vid) in seeds {
874874
let seed_index = NodeIndex(vid.index as usize);
875-
for succ_index in graph.depth_traverse(seed_index) {
875+
for succ_index in graph.depth_traverse(seed_index, OUTGOING) {
876876
let succ_index = succ_index.0 as u32;
877877
if succ_index < self.num_vars() {
878878
let succ_vid = RegionVid { index: succ_index };

src/librustc_data_structures/graph/mod.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -292,11 +292,15 @@ impl<N: Debug, E: Debug> Graph<N, E> {
292292
}
293293
}
294294

295-
pub fn depth_traverse<'a>(&'a self, start: NodeIndex) -> DepthFirstTraversal<'a, N, E> {
295+
pub fn depth_traverse<'a>(&'a self,
296+
start: NodeIndex,
297+
direction: Direction)
298+
-> DepthFirstTraversal<'a, N, E> {
296299
DepthFirstTraversal {
297300
graph: self,
298301
stack: vec![start],
299302
visited: BitVector::new(self.nodes.len()),
303+
direction: direction,
300304
}
301305
}
302306
}
@@ -371,6 +375,7 @@ pub struct DepthFirstTraversal<'g, N: 'g, E: 'g> {
371375
graph: &'g Graph<N, E>,
372376
stack: Vec<NodeIndex>,
373377
visited: BitVector,
378+
direction: Direction,
374379
}
375380

376381
impl<'g, N: Debug, E: Debug> Iterator for DepthFirstTraversal<'g, N, E> {
@@ -382,9 +387,10 @@ impl<'g, N: Debug, E: Debug> Iterator for DepthFirstTraversal<'g, N, E> {
382387
continue;
383388
}
384389

385-
for (_, edge) in self.graph.outgoing_edges(idx) {
386-
if !self.visited.contains(edge.target().node_id()) {
387-
self.stack.push(edge.target());
390+
for (_, edge) in self.graph.adjacent_edges(idx, self.direction) {
391+
let target = edge.source_or_target(self.direction);
392+
if !self.visited.contains(target.node_id()) {
393+
self.stack.push(target);
388394
}
389395
}
390396

src/librustc_incremental/assert_dep_graph.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ fn check_paths<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
195195
};
196196

197197
for &(_, source_def_id, source_dep_node) in sources {
198-
let dependents = query.transitive_dependents(source_dep_node);
198+
let dependents = query.transitive_successors(source_dep_node);
199199
for &(target_span, ref target_pass, _, ref target_dep_node) in targets {
200200
if !dependents.contains(&target_dep_node) {
201201
tcx.sess.span_err(

src/librustc_incremental/persist/data.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,50 @@ use rustc::dep_graph::DepNode;
1414

1515
use super::directory::DefPathIndex;
1616

17+
/// Data for use when recompiling the **current crate**.
1718
#[derive(Debug, RustcEncodable, RustcDecodable)]
1819
pub struct SerializedDepGraph {
1920
pub nodes: Vec<DepNode<DefPathIndex>>,
2021
pub edges: Vec<SerializedEdge>,
22+
23+
/// These are hashes of two things:
24+
/// - the HIR nodes in this crate
25+
/// - the metadata nodes from dependent crates we use
26+
///
27+
/// In each case, we store a hash summarizing the contents of
28+
/// those items as they were at the time we did this compilation.
29+
/// In the case of HIR nodes, this hash is derived by walking the
30+
/// HIR itself. In the case of metadata nodes, the hash is loaded
31+
/// from saved state.
32+
///
33+
/// When we do the next compile, we will load these back up and
34+
/// compare them against the hashes we see at that time, which
35+
/// will tell us what has changed, either in this crate or in some
36+
/// crate that we depend on.
37+
pub hashes: Vec<SerializedHash>,
38+
}
39+
40+
/// Data for use when downstream crates get recompiled.
41+
#[derive(Debug, RustcEncodable, RustcDecodable)]
42+
pub struct SerializedMetadataHashes {
43+
/// For each def-id defined in this crate that appears in the
44+
/// metadata, we hash all the inputs that were used when producing
45+
/// the metadata. We save this after compilation is done. Then,
46+
/// when some downstream crate is being recompiled, it can compare
47+
/// the hashes we saved against the hashes that it saw from
48+
/// before; this will tell it which of the items in this crate
49+
/// changed, which in turn implies what items in the downstream
50+
/// crate need to be recompiled.
2151
pub hashes: Vec<SerializedHash>,
2252
}
2353

2454
pub type SerializedEdge = (DepNode<DefPathIndex>, DepNode<DefPathIndex>);
2555

2656
#[derive(Debug, RustcEncodable, RustcDecodable)]
2757
pub struct SerializedHash {
28-
pub index: DefPathIndex,
58+
/// node being hashed; either a Hir or MetaData variant, in
59+
/// practice
60+
pub node: DepNode<DefPathIndex>,
2961

3062
/// the hash itself, computed by `calculate_item_hash`
3163
pub hash: u64,

src/librustc_incremental/persist/load.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
//! Code to save/load the dep-graph from files.
1212
13-
use calculate_svh::SvhCalculate;
1413
use rbml::Error;
1514
use rbml::opaque::Decoder;
1615
use rustc::dep_graph::DepNode;
@@ -131,20 +130,20 @@ pub fn decode_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
131130
}
132131

133132
fn initial_dirty_nodes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
134-
hashed_items: &[SerializedHash],
133+
hashes: &[SerializedHash],
135134
retraced: &RetracedDefIdDirectory)
136135
-> DirtyNodes {
137136
let mut items_removed = false;
138137
let mut dirty_nodes = FnvHashSet();
139-
for hashed_item in hashed_items {
140-
match retraced.def_id(hashed_item.index) {
141-
Some(def_id) => {
138+
for hash in hashes {
139+
match hash.node.map_def(|&i| retraced.def_id(i)) {
140+
Some(dep_node) => {
142141
// FIXME(#32753) -- should we use a distinct hash here
143-
let current_hash = tcx.calculate_item_hash(def_id);
142+
let current_hash = dep_node.hash(tcx).unwrap();
144143
debug!("initial_dirty_nodes: hash of {:?} is {:?}, was {:?}",
145-
def_id, current_hash, hashed_item.hash);
146-
if current_hash != hashed_item.hash {
147-
dirty_nodes.insert(DepNode::Hir(def_id));
144+
dep_node, current_hash, hash.hash);
145+
if current_hash != hash.hash {
146+
dirty_nodes.insert(dep_node);
148147
}
149148
}
150149
None => {

0 commit comments

Comments
 (0)