Skip to content

Commit 9228d23

Browse files
committed
Auto merge of #43028 - michaelwoerister:dedup-dep-nodes, r=nikomatsakis
incr.comp.: Deduplicate some DepNodes and introduce anonymous DepNodes This is a parallel PR to the pending #42769. It implements most of what is possible in terms of DepNode re-opening without having anonymous DepNodes yet (#42298). r? @nikomatsakis
2 parents bf0a9e0 + 4f1f671 commit 9228d23

File tree

19 files changed

+640
-691
lines changed

19 files changed

+640
-691
lines changed

src/librustc/dep_graph/README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ The nodes of the graph are defined by the enum `DepNode`. They represent
1616
one of three things:
1717

1818
1. HIR nodes (like `Hir(DefId)`) represent the HIR input itself.
19-
2. Data nodes (like `ItemSignature(DefId)`) represent some computed
19+
2. Data nodes (like `TypeOfItem(DefId)`) represent some computed
2020
information about a particular item.
2121
3. Procedure nodes (like `CoherenceCheckTrait(DefId)`) represent some
2222
procedure that is executing. Usually this procedure is
@@ -289,7 +289,7 @@ to see something like:
289289

290290
Hir(foo) -> Collect(bar)
291291
Collect(bar) -> TypeckTables(bar)
292-
292+
293293
That first edge looks suspicious to you. So you set
294294
`RUST_FORBID_DEP_GRAPH_EDGE` to `Hir&foo -> Collect&bar`, re-run, and
295295
then observe the backtrace. Voila, bug fixed!

src/librustc/dep_graph/dep_node.rs

+135-88
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,9 @@ use hir::def_id::{CrateNum, DefId};
6464
use hir::map::DefPathHash;
6565

6666
use ich::Fingerprint;
67-
use ty::TyCtxt;
67+
use ty::{TyCtxt, Instance, InstanceDef};
68+
use ty::fast_reject::SimplifiedType;
69+
use ty::subst::Substs;
6870
use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
6971
use ich::StableHashingContext;
7072
use std::fmt;
@@ -77,8 +79,14 @@ macro_rules! erase {
7779
($x:tt) => ({})
7880
}
7981

