mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-04 19:29:07 +00:00
incr.comp.: Introduce the concept of anonymous DepNodes.
This commit is contained in:
parent
089860b603
commit
0363a23c35
@ -79,9 +79,14 @@ macro_rules! erase {
|
|||||||
($x:tt) => ({})
|
($x:tt) => ({})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! anon_attr_to_bool {
|
||||||
|
(anon) => (true)
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! define_dep_nodes {
|
macro_rules! define_dep_nodes {
|
||||||
(<$tcx:tt>
|
(<$tcx:tt>
|
||||||
$(
|
$(
|
||||||
|
[$($anon:ident)*]
|
||||||
$variant:ident $(( $($tuple_arg:tt),* ))*
|
$variant:ident $(( $($tuple_arg:tt),* ))*
|
||||||
$({ $($struct_arg_name:ident : $struct_arg_ty:ty),* })*
|
$({ $($struct_arg_name:ident : $struct_arg_ty:ty),* })*
|
||||||
,)*
|
,)*
|
||||||
@ -117,6 +122,19 @@ macro_rules! define_dep_nodes {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unreachable_code)]
|
||||||
|
#[inline]
|
||||||
|
pub fn is_anon<$tcx>(&self) -> bool {
|
||||||
|
match *self {
|
||||||
|
$(
|
||||||
|
DepKind :: $variant => {
|
||||||
|
$(return anon_attr_to_bool!($anon);)*
|
||||||
|
false
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(unreachable_code)]
|
#[allow(unreachable_code)]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn has_params(&self) -> bool {
|
pub fn has_params(&self) -> bool {
|
||||||
@ -356,100 +374,101 @@ define_dep_nodes!( <'tcx>
|
|||||||
// suitable wrapper, you can use `tcx.dep_graph.ignore()` to gain
|
// suitable wrapper, you can use `tcx.dep_graph.ignore()` to gain
|
||||||
// access to the krate, but you must remember to add suitable
|
// access to the krate, but you must remember to add suitable
|
||||||
// edges yourself for the individual items that you read.
|
// edges yourself for the individual items that you read.
|
||||||
Krate,
|
[] Krate,
|
||||||
|
|
||||||
// Represents the HIR node with the given node-id
|
// Represents the HIR node with the given node-id
|
||||||
Hir(DefId),
|
[] Hir(DefId),
|
||||||
|
|
||||||
// Represents the body of a function or method. The def-id is that of the
|
// Represents the body of a function or method. The def-id is that of the
|
||||||
// function/method.
|
// function/method.
|
||||||
HirBody(DefId),
|
[] HirBody(DefId),
|
||||||
|
|
||||||
// Represents the metadata for a given HIR node, typically found
|
// Represents the metadata for a given HIR node, typically found
|
||||||
// in an extern crate.
|
// in an extern crate.
|
||||||
MetaData(DefId),
|
[] MetaData(DefId),
|
||||||
|
|
||||||
// Represents some artifact that we save to disk. Note that these
|
// Represents some artifact that we save to disk. Note that these
|
||||||
// do not have a def-id as part of their identifier.
|
// do not have a def-id as part of their identifier.
|
||||||
WorkProduct(WorkProductId),
|
[] WorkProduct(WorkProductId),
|
||||||
|
|
||||||
// Represents different phases in the compiler.
|
// Represents different phases in the compiler.
|
||||||
RegionMaps(DefId),
|
[] RegionMaps(DefId),
|
||||||
Coherence,
|
[] Coherence,
|
||||||
Resolve,
|
[] Resolve,
|
||||||
CoherenceCheckTrait(DefId),
|
[] CoherenceCheckTrait(DefId),
|
||||||
PrivacyAccessLevels(CrateNum),
|
[] PrivacyAccessLevels(CrateNum),
|
||||||
|
|
||||||
// Represents the MIR for a fn; also used as the task node for
|
// Represents the MIR for a fn; also used as the task node for
|
||||||
// things read/modify that MIR.
|
// things read/modify that MIR.
|
||||||
MirConstQualif(DefId),
|
[] MirConstQualif(DefId),
|
||||||
MirConst(DefId),
|
[] MirConst(DefId),
|
||||||
MirValidated(DefId),
|
[] MirValidated(DefId),
|
||||||
MirOptimized(DefId),
|
[] MirOptimized(DefId),
|
||||||
MirShim { instance_def: InstanceDef<'tcx> },
|
[] MirShim { instance_def: InstanceDef<'tcx> },
|
||||||
|
|
||||||
BorrowCheckKrate,
|
[] BorrowCheckKrate,
|
||||||
BorrowCheck(DefId),
|
[] BorrowCheck(DefId),
|
||||||
RvalueCheck(DefId),
|
[] RvalueCheck(DefId),
|
||||||
Reachability,
|
[] Reachability,
|
||||||
MirKeys,
|
[] MirKeys,
|
||||||
TransWriteMetadata,
|
[] TransWriteMetadata,
|
||||||
CrateVariances,
|
[] CrateVariances,
|
||||||
|
|
||||||
// Nodes representing bits of computed IR in the tcx. Each shared
|
// Nodes representing bits of computed IR in the tcx. Each shared
|
||||||
// table in the tcx (or elsewhere) maps to one of these
|
// table in the tcx (or elsewhere) maps to one of these
|
||||||
// nodes.
|
// nodes.
|
||||||
AssociatedItems(DefId),
|
[] AssociatedItems(DefId),
|
||||||
TypeOfItem(DefId),
|
[] TypeOfItem(DefId),
|
||||||
GenericsOfItem(DefId),
|
[] GenericsOfItem(DefId),
|
||||||
PredicatesOfItem(DefId),
|
[] PredicatesOfItem(DefId),
|
||||||
SuperPredicatesOfItem(DefId),
|
[] SuperPredicatesOfItem(DefId),
|
||||||
TraitDefOfItem(DefId),
|
[] TraitDefOfItem(DefId),
|
||||||
AdtDefOfItem(DefId),
|
[] AdtDefOfItem(DefId),
|
||||||
IsDefaultImpl(DefId),
|
[] IsDefaultImpl(DefId),
|
||||||
ImplTraitRef(DefId),
|
[] ImplTraitRef(DefId),
|
||||||
ImplPolarity(DefId),
|
[] ImplPolarity(DefId),
|
||||||
ClosureKind(DefId),
|
[] ClosureKind(DefId),
|
||||||
FnSignature(DefId),
|
[] FnSignature(DefId),
|
||||||
CoerceUnsizedInfo(DefId),
|
[] CoerceUnsizedInfo(DefId),
|
||||||
|
|
||||||
ItemVarianceConstraints(DefId),
|
[] ItemVarianceConstraints(DefId),
|
||||||
ItemVariances(DefId),
|
[] ItemVariances(DefId),
|
||||||
IsConstFn(DefId),
|
[] IsConstFn(DefId),
|
||||||
IsForeignItem(DefId),
|
[] IsForeignItem(DefId),
|
||||||
TypeParamPredicates { item_id: DefId, param_id: DefId },
|
[] TypeParamPredicates { item_id: DefId, param_id: DefId },
|
||||||
SizedConstraint(DefId),
|
[] SizedConstraint(DefId),
|
||||||
DtorckConstraint(DefId),
|
[] DtorckConstraint(DefId),
|
||||||
AdtDestructor(DefId),
|
[] AdtDestructor(DefId),
|
||||||
AssociatedItemDefIds(DefId),
|
[] AssociatedItemDefIds(DefId),
|
||||||
InherentImpls(DefId),
|
[] InherentImpls(DefId),
|
||||||
TypeckBodiesKrate,
|
[] TypeckBodiesKrate,
|
||||||
TypeckTables(DefId),
|
[] TypeckTables(DefId),
|
||||||
HasTypeckTables(DefId),
|
[] HasTypeckTables(DefId),
|
||||||
ConstEval { def_id: DefId, substs: &'tcx Substs<'tcx> },
|
[] ConstEval { def_id: DefId, substs: &'tcx Substs<'tcx> },
|
||||||
SymbolName(DefId),
|
[] SymbolName(DefId),
|
||||||
InstanceSymbolName { instance: Instance<'tcx> },
|
[] InstanceSymbolName { instance: Instance<'tcx> },
|
||||||
SpecializationGraph(DefId),
|
[] SpecializationGraph(DefId),
|
||||||
ObjectSafety(DefId),
|
[] ObjectSafety(DefId),
|
||||||
IsCopy(DefId),
|
|
||||||
IsSized(DefId),
|
[anon] IsCopy(DefId),
|
||||||
IsFreeze(DefId),
|
[anon] IsSized(DefId),
|
||||||
NeedsDrop(DefId),
|
[anon] IsFreeze(DefId),
|
||||||
Layout(DefId),
|
[anon] NeedsDrop(DefId),
|
||||||
|
[anon] Layout(DefId),
|
||||||
|
|
||||||
// The set of impls for a given trait.
|
// The set of impls for a given trait.
|
||||||
TraitImpls(DefId),
|
[] TraitImpls(DefId),
|
||||||
RelevantTraitImpls(DefId, SimplifiedType),
|
[] RelevantTraitImpls(DefId, SimplifiedType),
|
||||||
|
|
||||||
AllLocalTraitImpls,
|
[] AllLocalTraitImpls,
|
||||||
|
|
||||||
// Nodes representing caches. To properly handle a true cache, we
|
// Nodes representing caches. To properly handle a true cache, we
|
||||||
// don't use a DepTrackingMap, but rather we push a task node.
|
// don't use a DepTrackingMap, but rather we push a task node.
|
||||||
// Otherwise the write into the map would be incorrectly
|
// Otherwise the write into the map would be incorrectly
|
||||||
// attributed to the first task that happened to fill the cache,
|
// attributed to the first task that happened to fill the cache,
|
||||||
// which would yield an overly conservative dep-graph.
|
// which would yield an overly conservative dep-graph.
|
||||||
TraitItems(DefId),
|
[] TraitItems(DefId),
|
||||||
ReprHints(DefId),
|
[] ReprHints(DefId),
|
||||||
|
|
||||||
// Trait selection cache is a little funny. Given a trait
|
// Trait selection cache is a little funny. Given a trait
|
||||||
// reference like `Foo: SomeTrait<Bar>`, there could be
|
// reference like `Foo: SomeTrait<Bar>`, there could be
|
||||||
@ -476,35 +495,45 @@ define_dep_nodes!( <'tcx>
|
|||||||
// imprecision in our dep-graph tracking. The important thing is
|
// imprecision in our dep-graph tracking. The important thing is
|
||||||
// that for any given trait-ref, we always map to the **same**
|
// that for any given trait-ref, we always map to the **same**
|
||||||
// trait-select node.
|
// trait-select node.
|
||||||
TraitSelect { trait_def_id: DefId, input_def_id: DefId },
|
[] TraitSelect { trait_def_id: DefId, input_def_id: DefId },
|
||||||
|
|
||||||
// For proj. cache, we just keep a list of all def-ids, since it is
|
// For proj. cache, we just keep a list of all def-ids, since it is
|
||||||
// not a hotspot.
|
// not a hotspot.
|
||||||
ProjectionCache { def_ids: DefIdList },
|
[] ProjectionCache { def_ids: DefIdList },
|
||||||
|
|
||||||
ParamEnv(DefId),
|
[] ParamEnv(DefId),
|
||||||
DescribeDef(DefId),
|
[] DescribeDef(DefId),
|
||||||
DefSpan(DefId),
|
[] DefSpan(DefId),
|
||||||
Stability(DefId),
|
[] Stability(DefId),
|
||||||
Deprecation(DefId),
|
[] Deprecation(DefId),
|
||||||
ItemBodyNestedBodies(DefId),
|
[] ItemBodyNestedBodies(DefId),
|
||||||
ConstIsRvaluePromotableToStatic(DefId),
|
[] ConstIsRvaluePromotableToStatic(DefId),
|
||||||
ImplParent(DefId),
|
[] ImplParent(DefId),
|
||||||
TraitOfItem(DefId),
|
[] TraitOfItem(DefId),
|
||||||
IsExportedSymbol(DefId),
|
[] IsExportedSymbol(DefId),
|
||||||
IsMirAvailable(DefId),
|
[] IsMirAvailable(DefId),
|
||||||
ItemAttrs(DefId),
|
[] ItemAttrs(DefId),
|
||||||
FnArgNames(DefId),
|
[] FnArgNames(DefId),
|
||||||
DylibDepFormats(DefId),
|
[] DylibDepFormats(DefId),
|
||||||
IsAllocator(DefId),
|
[] IsAllocator(DefId),
|
||||||
IsPanicRuntime(DefId),
|
[] IsPanicRuntime(DefId),
|
||||||
ExternCrate(DefId),
|
[] ExternCrate(DefId),
|
||||||
);
|
);
|
||||||
|
|
||||||
trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> {
|
trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {
|
||||||
const CAN_RECONSTRUCT_QUERY_KEY: bool;
|
const CAN_RECONSTRUCT_QUERY_KEY: bool;
|
||||||
fn to_fingerprint(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Fingerprint;
|
|
||||||
fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String;
|
/// This method turns the parameters of a DepNodeConstructor into an opaque
|
||||||
|
/// Fingerprint to be used in DepNode.
|
||||||
|
/// Not all DepNodeParams support being turned into a Fingerprint (they
|
||||||
|
/// don't need to if the corresponding DepNode is anonymous).
|
||||||
|
fn to_fingerprint(&self, _: TyCtxt<'a, 'gcx, 'tcx>) -> Fingerprint {
|
||||||
|
panic!("Not implemented. Accidentally called on anonymous node?")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_debug_str(&self, _: TyCtxt<'a, 'gcx, 'tcx>) -> String {
|
||||||
|
format!("{:?}", self)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a, T> DepNodeParams<'a, 'gcx, 'tcx> for T
|
impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a, T> DepNodeParams<'a, 'gcx, 'tcx> for T
|
||||||
|
@ -8,9 +8,13 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
|
use ich::Fingerprint;
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
|
use rustc_data_structures::stable_hasher::StableHasher;
|
||||||
use std::env;
|
use std::env;
|
||||||
use super::{DepGraphQuery, DepNode};
|
use std::hash::Hash;
|
||||||
|
use std::mem;
|
||||||
|
use super::{DepGraphQuery, DepKind, DepNode};
|
||||||
use super::debug::EdgeFilter;
|
use super::debug::EdgeFilter;
|
||||||
|
|
||||||
pub struct DepGraphEdges {
|
pub struct DepGraphEdges {
|
||||||
@ -44,6 +48,10 @@ enum OpenTask {
|
|||||||
reads: Vec<DepNode>,
|
reads: Vec<DepNode>,
|
||||||
read_set: FxHashSet<DepNode>,
|
read_set: FxHashSet<DepNode>,
|
||||||
},
|
},
|
||||||
|
Anon {
|
||||||
|
reads: Vec<DepNode>,
|
||||||
|
read_set: FxHashSet<DepNode>,
|
||||||
|
},
|
||||||
Ignore,
|
Ignore,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,6 +122,56 @@ impl DepGraphEdges {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn push_anon_task(&mut self) {
|
||||||
|
self.task_stack.push(OpenTask::Anon {
|
||||||
|
reads: Vec::new(),
|
||||||
|
read_set: FxHashSet(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pop_anon_task(&mut self, kind: DepKind) -> DepNode {
|
||||||
|
let popped_node = self.task_stack.pop().unwrap();
|
||||||
|
|
||||||
|
if let OpenTask::Anon {
|
||||||
|
read_set: _,
|
||||||
|
reads
|
||||||
|
} = popped_node {
|
||||||
|
let mut fingerprint = Fingerprint::zero();
|
||||||
|
let mut hasher = StableHasher::new();
|
||||||
|
|
||||||
|
for read in reads.iter() {
|
||||||
|
mem::discriminant(&read.kind).hash(&mut hasher);
|
||||||
|
|
||||||
|
// Fingerprint::combine() is faster than sending Fingerprint
|
||||||
|
// through the StableHasher (at least as long as StableHasher
|
||||||
|
// is so slow).
|
||||||
|
fingerprint = fingerprint.combine(read.hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
fingerprint = fingerprint.combine(hasher.finish());
|
||||||
|
|
||||||
|
let target_dep_node = DepNode {
|
||||||
|
kind,
|
||||||
|
hash: fingerprint,
|
||||||
|
};
|
||||||
|
|
||||||
|
if self.indices.contains_key(&target_dep_node) {
|
||||||
|
return target_dep_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
let target_id = self.get_or_create_node(target_dep_node);
|
||||||
|
|
||||||
|
for read in reads.into_iter() {
|
||||||
|
let source_id = self.get_or_create_node(read);
|
||||||
|
self.edges.insert((source_id, target_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
target_dep_node
|
||||||
|
} else {
|
||||||
|
bug!("pop_anon_task() - Expected anonymous task to be popped")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Indicates that the current task `C` reads `v` by adding an
|
/// Indicates that the current task `C` reads `v` by adding an
|
||||||
/// edge from `v` to `C`. If there is no current task, has no
|
/// edge from `v` to `C`. If there is no current task, has no
|
||||||
/// effect. Note that *reading* from tracked state is harmless if
|
/// effect. Note that *reading* from tracked state is harmless if
|
||||||
@ -138,6 +196,14 @@ impl DepGraphEdges {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some(&mut OpenTask::Anon {
|
||||||
|
ref mut reads,
|
||||||
|
ref mut read_set,
|
||||||
|
}) => {
|
||||||
|
if read_set.insert(source) {
|
||||||
|
reads.push(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
Some(&mut OpenTask::Ignore) | None => {
|
Some(&mut OpenTask::Ignore) | None => {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ use session::config::OutputType;
|
|||||||
use std::cell::{Ref, RefCell};
|
use std::cell::{Ref, RefCell};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use super::dep_node::{DepNode, WorkProductId};
|
use super::dep_node::{DepNode, DepKind, WorkProductId};
|
||||||
use super::query::DepGraphQuery;
|
use super::query::DepGraphQuery;
|
||||||
use super::raii;
|
use super::raii;
|
||||||
use super::safe::DepGraphSafe;
|
use super::safe::DepGraphSafe;
|
||||||
@ -115,6 +115,21 @@ impl DepGraph {
|
|||||||
task(cx, arg)
|
task(cx, arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Execute something within an "anonymous" task, that is, a task the
|
||||||
|
/// DepNode of which is determined by the list of inputs it read from.
|
||||||
|
pub fn with_anon_task<OP,R>(&self, dep_kind: DepKind, op: OP) -> (R, DepNode)
|
||||||
|
where OP: FnOnce() -> R
|
||||||
|
{
|
||||||
|
if let Some(ref data) = self.data {
|
||||||
|
data.edges.borrow_mut().push_anon_task();
|
||||||
|
let result = op();
|
||||||
|
let dep_node = data.edges.borrow_mut().pop_anon_task(dep_kind);
|
||||||
|
(result, dep_node)
|
||||||
|
} else {
|
||||||
|
(op(), DepNode::new_no_params(DepKind::Krate))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn read(&self, v: DepNode) {
|
pub fn read(&self, v: DepNode) {
|
||||||
if let Some(ref data) = self.data {
|
if let Some(ref data) = self.data {
|
||||||
|
Loading…
Reference in New Issue
Block a user