1 // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 use rustc
::dep_graph
::{DepGraphQuery, DepNode}
;
12 use rustc
::hir
::def_id
::DefId
;
13 use rustc_data_structures
::fnv
::FnvHashMap
;
14 use rustc_data_structures
::graph
::{DepthFirstTraversal, INCOMING, NodeIndex}
;
18 /// A data-structure that makes it easy to enumerate the hashable
19 /// predecessors of any given dep-node.
20 pub struct Predecessors
<'query
> {
21 // - Keys: dep-nodes that may have work-products, output meta-data
23 // - Values: transitive predecessors of the key that are hashable
24 // (e.g., HIR nodes, input meta-data nodes)
25 pub inputs
: FnvHashMap
<&'query DepNode
<DefId
>, Vec
<&'query DepNode
<DefId
>>>,
27 // - Keys: some hashable node
28 // - Values: the hash thereof
29 pub hashes
: FnvHashMap
<&'query DepNode
<DefId
>, u64>,
32 impl<'q
> Predecessors
<'q
> {
33 pub fn new(query
: &'q DepGraphQuery
<DefId
>, hcx
: &mut HashContext
) -> Self {
34 // Find nodes for which we want to know the full set of preds
35 let mut dfs
= DepthFirstTraversal
::new(&query
.graph
, INCOMING
);
36 let all_nodes
= query
.graph
.all_nodes();
39 let inputs
: FnvHashMap
<_
, _
> = all_nodes
.iter()
41 .filter(|&(_
, node
)| match node
.data
{
42 DepNode
::WorkProduct(_
) => true,
43 DepNode
::MetaData(ref def_id
) => def_id
.is_local(),
45 // if -Z query-dep-graph is passed, save more extended data
46 // to enable better unit testing
47 DepNode
::TypeckItemBody(_
) |
48 DepNode
::TransCrateItem(_
) => tcx
.sess
.opts
.debugging_opts
.query_dep_graph
,
52 .map(|(node_index
, node
)| {
53 dfs
.reset(NodeIndex(node_index
));
54 let inputs
: Vec
<_
> = dfs
.by_ref()
55 .map(|i
| &all_nodes
[i
.node_id()].data
)
56 .filter(|d
| HashContext
::is_hashable(d
))
62 let mut hashes
= FnvHashMap();
63 for input
in inputs
.values().flat_map(|v
| v
.iter().cloned()) {
65 .or_insert_with(|| hcx
.hash(input
).unwrap());