use rustc::dep_graph::{DepGraphQuery, DepNode};
use rustc::hir::def_id::DefId;
+use rustc::ich::Fingerprint;
use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::graph::Graph;
+use rustc_data_structures::graph::{Graph, NodeIndex};
use super::hash::*;
-use ich::Fingerprint;
mod compress;
// of the graph down.
pub reduced_graph: Graph<&'query DepNode<DefId>, ()>,
+ // These are output nodes that have no incoming edges. We have to
+ // track these specially because, when we load the data back up
+ // again, we want to make sure and recreate these nodes (we want
+ // to recreate the nodes where all incoming edges are clean; but
+ // since we ordinarily just serialize edges, we wind up just
+ // forgetting that bootstrap outputs even exist in that case.)
+ pub bootstrap_outputs: Vec<&'query DepNode<DefId>>,
+
// For the inputs (hir/foreign-metadata), we include hashes.
pub hashes: FxHashMap<&'query DepNode<DefId>, Fingerprint>,
}
pub fn new(query: &'q DepGraphQuery<DefId>, hcx: &mut HashContext) -> Self {
let tcx = hcx.tcx;
- let collect_for_metadata = tcx.sess.opts.debugging_opts.incremental_cc ||
- tcx.sess.opts.debugging_opts.query_dep_graph;
-
// Find the set of "start nodes". These are nodes that we will
// possibly query later.
let is_output = |node: &DepNode<DefId>| -> bool {
match *node {
DepNode::WorkProduct(_) => true,
- DepNode::MetaData(ref def_id) => collect_for_metadata && def_id.is_local(),
-
+ DepNode::MetaData(ref def_id) => {
+ // We do *not* create dep-nodes for the current crate's
+ // metadata anymore, just for metadata that we import/read
+ // from other crates.
+ debug_assert!(!def_id.is_local());
+ false
+ }
// if -Z query-dep-graph is passed, save more extended data
// to enable better unit testing
DepNode::TypeckTables(_) |
// Reduce the graph to the most important nodes.
let compress::Reduction { graph, input_nodes } =
- compress::reduce_graph(&query.graph, HashContext::is_hashable, is_output);
+ compress::reduce_graph(&query.graph, HashContext::is_hashable, |n| is_output(n));
let mut hashes = FxHashMap();
for input_index in input_nodes {
.or_insert_with(|| hcx.hash(input).unwrap());
}
+ if tcx.sess.opts.debugging_opts.query_dep_graph {
+ // Not all inputs might have been reachable from an output node,
+ // but we still want their hash for our unit tests.
+ let hir_nodes = query.graph.all_nodes().iter().filter_map(|node| {
+ match node.data {
+ DepNode::Hir(_) => Some(&node.data),
+ _ => None,
+ }
+ });
+
+ for node in hir_nodes {
+ hashes.entry(node)
+ .or_insert_with(|| hcx.hash(node).unwrap());
+ }
+ }
+
+ let bootstrap_outputs: Vec<&'q DepNode<DefId>> =
+ (0 .. graph.len_nodes())
+ .map(NodeIndex)
+ .filter(|&n| graph.incoming_edges(n).next().is_none())
+ .map(|n| *graph.node_data(n))
+ .filter(|n| is_output(n))
+ .collect();
+
Predecessors {
reduced_graph: graph,
+ bootstrap_outputs: bootstrap_outputs,
hashes: hashes,
}
}