Skip to content

Commit 936dbbc

Browse files
committed
Give function bodies their own dep graph node
1 parent 16eedd2 commit 936dbbc

File tree

15 files changed

+118
-29
lines changed

15 files changed

+118
-29
lines changed

src/librustc/dep_graph/dep_node.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ pub enum DepNode<D: Clone + Debug> {
4242
// Represents the HIR node with the given node-id
4343
Hir(D),
4444

45+
// Represents the body of a function or method
46+
HirBody(D),
47+
4548
// Represents the metadata for a given HIR node, typically found
4649
// in an extern crate.
4750
MetaData(D),
@@ -150,6 +153,7 @@ impl<D: Clone + Debug> DepNode<D> {
150153
CollectItem,
151154
BorrowCheck,
152155
Hir,
156+
HirBody,
153157
TransCrateItem,
154158
TypeckItemType,
155159
TypeckItemBody,
@@ -199,6 +203,7 @@ impl<D: Clone + Debug> DepNode<D> {
199203
WorkProduct(ref id) => Some(WorkProduct(id.clone())),
200204

201205
Hir(ref d) => op(d).map(Hir),
206+
HirBody(ref d) => op(d).map(HirBody),
202207
MetaData(ref d) => op(d).map(MetaData),
203208
CollectItem(ref d) => op(d).map(CollectItem),
204209
CoherenceCheckImpl(ref d) => op(d).map(CoherenceCheckImpl),

src/librustc/hir/map/mod.rs

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,26 +256,46 @@ impl<'ast> Map<'ast> {
256256
let map = self.map.borrow();
257257
let mut id = id0;
258258
if !self.is_inlined_node_id(id) {
259+
let mut last_expr = None;
259260
loop {
260261
match map[id.as_usize()] {
261262
EntryItem(_, item) => {
262263
assert_eq!(id, item.id);
263264
let def_id = self.local_def_id(id);
264265
assert!(!self.is_inlined_def_id(def_id));
266+
267+
if let Some(last_id) = last_expr {
268+
// The body of the item may have a separate dep node
269+
// (Note that impl/trait items don't currently have
270+
// their own dep node, so there's also just one
271+
// HirBody node for all the items)
272+
if self.is_body(last_id, item) {
273+
return DepNode::HirBody(def_id);
274+
}
275+
}
265276
return DepNode::Hir(def_id);
266277
}
267278

268-
EntryImplItem(..) => {
279+
EntryImplItem(_, item) => {
269280
let def_id = self.local_def_id(id);
270281
assert!(!self.is_inlined_def_id(def_id));
282+
283+
if let Some(last_id) = last_expr {
284+
// The body of the item may have a separate dep node
285+
// (Note that impl/trait items don't currently have
286+
// their own dep node, so there's also just one
287+
// HirBody node for all the items)
288+
if self.is_impl_item_body(last_id, item) {
289+
return DepNode::HirBody(def_id);
290+
}
291+
}
271292
return DepNode::Hir(def_id);
272293
}
273294

274295
EntryForeignItem(p, _) |
275296
EntryTraitItem(p, _) |
276297
EntryVariant(p, _) |
277298
EntryField(p, _) |
278-
EntryExpr(p, _) |
279299
EntryStmt(p, _) |
280300
EntryTy(p, _) |
281301
EntryTraitRef(p, _) |
@@ -288,6 +308,11 @@ impl<'ast> Map<'ast> {
288308
EntryVisibility(p, _) =>
289309
id = p,
290310

311+
EntryExpr(p, _) => {
312+
last_expr = Some(id);
313+
id = p;
314+
}
315+
291316
RootCrate =>
292317
return DepNode::Krate,
293318

@@ -345,6 +370,29 @@ impl<'ast> Map<'ast> {
345370
}
346371
}
347372

373+
fn is_body(&self, node_id: NodeId, item: &Item) -> bool {
374+
match item.node {
375+
ItemFn(_, _, _, _, _, body) => body.node_id() == node_id,
376+
// Since trait/impl items currently don't get their own dep nodes,
377+
// we check here whether node_id is the body of any of the items.
378+
// Once they get their own dep nodes, this can go away
379+
ItemTrait(_, _, _, ref trait_items) => {
380+
trait_items.iter().any(|trait_item| { match trait_item.node {
381+
MethodTraitItem(_, Some(body)) => body.node_id() == node_id,
382+
_ => false
383+
}})
384+
}
385+
_ => false
386+
}
387+
}
388+
389+
fn is_impl_item_body(&self, node_id: NodeId, item: &ImplItem) -> bool {
390+
match item.node {
391+
ImplItemKind::Method(_, body) => body.node_id() == node_id,
392+
_ => false
393+
}
394+
}
395+
348396
pub fn num_local_def_ids(&self) -> usize {
349397
self.definitions.borrow().len()
350398
}

src/librustc_const_eval/eval.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ use graphviz::IntoCow;
3333
use syntax::ast;
3434
use rustc::hir::{Expr, PatKind};
3535
use rustc::hir;
36-
use rustc::hir::intravisit::FnKind;
3736
use syntax::ptr::P;
3837
use syntax::codemap;
3938
use syntax::attr::IntType;

src/librustc_incremental/calculate_svh/mod.rs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -149,19 +149,27 @@ impl<'a, 'tcx> HashItemsVisitor<'a, 'tcx> {
149149
{
150150
assert!(def_id.is_local());
151151
debug!("HashItemsVisitor::calculate(def_id={:?})", def_id);
152+
self.calculate_def_hash(DepNode::Hir(def_id), false, &mut walk_op);
153+
self.calculate_def_hash(DepNode::HirBody(def_id), true, &mut walk_op);
154+
}
155+
156+
fn calculate_def_hash<W>(&mut self, dep_node: DepNode<DefId>, hash_bodies: bool, walk_op: &mut W)
157+
where W: for<'v> FnMut(&mut StrictVersionHashVisitor<'v, 'a, 'tcx>)
158+
{
152159
let mut state = IchHasher::new();
153160
walk_op(&mut StrictVersionHashVisitor::new(&mut state,
154161
self.tcx,
155162
&mut self.def_path_hashes,
156163
&mut self.codemap,
157-
self.hash_spans));
164+
self.hash_spans,
165+
hash_bodies));
158166
let bytes_hashed = state.bytes_hashed();
159167
let item_hash = state.finish();
160-
self.hashes.insert(DepNode::Hir(def_id), item_hash);
161-
debug!("calculate_item_hash: def_id={:?} hash={:?}", def_id, item_hash);
168+
debug!("calculate_def_hash: dep_node={:?} hash={:?}", dep_node, item_hash);
169+
self.hashes.insert(dep_node, item_hash);
162170

163171
let bytes_hashed = self.tcx.sess.perf_stats.incr_comp_bytes_hashed.get() +
164-
bytes_hashed;
172+
bytes_hashed;
165173
self.tcx.sess.perf_stats.incr_comp_bytes_hashed.set(bytes_hashed);
166174
}
167175

@@ -200,7 +208,8 @@ impl<'a, 'tcx> HashItemsVisitor<'a, 'tcx> {
200208
self.tcx,
201209
&mut self.def_path_hashes,
202210
&mut self.codemap,
203-
self.hash_spans);
211+
self.hash_spans,
212+
false);
204213
visitor.hash_attributes(&krate.attrs);
205214
}
206215

src/librustc_incremental/calculate_svh/svh_visitor.rs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,16 @@ pub struct StrictVersionHashVisitor<'a, 'hash: 'a, 'tcx: 'hash> {
5252
hash_spans: bool,
5353
codemap: &'a mut CachingCodemapView<'tcx>,
5454
overflow_checks_enabled: bool,
55+
hash_bodies: bool,
5556
}
5657

5758
impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> {
5859
pub fn new(st: &'a mut IchHasher,
5960
tcx: TyCtxt<'hash, 'tcx, 'tcx>,
6061
def_path_hashes: &'a mut DefPathHashes<'hash, 'tcx>,
6162
codemap: &'a mut CachingCodemapView<'tcx>,
62-
hash_spans: bool)
63+
hash_spans: bool,
64+
hash_bodies: bool)
6365
-> Self {
6466
let check_overflow = tcx.sess.opts.debugging_opts.force_overflow_checks
6567
.unwrap_or(tcx.sess.opts.debug_assertions);
@@ -71,6 +73,7 @@ impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> {
7173
hash_spans: hash_spans,
7274
codemap: codemap,
7375
overflow_checks_enabled: check_overflow,
76+
hash_bodies: hash_bodies,
7477
}
7578
}
7679

@@ -459,15 +462,16 @@ fn saw_ty(node: &Ty_) -> SawTyComponent {
459462
#[derive(Hash)]
460463
enum SawTraitOrImplItemComponent {
461464
SawTraitOrImplItemConst,
462-
SawTraitOrImplItemMethod(Unsafety, Constness, Abi),
465+
// The boolean signifies whether a body is present
466+
SawTraitOrImplItemMethod(Unsafety, Constness, Abi, bool),
463467
SawTraitOrImplItemType
464468
}
465469

466470
fn saw_trait_item(ti: &TraitItem_) -> SawTraitOrImplItemComponent {
467471
match *ti {
468472
ConstTraitItem(..) => SawTraitOrImplItemConst,
469-
MethodTraitItem(ref sig, _) =>
470-
SawTraitOrImplItemMethod(sig.unsafety, sig.constness, sig.abi),
473+
MethodTraitItem(ref sig, ref body) =>
474+
SawTraitOrImplItemMethod(sig.unsafety, sig.constness, sig.abi, body.is_some()),
471475
TypeTraitItem(..) => SawTraitOrImplItemType
472476
}
473477
}
@@ -476,7 +480,7 @@ fn saw_impl_item(ii: &ImplItemKind) -> SawTraitOrImplItemComponent {
476480
match *ii {
477481
ImplItemKind::Const(..) => SawTraitOrImplItemConst,
478482
ImplItemKind::Method(ref sig, _) =>
479-
SawTraitOrImplItemMethod(sig.unsafety, sig.constness, sig.abi),
483+
SawTraitOrImplItemMethod(sig.unsafety, sig.constness, sig.abi, true),
480484
ImplItemKind::Type(..) => SawTraitOrImplItemType
481485
}
482486
}
@@ -509,6 +513,14 @@ macro_rules! hash_span {
509513
}
510514

511515
impl<'a, 'hash, 'tcx> visit::Visitor<'tcx> for StrictVersionHashVisitor<'a, 'hash, 'tcx> {
516+
fn nested_visit_map(&mut self) -> Option<(&hir::map::Map<'tcx>, visit::NestedVisitMode)> {
517+
if self.hash_bodies {
518+
Some((&self.tcx.map, visit::NestedVisitMode::OnlyBodies))
519+
} else {
520+
None
521+
}
522+
}
523+
512524
fn visit_variant_data(&mut self,
513525
s: &'tcx VariantData,
514526
name: Name,
@@ -609,7 +621,8 @@ impl<'a, 'hash, 'tcx> visit::Visitor<'tcx> for StrictVersionHashVisitor<'a, 'has
609621

610622
fn visit_mod(&mut self, m: &'tcx Mod, _s: Span, n: NodeId) {
611623
debug!("visit_mod: st={:?}", self.st);
612-
SawMod.hash(self.st); visit::walk_mod(self, m, n)
624+
SawMod.hash(self.st);
625+
visit::walk_mod(self, m, n)
613626
}
614627

615628
fn visit_ty(&mut self, t: &'tcx Ty) {

src/librustc_incremental/persist/dirty_clean.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@ impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> {
114114

115115
match dep_node {
116116
DepNode::Krate |
117-
DepNode::Hir(_) => {
117+
DepNode::Hir(_) |
118+
DepNode::HirBody(_) => {
118119
// HIR nodes are inputs, so if we are asserting that the HIR node is
119120
// dirty, we check the dirty input set.
120121
if !self.dirty_inputs.contains(&dep_node) {
@@ -143,7 +144,8 @@ impl<'a, 'tcx> DirtyCleanVisitor<'a, 'tcx> {
143144

144145
match dep_node {
145146
DepNode::Krate |
146-
DepNode::Hir(_) => {
147+
DepNode::Hir(_) |
148+
DepNode::HirBody(_) => {
147149
// For HIR nodes, check the inputs.
148150
if self.dirty_inputs.contains(&dep_node) {
149151
let dep_node_str = self.dep_node_str(&dep_node);

src/librustc_incremental/persist/hash.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> {
4545
pub fn is_hashable(dep_node: &DepNode<DefId>) -> bool {
4646
match *dep_node {
4747
DepNode::Krate |
48-
DepNode::Hir(_) => true,
48+
DepNode::Hir(_) |
49+
DepNode::HirBody(_) =>
50+
true,
4951
DepNode::MetaData(def_id) => !def_id.is_local(),
5052
_ => false,
5153
}
@@ -58,7 +60,7 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> {
5860
}
5961

6062
// HIR nodes (which always come from our crate) are an input:
61-
DepNode::Hir(def_id) => {
63+
DepNode::Hir(def_id) | DepNode::HirBody(def_id) => {
6264
assert!(def_id.is_local(),
6365
"cannot hash HIR for non-local def-id {:?} => {:?}",
6466
def_id,

src/librustc_incremental/persist/save.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,8 @@ pub fn encode_dep_graph(preds: &Predecessors,
145145
for (&target, sources) in &preds.inputs {
146146
match *target {
147147
DepNode::MetaData(ref def_id) => {
148-
// Metadata *targets* are always local metadata nodes. We handle
149-
// those in `encode_metadata_hashes`, which comes later.
148+
// Metadata *targets* are always local metadata nodes. We have
149+
// already handled those in `encode_metadata_hashes`.
150150
assert!(def_id.is_local());
151151
continue;
152152
}

src/test/incremental/hello_world.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ mod x {
3131
mod y {
3232
use x;
3333

34-
#[rustc_dirty(label="TypeckItemBody", cfg="rpass2")]
34+
#[rustc_clean(label="TypeckItemBody", cfg="rpass2")]
3535
pub fn y() {
3636
x::x();
3737
}

src/test/incremental/ich_method_call_trait_scope.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,14 @@ mod mod3 {
4646
mod mod3 {
4747
use Trait2;
4848

49-
#[rustc_dirty(label="Hir", cfg="rpass2")]
49+
#[rustc_clean(label="Hir", cfg="rpass2")]
50+
#[rustc_dirty(label="HirBody", cfg="rpass2")]
5051
fn bar() {
5152
().method();
5253
}
5354

5455
#[rustc_clean(label="Hir", cfg="rpass2")]
56+
#[rustc_clean(label="HirBody", cfg="rpass2")]
5557
fn baz() {
5658
22; // no method call, traits in scope don't matter
5759
}

0 commit comments

Comments
 (0)