82+
macro_rules! anon_attr_to_bool {
83+
(anon) => (true)
84+
}
85+
8086
macro_rules! define_dep_nodes {
81-
($(
87+
(<$tcx:tt>
88+
$(
89+
[$($anon:ident)*]
8290
$variant:ident $(( $($tuple_arg:tt),* ))*
8391
$({ $($struct_arg_name:ident : $struct_arg_ty:ty),* })*
8492
,)*
@@ -92,7 +100,7 @@ macro_rules! define_dep_nodes {
92100
impl DepKind {
93101
#[allow(unreachable_code)]
94102
#[inline]
95-
pub fn can_reconstruct_query_key(&self) -> bool {
103+
pub fn can_reconstruct_query_key<$tcx>(&self) -> bool {
96104
match *self {
97105
$(
98106
DepKind :: $variant => {
@@ -114,6 +122,19 @@ macro_rules! define_dep_nodes {
114122
}
115123
}
116124

125+
#[allow(unreachable_code)]
126+
#[inline]
127+
pub fn is_anon<$tcx>(&self) -> bool {
128+
match *self {
129+
$(
130+
DepKind :: $variant => {
131+
$(return anon_attr_to_bool!($anon);)*
132+
false
133+
}
134+
)*
135+
}
136+
}
137+
117138
#[allow(unreachable_code)]
118139
#[inline]
119140
pub fn has_params(&self) -> bool {
@@ -139,7 +160,7 @@ macro_rules! define_dep_nodes {
139160
}
140161
}
141162

142-
pub enum DepConstructor {
163+
pub enum DepConstructor<$tcx> {
143164
$(
144165
$variant $(( $($tuple_arg),* ))*
145166
$({ $($struct_arg_name : $struct_arg_ty),* })*
@@ -155,7 +176,12 @@ macro_rules! define_dep_nodes {
155176

156177
impl DepNode {
157178
#[allow(unreachable_code, non_snake_case)]
158-
pub fn new(tcx: TyCtxt, dep: DepConstructor) -> DepNode {
179+
pub fn new<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
180+
dep: DepConstructor<'gcx>)
181+
-> DepNode
182+
where 'gcx: 'a + 'tcx,
183+
'tcx: 'a
184+
{
159185
match dep {
160186
$(
161187
DepConstructor :: $variant $(( $($tuple_arg),* ))*
@@ -336,7 +362,7 @@ impl DefId {
336362
}
337363
}
338364

339-
define_dep_nodes!(
365+
define_dep_nodes!( <'tcx>
340366
// Represents the `Krate` as a whole (the `hir::Krate` value) (as
341367
// distinct from the krate module). This is basically a hash of
342368
// the entire krate, so if you read from `Krate` (e.g., by calling
@@ -348,90 +374,101 @@ define_dep_nodes!(
348374
// suitable wrapper, you can use `tcx.dep_graph.ignore()` to gain
349375
// access to the krate, but you must remember to add suitable
350376
// edges yourself for the individual items that you read.
351-
Krate,
377+
[] Krate,
352378

353379
// Represents the HIR node with the given node-id
354-
Hir(DefId),
380+
[] Hir(DefId),
355381

356382
// Represents the body of a function or method. The def-id is that of the
357383
// function/method.
358-
HirBody(DefId),
384+
[] HirBody(DefId),
359385

360386
// Represents the metadata for a given HIR node, typically found
361387
// in an extern crate.
362-
MetaData(DefId),
388+
[] MetaData(DefId),
363389

364390
// Represents some artifact that we save to disk. Note that these
365391
// do not have a def-id as part of their identifier.
366-
WorkProduct(WorkProductId),
392+
[] WorkProduct(WorkProductId),
367393

368394
// Represents different phases in the compiler.
369-
RegionMaps(DefId),
370-
Coherence,
371-
Resolve,
372-
CoherenceCheckTrait(DefId),
373-
PrivacyAccessLevels(CrateNum),
395+
[] RegionMaps(DefId),
396+
[] Coherence,
397+
[] Resolve,
398+
[] CoherenceCheckTrait(DefId),
399+
[] PrivacyAccessLevels(CrateNum),
374400

375401
// Represents the MIR for a fn; also used as the task node for
376402
// things read/modify that MIR.
377-
Mir(DefId),
378-
MirShim(DefIdList),
379-
380-
BorrowCheckKrate,
381-
BorrowCheck(DefId),
382-
RvalueCheck(DefId),
383-
Reachability,
384-
MirKeys,
385-
TransWriteMetadata,
386-
CrateVariances,
403+
[] MirConstQualif(DefId),
404+
[] MirConst(DefId),
405+
[] MirValidated(DefId),
406+
[] MirOptimized(DefId),
407+
[] MirShim { instance_def: InstanceDef<'tcx> },
408+
409+
[] BorrowCheckKrate,
410+
[] BorrowCheck(DefId),
411+
[] RvalueCheck(DefId),
412+
[] Reachability,
413+
[] MirKeys,
414+
[] TransWriteMetadata,
415+
[] CrateVariances,
387416

388417
// Nodes representing bits of computed IR in the tcx. Each shared
389418
// table in the tcx (or elsewhere) maps to one of these
390-
// nodes. Often we map multiple tables to the same node if there
391-
// is no point in distinguishing them (e.g., both the type and
392-
// predicates for an item wind up in `ItemSignature`).
393-
AssociatedItems(DefId),
394-
ItemSignature(DefId),
395-
ItemVarianceConstraints(DefId),
396-
ItemVariances(DefId),
397-
IsConstFn(DefId),
398-
IsForeignItem(DefId),
399-
TypeParamPredicates { item_id: DefId, param_id: DefId },
400-
SizedConstraint(DefId),
401-
DtorckConstraint(DefId),
402-
AdtDestructor(DefId),
403-
AssociatedItemDefIds(DefId),
404-
InherentImpls(DefId),
405-
TypeckBodiesKrate,
406-
TypeckTables(DefId),
407-
ConstEval(DefId),
408-
SymbolName(DefId),
409-
SpecializationGraph(DefId),
410-
ObjectSafety(DefId),
411-
IsCopy(DefId),
412-
IsSized(DefId),
413-
IsFreeze(DefId),
414-
NeedsDrop(DefId),
415-
Layout(DefId),
416-
417-
// The set of impls for a given trait. Ultimately, it would be
418-
// nice to get more fine-grained here (e.g., to include a
419-
// simplified type), but we can't do that until we restructure the
420-
// HIR to distinguish the *header* of an impl from its body. This
421-
// is because changes to the header may change the self-type of
422-
// the impl and hence would require us to be more conservative
423-
// than changes in the impl body.
424-
TraitImpls(DefId),
425-
426-
AllLocalTraitImpls,
419+
// nodes.
420+
[] AssociatedItems(DefId),
421+
[] TypeOfItem(DefId),
422+
[] GenericsOfItem(DefId),
423+
[] PredicatesOfItem(DefId),
424+
[] SuperPredicatesOfItem(DefId),
425+
[] TraitDefOfItem(DefId),
426+
[] AdtDefOfItem(DefId),
427+
[] IsDefaultImpl(DefId),
428+
[] ImplTraitRef(DefId),
429+
[] ImplPolarity(DefId),
430+
[] ClosureKind(DefId),
431+
[] FnSignature(DefId),
432+
[] CoerceUnsizedInfo(DefId),
433+
434+
[] ItemVarianceConstraints(DefId),
435+
[] ItemVariances(DefId),
436+
[] IsConstFn(DefId),
437+
[] IsForeignItem(DefId),
438+
[] TypeParamPredicates { item_id: DefId, param_id: DefId },
439+
[] SizedConstraint(DefId),
440+
[] DtorckConstraint(DefId),
441+
[] AdtDestructor(DefId),
442+
[] AssociatedItemDefIds(DefId),
443+
[] InherentImpls(DefId),
444+
[] TypeckBodiesKrate,
445+
[] TypeckTables(DefId),
446+
[] HasTypeckTables(DefId),
447+
[] ConstEval { def_id: DefId, substs: &'tcx Substs<'tcx> },
448+
[] SymbolName(DefId),
449+
[] InstanceSymbolName { instance: Instance<'tcx> },
450+
[] SpecializationGraph(DefId),
451+
[] ObjectSafety(DefId),
452+
453+
[anon] IsCopy(DefId),
454+
[anon] IsSized(DefId),
455+
[anon] IsFreeze(DefId),
456+
[anon] NeedsDrop(DefId),
457+
[anon] Layout(DefId),
458+
459+
// The set of impls for a given trait.
460+
[] TraitImpls(DefId),
461+
[] RelevantTraitImpls(DefId, SimplifiedType),
462+
463+
[] AllLocalTraitImpls,
427464

428465
// Nodes representing caches. To properly handle a true cache, we
429466
// don't use a DepTrackingMap, but rather we push a task node.
430467
// Otherwise the write into the map would be incorrectly
431468
// attributed to the first task that happened to fill the cache,
432469
// which would yield an overly conservative dep-graph.
433-
TraitItems(DefId),
434-
ReprHints(DefId),
470+
[] TraitItems(DefId),
471+
[] ReprHints(DefId),
435472

436473
// Trait selection cache is a little funny. Given a trait
437474
// reference like `Foo: SomeTrait<Bar>`, there could be
@@ -458,35 +495,45 @@ define_dep_nodes!(
458495
// imprecision in our dep-graph tracking. The important thing is
459496
// that for any given trait-ref, we always map to the **same**
460497
// trait-select node.
461-
TraitSelect { trait_def_id: DefId, input_def_id: DefId },
498+
[] TraitSelect { trait_def_id: DefId, input_def_id: DefId },
462499

463500
// For proj. cache, we just keep a list of all def-ids, since it is
464501
// not a hotspot.
465-
ProjectionCache { def_ids: DefIdList },
466-
467-
ParamEnv(DefId),
468-
DescribeDef(DefId),
469-
DefSpan(DefId),
470-
Stability(DefId),
471-
Deprecation(DefId),
472-
ItemBodyNestedBodies(DefId),
473-
ConstIsRvaluePromotableToStatic(DefId),
474-
ImplParent(DefId),
475-
TraitOfItem(DefId),
476-
IsExportedSymbol(DefId),
477-
IsMirAvailable(DefId),
478-
ItemAttrs(DefId),
479-
FnArgNames(DefId),
480-
DylibDepFormats(DefId),
481-
IsAllocator(DefId),
482-
IsPanicRuntime(DefId),
483-
ExternCrate(DefId),
502+
[] ProjectionCache { def_ids: DefIdList },
503+
504+
[] ParamEnv(DefId),
505+
[] DescribeDef(DefId),
506+
[] DefSpan(DefId),
507+
[] Stability(DefId),
508+
[] Deprecation(DefId),
509+
[] ItemBodyNestedBodies(DefId),
510+
[] ConstIsRvaluePromotableToStatic(DefId),
511+
[] ImplParent(DefId),
512+
[] TraitOfItem(DefId),
513+
[] IsExportedSymbol(DefId),
514+
[] IsMirAvailable(DefId),
515+
[] ItemAttrs(DefId),
516+
[] FnArgNames(DefId),
517+
[] DylibDepFormats(DefId),
518+
[] IsAllocator(DefId),
519+
[] IsPanicRuntime(DefId),
520+
[] ExternCrate(DefId),
484521
);
485522

486-
trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> {
523+
trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {
487524
const CAN_RECONSTRUCT_QUERY_KEY: bool;
488-
fn to_fingerprint(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Fingerprint;
489-
fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String;
525+
526+
/// This method turns the parameters of a DepNodeConstructor into an opaque
527+
/// Fingerprint to be used in DepNode.
528+
/// Not all DepNodeParams support being turned into a Fingerprint (they
529+
/// don't need to if the corresponding DepNode is anonymous).
530+
fn to_fingerprint(&self, _: TyCtxt<'a, 'gcx, 'tcx>) -> Fingerprint {
531+
panic!("Not implemented. Accidentally called on anonymous node?")
532+
}
533+
534+
fn to_debug_str(&self, _: TyCtxt<'a, 'gcx, 'tcx>) -> String {
535+
format!("{:?}", self)
536+
}
490537
}
491538

492539
impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a, T> DepNodeParams<'a, 'gcx, 'tcx> for T

0 commit comments

Comments
 (0)