Skip to content

Commit c4d1651

Browse files
incr.comp.: Store result fingerprints in DepGraph.
1 parent 25bc69e commit c4d1651

File tree

13 files changed

+235
-74
lines changed

13 files changed

+235
-74
lines changed

src/librustc/dep_graph/dep_node.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,17 @@ impl DefId {
387387
}
388388
}
389389

390+
impl DepKind {
391+
#[inline]
392+
pub fn fingerprint_needed_for_crate_hash(self) -> bool {
393+
match self {
394+
DepKind::HirBody |
395+
DepKind::Krate => true,
396+
_ => false,
397+
}
398+
}
399+
}
400+
390401
define_dep_nodes!( <'tcx>
391402
// Represents the `Krate` as a whole (the `hir::Krate` value) (as
392403
// distinct from the krate module). This is basically a hash of
@@ -401,13 +412,13 @@ define_dep_nodes!( <'tcx>
401412
// edges yourself for the individual items that you read.
402413
[input] Krate,
403414

404-
// Represents the HIR node with the given node-id
405-
[input] Hir(DefId),
406-
407415
// Represents the body of a function or method. The def-id is that of the
408416
// function/method.
409417
[input] HirBody(DefId),
410418

419+
// Represents the HIR node with the given node-id
420+
[input] Hir(DefId),
421+
411422
// Represents metadata from an extern crate.
412423
[input] MetaData(DefId),
413424

src/librustc/dep_graph/graph.rs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ use super::edges::{DepGraphEdges, DepNodeIndex};
2626

2727
#[derive(Clone)]
2828
pub struct DepGraph {
29-
data: Option<Rc<DepGraphData>>
29+
data: Option<Rc<DepGraphData>>,
30+
fingerprints: Rc<RefCell<FxHashMap<DepNode, Fingerprint>>>
3031
}
3132

3233
struct DepGraphData {
@@ -57,7 +58,8 @@ impl DepGraph {
5758
}))
5859
} else {
5960
None
60-
}
61+
},
62+
fingerprints: Rc::new(RefCell::new(FxHashMap())),
6163
}
6264
}
6365

@@ -139,11 +141,27 @@ impl DepGraph {
139141

140142
let mut stable_hasher = StableHasher::new();
141143
result.hash_stable(&mut hcx, &mut stable_hasher);
142-
let _: Fingerprint = stable_hasher.finish();
144+
145+
assert!(self.fingerprints
146+
.borrow_mut()
147+
.insert(key, stable_hasher.finish())
148+
.is_none());
143149

144150
(result, dep_node_index)
145151
} else {
146-
(task(cx, arg), DepNodeIndex::INVALID)
152+
if key.kind.fingerprint_needed_for_crate_hash() {
153+
let mut hcx = cx.create_stable_hashing_context();
154+
let result = task(cx, arg);
155+
let mut stable_hasher = StableHasher::new();
156+
result.hash_stable(&mut hcx, &mut stable_hasher);
157+
assert!(self.fingerprints
158+
.borrow_mut()
159+
.insert(key, stable_hasher.finish())
160+
.is_none());
161+
(result, DepNodeIndex::INVALID)
162+
} else {
163+
(task(cx, arg), DepNodeIndex::INVALID)
164+
}
147165
}
148166
}
149167

@@ -195,6 +213,10 @@ impl DepGraph {
195213
}
196214
}
197215

216+
pub fn fingerprint_of(&self, dep_node: &DepNode) -> Option<Fingerprint> {
217+
self.fingerprints.borrow().get(dep_node).cloned()
218+
}
219+
198220
/// Indicates that a previous work product exists for `v`. This is
199221
/// invoked during initial start-up based on what nodes are clean
200222
/// (and what files exist in the incr. directory).

src/librustc/hir/map/collector.rs

Lines changed: 142 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ use std::iter::repeat;
1616
use syntax::ast::{NodeId, CRATE_NODE_ID};
1717
use syntax_pos::Span;
1818

19+
use ich::StableHashingContext;
20+
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult};
21+
1922
/// A Visitor that walks over the HIR and collects Nodes into a HIR map
2023
pub(super) struct NodeCollector<'a, 'hir> {
2124
/// The crate
@@ -26,36 +29,99 @@ pub(super) struct NodeCollector<'a, 'hir> {
2629
parent_node: NodeId,
2730

2831
current_dep_node_owner: DefIndex,
29-
current_dep_node_index: DepNodeIndex,
32+
current_signature_dep_index: DepNodeIndex,
33+
current_full_dep_index: DepNodeIndex,
34+
currently_in_body: bool,
3035

3136
dep_graph: &'a DepGraph,
3237
definitions: &'a definitions::Definitions,
38+
39+
hcx: StableHashingContext<'a>,
40+
41+
hir_body_nodes: Vec<DefPathHash>,
3342
}
3443

3544
impl<'a, 'hir> NodeCollector<'a, 'hir> {
3645
pub(super) fn root(krate: &'hir Crate,
37-
dep_graph: &'a DepGraph,
38-
definitions: &'a definitions::Definitions)
46+
dep_graph: &'a DepGraph,
47+
definitions: &'a definitions::Definitions,
48+
hcx: StableHashingContext<'a>)
3949
-> NodeCollector<'a, 'hir> {
4050
let root_mod_def_path_hash = definitions.def_path_hash(CRATE_DEF_INDEX);
41-
let root_mod_dep_node = root_mod_def_path_hash.to_dep_node(DepKind::Hir);
42-
let root_mod_dep_node_index = dep_graph.alloc_input_node(root_mod_dep_node);
51+
52+
// Allocate DepNodes for the root module
53+
let (root_mod_sig_dep_index, root_mod_full_dep_index);
54+
{
55+
let Crate {
56+
ref module,
57+
// Crate attributes are not copied over to the root `Mod`, so hash
58+
// them explicitly here.
59+
ref attrs,
60+
span,
61+
62+
// These fields are handled separately:
63+
exported_macros: _,
64+
items: _,
65+
trait_items: _,
66+
impl_items: _,
67+
bodies: _,
68+
trait_impls: _,
69+
trait_default_impl: _,
70+
body_ids: _,
71+
} = *krate;
72+
73+
root_mod_sig_dep_index = dep_graph.with_task(
74+
root_mod_def_path_hash.to_dep_node(DepKind::Hir),
75+
&hcx,
76+
HirItemLike { item_like: (module, attrs, span), hash_bodies: false },
77+
identity_fn
78+
).1;
79+
root_mod_full_dep_index = dep_graph.with_task(
80+
root_mod_def_path_hash.to_dep_node(DepKind::HirBody),
81+
&hcx,
82+
HirItemLike { item_like: (module, attrs, span), hash_bodies: true },
83+
identity_fn
84+
).1;
85+
}
86+
87+
let hir_body_nodes = vec![root_mod_def_path_hash];
4388

4489
let mut collector = NodeCollector {
4590
krate,
4691
map: vec![],
4792
parent_node: CRATE_NODE_ID,
48-
current_dep_node_index: root_mod_dep_node_index,
93+
current_signature_dep_index: root_mod_sig_dep_index,
94+
current_full_dep_index: root_mod_full_dep_index,
4995
current_dep_node_owner: CRATE_DEF_INDEX,
96+
currently_in_body: false,
5097
dep_graph,
5198
definitions,
99+
hcx,
100+
hir_body_nodes,
52101
};
53-
collector.insert_entry(CRATE_NODE_ID, RootCrate(root_mod_dep_node_index));
102+
collector.insert_entry(CRATE_NODE_ID, RootCrate(root_mod_sig_dep_index));
54103

55104
collector
56105
}
57106

58-
pub(super) fn into_map(self) -> Vec<MapEntry<'hir>> {
107+
pub(super) fn finalize_and_compute_crate_hash(self,
108+
crate_disambiguator: &str)
109+
-> Vec<MapEntry<'hir>> {
110+
let mut node_hashes: Vec<_> = self
111+
.hir_body_nodes
112+
.iter()
113+
.map(|&def_path_hash| {
114+
let dep_node = def_path_hash.to_dep_node(DepKind::HirBody);
115+
(def_path_hash, self.dep_graph.fingerprint_of(&dep_node))
116+
})
117+
.collect();
118+
119+
node_hashes.sort_unstable_by(|&(ref d1, _), &(ref d2, _)| d1.cmp(d2));
120+
121+
self.dep_graph.with_task(DepNode::new_no_params(DepKind::Krate),
122+
&self.hcx,
123+
(node_hashes, crate_disambiguator),
124+
identity_fn);
59125
self.map
60126
}
61127

@@ -70,7 +136,11 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
70136

71137
fn insert(&mut self, id: NodeId, node: Node<'hir>) {
72138
let parent = self.parent_node;
73-
let dep_node_index = self.current_dep_node_index;
139+
let dep_node_index = if self.currently_in_body {
140+
self.current_full_dep_index
141+
} else {
142+
self.current_signature_dep_index
143+
};
74144

75145
let entry = match node {
76146
NodeItem(n) => EntryItem(parent, dep_node_index, n),
@@ -91,6 +161,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
91161
NodeTyParam(n) => EntryTyParam(parent, dep_node_index, n),
92162
NodeVisibility(n) => EntryVisibility(parent, dep_node_index, n),
93163
NodeLocal(n) => EntryLocal(parent, dep_node_index, n),
164+
NodeMacroDef(n) => EntryMacroDef(dep_node_index, n),
94165
};
95166

96167
// Make sure that the DepNode of some node coincides with the HirId
@@ -127,22 +198,41 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
127198
self.parent_node = parent_node;
128199
}
129200

130-
fn with_dep_node_owner<F: FnOnce(&mut Self)>(&mut self,
201+
fn with_dep_node_owner<T: HashStable<StableHashingContext<'a>>,
202+
F: FnOnce(&mut Self)>(&mut self,
131203
dep_node_owner: DefIndex,
204+
item_like: &T,
132205
f: F) {
133206
let prev_owner = self.current_dep_node_owner;
134-
let prev_index = self.current_dep_node_index;
135-
136-
// When we enter a new owner (item, impl item, or trait item), we always
137-
// start out again with DepKind::Hir.
138-
let new_dep_node = self.definitions
139-
.def_path_hash(dep_node_owner)
140-
.to_dep_node(DepKind::Hir);
141-
self.current_dep_node_index = self.dep_graph.alloc_input_node(new_dep_node);
207+
let prev_signature_dep_index = self.current_signature_dep_index;
208+
let prev_full_dep_index = self.current_signature_dep_index;
209+
let prev_in_body = self.currently_in_body;
210+
211+
let def_path_hash = self.definitions.def_path_hash(dep_node_owner);
212+
213+
self.current_signature_dep_index = self.dep_graph.with_task(
214+
def_path_hash.to_dep_node(DepKind::Hir),
215+
&self.hcx,
216+
HirItemLike { item_like, hash_bodies: false },
217+
identity_fn
218+
).1;
219+
220+
self.current_full_dep_index = self.dep_graph.with_task(
221+
def_path_hash.to_dep_node(DepKind::HirBody),
222+
&self.hcx,
223+
HirItemLike { item_like, hash_bodies: true },
224+
identity_fn
225+
).1;
226+
227+
self.hir_body_nodes.push(def_path_hash);
228+
142229
self.current_dep_node_owner = dep_node_owner;
230+
self.currently_in_body = false;
143231
f(self);
144-
self.current_dep_node_index = prev_index;
232+
self.currently_in_body = prev_in_body;
145233
self.current_dep_node_owner = prev_owner;
234+
self.current_full_dep_index = prev_full_dep_index;
235+
self.current_signature_dep_index = prev_signature_dep_index;
146236
}
147237
}
148238

@@ -169,24 +259,17 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
169259
}
170260

171261
fn visit_nested_body(&mut self, id: BodyId) {
172-
// When we enter a body, we switch to DepKind::HirBody.
173-
// Note that current_dep_node_index might already be DepKind::HirBody,
174-
// e.g. when entering the body of a closure that is already part of a
175-
// surrounding body. That's expected and not a problem.
176-
let prev_index = self.current_dep_node_index;
177-
let new_dep_node = self.definitions
178-
.def_path_hash(self.current_dep_node_owner)
179-
.to_dep_node(DepKind::HirBody);
180-
self.current_dep_node_index = self.dep_graph.alloc_input_node(new_dep_node);
262+
let prev_in_body = self.currently_in_body;
263+
self.currently_in_body = true;
181264
self.visit_body(self.krate.body(id));
182-
self.current_dep_node_index = prev_index;
265+
self.currently_in_body = prev_in_body;
183266
}
184267

185268
fn visit_item(&mut self, i: &'hir Item) {
186269
debug!("visit_item: {:?}", i);
187270
debug_assert_eq!(i.hir_id.owner,
188271
self.definitions.opt_def_index(i.id).unwrap());
189-
self.with_dep_node_owner(i.hir_id.owner, |this| {
272+
self.with_dep_node_owner(i.hir_id.owner, i, |this| {
190273
this.insert(i.id, NodeItem(i));
191274
this.with_parent(i.id, |this| {
192275
match i.node {
@@ -222,7 +305,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
222305
fn visit_trait_item(&mut self, ti: &'hir TraitItem) {
223306
debug_assert_eq!(ti.hir_id.owner,
224307
self.definitions.opt_def_index(ti.id).unwrap());
225-
self.with_dep_node_owner(ti.hir_id.owner, |this| {
308+
self.with_dep_node_owner(ti.hir_id.owner, ti, |this| {
226309
this.insert(ti.id, NodeTraitItem(ti));
227310

228311
this.with_parent(ti.id, |this| {
@@ -234,7 +317,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
234317
fn visit_impl_item(&mut self, ii: &'hir ImplItem) {
235318
debug_assert_eq!(ii.hir_id.owner,
236319
self.definitions.opt_def_index(ii.id).unwrap());
237-
self.with_dep_node_owner(ii.hir_id.owner, |this| {
320+
self.with_dep_node_owner(ii.hir_id.owner, ii, |this| {
238321
this.insert(ii.id, NodeImplItem(ii));
239322

240323
this.with_parent(ii.id, |this| {
@@ -328,7 +411,11 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
328411
}
329412

330413
fn visit_macro_def(&mut self, macro_def: &'hir MacroDef) {
331-
self.insert_entry(macro_def.id, NotPresent);
414+
let def_index = self.definitions.opt_def_index(macro_def.id).unwrap();
415+
416+
self.with_dep_node_owner(def_index, macro_def, |this| {
417+
this.insert(macro_def.id, NodeMacroDef(macro_def));
418+
});
332419
}
333420

334421
fn visit_variant(&mut self, v: &'hir Variant, g: &'hir Generics, item_id: NodeId) {
@@ -375,3 +462,25 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
375462
self.visit_nested_impl_item(id);
376463
}
377464
}
465+
466+
467+
fn identity_fn<T>(_: &StableHashingContext, item_like: T) -> T {
468+
item_like
469+
}
470+
471+
struct HirItemLike<T> {
472+
item_like: T,
473+
hash_bodies: bool,
474+
}
475+
476+
impl<'hir, T> HashStable<StableHashingContext<'hir>> for HirItemLike<T>
477+
where T: HashStable<StableHashingContext<'hir>>
478+
{
479+
fn hash_stable<W: StableHasherResult>(&self,
480+
hcx: &mut StableHashingContext<'hir>,
481+
hasher: &mut StableHasher<W>) {
482+
hcx.while_hashing_hir_bodies(self.hash_bodies, |hcx| {
483+
self.item_like.hash_stable(hcx, hasher);
484+
});
485+
}
486+
}

0 commit comments

Comments
 (0)