Auto merge of #57061 - Zoxc:graph-refactor, r=michaelwoerister
Group dep node data into a single structure r? @michaelwoerister
This commit is contained in:
commit
433ef826f0
@ -423,17 +423,6 @@ pub fn to_dep_node(self, tcx: TyCtxt<'_, '_, '_>, kind: DepKind) -> DepNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DepKind {
|
|
||||||
#[inline]
|
|
||||||
pub fn fingerprint_needed_for_crate_hash(self) -> bool {
|
|
||||||
match self {
|
|
||||||
DepKind::HirBody |
|
|
||||||
DepKind::Krate => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
define_dep_nodes!( <'tcx>
|
define_dep_nodes!( <'tcx>
|
||||||
// We use this for most things when incr. comp. is turned off.
|
// We use this for most things when incr. comp. is turned off.
|
||||||
[] Null,
|
[] Null,
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
use rustc_data_structures::sync::{Lrc, Lock};
|
use rustc_data_structures::sync::{Lrc, Lock};
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
use std::collections::hash_map::Entry;
|
||||||
use ty::{self, TyCtxt};
|
use ty::{self, TyCtxt};
|
||||||
use util::common::{ProfileQueriesMsg, profq_msg};
|
use util::common::{ProfileQueriesMsg, profq_msg};
|
||||||
|
|
||||||
@ -21,12 +22,6 @@
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct DepGraph {
|
pub struct DepGraph {
|
||||||
data: Option<Lrc<DepGraphData>>,
|
data: Option<Lrc<DepGraphData>>,
|
||||||
|
|
||||||
// A vector mapping depnodes from the current graph to their associated
|
|
||||||
// result value fingerprints. Do not rely on the length of this vector
|
|
||||||
// being the same as the number of nodes in the graph. The vector can
|
|
||||||
// contain an arbitrary number of zero-entries at the end.
|
|
||||||
fingerprints: Lrc<Lock<IndexVec<DepNodeIndex, Fingerprint>>>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
newtype_index! {
|
newtype_index! {
|
||||||
@ -81,30 +76,23 @@ impl DepGraph {
|
|||||||
|
|
||||||
pub fn new(prev_graph: PreviousDepGraph,
|
pub fn new(prev_graph: PreviousDepGraph,
|
||||||
prev_work_products: FxHashMap<WorkProductId, WorkProduct>) -> DepGraph {
|
prev_work_products: FxHashMap<WorkProductId, WorkProduct>) -> DepGraph {
|
||||||
// Pre-allocate the fingerprints array. We over-allocate a little so
|
|
||||||
// that we hopefully don't have to re-allocate during this compilation
|
|
||||||
// session.
|
|
||||||
let prev_graph_node_count = prev_graph.node_count();
|
let prev_graph_node_count = prev_graph.node_count();
|
||||||
|
|
||||||
let fingerprints = IndexVec::from_elem_n(Fingerprint::ZERO,
|
|
||||||
(prev_graph_node_count * 115) / 100);
|
|
||||||
DepGraph {
|
DepGraph {
|
||||||
data: Some(Lrc::new(DepGraphData {
|
data: Some(Lrc::new(DepGraphData {
|
||||||
previous_work_products: prev_work_products,
|
previous_work_products: prev_work_products,
|
||||||
dep_node_debug: Default::default(),
|
dep_node_debug: Default::default(),
|
||||||
current: Lock::new(CurrentDepGraph::new()),
|
current: Lock::new(CurrentDepGraph::new(prev_graph_node_count)),
|
||||||
previous: prev_graph,
|
previous: prev_graph,
|
||||||
colors: Lock::new(DepNodeColorMap::new(prev_graph_node_count)),
|
colors: Lock::new(DepNodeColorMap::new(prev_graph_node_count)),
|
||||||
loaded_from_cache: Default::default(),
|
loaded_from_cache: Default::default(),
|
||||||
})),
|
})),
|
||||||
fingerprints: Lrc::new(Lock::new(fingerprints)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_disabled() -> DepGraph {
|
pub fn new_disabled() -> DepGraph {
|
||||||
DepGraph {
|
DepGraph {
|
||||||
data: None,
|
data: None,
|
||||||
fingerprints: Lrc::new(Lock::new(IndexVec::new())),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,12 +104,12 @@ pub fn is_fully_enabled(&self) -> bool {
|
|||||||
|
|
||||||
pub fn query(&self) -> DepGraphQuery {
|
pub fn query(&self) -> DepGraphQuery {
|
||||||
let current_dep_graph = self.data.as_ref().unwrap().current.borrow();
|
let current_dep_graph = self.data.as_ref().unwrap().current.borrow();
|
||||||
let nodes: Vec<_> = current_dep_graph.nodes.iter().cloned().collect();
|
let nodes: Vec<_> = current_dep_graph.data.iter().map(|n| n.node).collect();
|
||||||
let mut edges = Vec::new();
|
let mut edges = Vec::new();
|
||||||
for (index, edge_targets) in current_dep_graph.edges.iter_enumerated() {
|
for (from, edge_targets) in current_dep_graph.data.iter()
|
||||||
let from = current_dep_graph.nodes[index];
|
.map(|d| (d.node, &d.edges)) {
|
||||||
for &edge_target in edge_targets.iter() {
|
for &edge_target in edge_targets.iter() {
|
||||||
let to = current_dep_graph.nodes[edge_target];
|
let to = current_dep_graph.data[edge_target].node;
|
||||||
edges.push((from, to));
|
edges.push((from, to));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -201,7 +189,7 @@ pub fn with_task<'gcx, C, A, R>(&self,
|
|||||||
reads: SmallVec::new(),
|
reads: SmallVec::new(),
|
||||||
read_set: Default::default(),
|
read_set: Default::default(),
|
||||||
})),
|
})),
|
||||||
|data, key, task| data.borrow_mut().complete_task(key, task))
|
|data, key, fingerprint, task| data.borrow_mut().complete_task(key, task, fingerprint))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new dep-graph input with value `input`
|
/// Creates a new dep-graph input with value `input`
|
||||||
@ -219,7 +207,9 @@ fn identity_fn<C, A>(_: C, arg: A) -> A {
|
|||||||
|
|
||||||
self.with_task_impl(key, cx, input, true, identity_fn,
|
self.with_task_impl(key, cx, input, true, identity_fn,
|
||||||
|_| OpenTask::Ignore,
|
|_| OpenTask::Ignore,
|
||||||
|data, key, _| data.borrow_mut().alloc_node(key, SmallVec::new()))
|
|data, key, fingerprint, _| {
|
||||||
|
data.borrow_mut().alloc_node(key, SmallVec::new(), fingerprint)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_task_impl<'gcx, C, A, R>(
|
fn with_task_impl<'gcx, C, A, R>(
|
||||||
@ -232,6 +222,7 @@ fn with_task_impl<'gcx, C, A, R>(
|
|||||||
create_task: fn(DepNode) -> OpenTask,
|
create_task: fn(DepNode) -> OpenTask,
|
||||||
finish_task_and_alloc_depnode: fn(&Lock<CurrentDepGraph>,
|
finish_task_and_alloc_depnode: fn(&Lock<CurrentDepGraph>,
|
||||||
DepNode,
|
DepNode,
|
||||||
|
Fingerprint,
|
||||||
OpenTask) -> DepNodeIndex
|
OpenTask) -> DepNodeIndex
|
||||||
) -> (R, DepNodeIndex)
|
) -> (R, DepNodeIndex)
|
||||||
where
|
where
|
||||||
@ -271,26 +262,17 @@ fn with_task_impl<'gcx, C, A, R>(
|
|||||||
profq_msg(hcx.sess(), ProfileQueriesMsg::TaskEnd)
|
profq_msg(hcx.sess(), ProfileQueriesMsg::TaskEnd)
|
||||||
};
|
};
|
||||||
|
|
||||||
let dep_node_index = finish_task_and_alloc_depnode(&data.current, key, open_task);
|
|
||||||
|
|
||||||
let mut stable_hasher = StableHasher::new();
|
let mut stable_hasher = StableHasher::new();
|
||||||
result.hash_stable(&mut hcx, &mut stable_hasher);
|
result.hash_stable(&mut hcx, &mut stable_hasher);
|
||||||
|
|
||||||
let current_fingerprint = stable_hasher.finish();
|
let current_fingerprint = stable_hasher.finish();
|
||||||
|
|
||||||
// Store the current fingerprint
|
let dep_node_index = finish_task_and_alloc_depnode(
|
||||||
{
|
&data.current,
|
||||||
let mut fingerprints = self.fingerprints.borrow_mut();
|
key,
|
||||||
|
current_fingerprint,
|
||||||
if dep_node_index.index() >= fingerprints.len() {
|
open_task
|
||||||
fingerprints.resize(dep_node_index.index() + 1, Fingerprint::ZERO);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
debug_assert!(fingerprints[dep_node_index] == Fingerprint::ZERO,
|
|
||||||
"DepGraph::with_task() - Duplicate fingerprint \
|
|
||||||
insertion for {:?}", key);
|
|
||||||
fingerprints[dep_node_index] = current_fingerprint;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine the color of the new DepNode.
|
// Determine the color of the new DepNode.
|
||||||
if let Some(prev_index) = data.previous.node_to_index_opt(&key) {
|
if let Some(prev_index) = data.previous.node_to_index_opt(&key) {
|
||||||
@ -310,29 +292,11 @@ fn with_task_impl<'gcx, C, A, R>(
|
|||||||
colors.insert(prev_index, color);
|
colors.insert(prev_index, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
(result, dep_node_index)
|
|
||||||
} else {
|
|
||||||
if key.kind.fingerprint_needed_for_crate_hash() {
|
|
||||||
let mut hcx = cx.get_stable_hashing_context();
|
|
||||||
let result = task(cx, arg);
|
|
||||||
let mut stable_hasher = StableHasher::new();
|
|
||||||
result.hash_stable(&mut hcx, &mut stable_hasher);
|
|
||||||
let fingerprint = stable_hasher.finish();
|
|
||||||
|
|
||||||
let mut fingerprints = self.fingerprints.borrow_mut();
|
|
||||||
let dep_node_index = DepNodeIndex::new(fingerprints.len());
|
|
||||||
fingerprints.push(fingerprint);
|
|
||||||
|
|
||||||
debug_assert!(fingerprints[dep_node_index] == fingerprint,
|
|
||||||
"DepGraph::with_task() - Assigned fingerprint to \
|
|
||||||
unexpected index for {:?}", key);
|
|
||||||
|
|
||||||
(result, dep_node_index)
|
(result, dep_node_index)
|
||||||
} else {
|
} else {
|
||||||
(task(cx, arg), DepNodeIndex::INVALID)
|
(task(cx, arg), DepNodeIndex::INVALID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// Execute something within an "anonymous" task, that is, a task the
|
/// Execute something within an "anonymous" task, that is, a task the
|
||||||
/// DepNode of which is determined by the list of inputs it read from.
|
/// DepNode of which is determined by the list of inputs it read from.
|
||||||
@ -381,7 +345,9 @@ pub fn with_eval_always_task<'gcx, C, A, R>(&self,
|
|||||||
{
|
{
|
||||||
self.with_task_impl(key, cx, arg, false, task,
|
self.with_task_impl(key, cx, arg, false, task,
|
||||||
|key| OpenTask::EvalAlways { node: key },
|
|key| OpenTask::EvalAlways { node: key },
|
||||||
|data, key, task| data.borrow_mut().complete_eval_always_task(key, task))
|
|data, key, fingerprint, task| {
|
||||||
|
data.borrow_mut().complete_eval_always_task(key, task, fingerprint)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -427,17 +393,8 @@ pub fn dep_node_exists(&self, dep_node: &DepNode) -> bool {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn fingerprint_of(&self, dep_node_index: DepNodeIndex) -> Fingerprint {
|
pub fn fingerprint_of(&self, dep_node_index: DepNodeIndex) -> Fingerprint {
|
||||||
match self.fingerprints.borrow().get(dep_node_index) {
|
let current = self.data.as_ref().expect("dep graph enabled").current.borrow_mut();
|
||||||
Some(&fingerprint) => fingerprint,
|
current.data[dep_node_index].fingerprint
|
||||||
None => {
|
|
||||||
if let Some(ref data) = self.data {
|
|
||||||
let dep_node = data.current.borrow().nodes[dep_node_index];
|
|
||||||
bug!("Could not find current fingerprint for {:?}", dep_node)
|
|
||||||
} else {
|
|
||||||
bug!("Could not find current fingerprint for {:?}", dep_node_index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prev_fingerprint_of(&self, dep_node: &DepNode) -> Option<Fingerprint> {
|
pub fn prev_fingerprint_of(&self, dep_node: &DepNode) -> Option<Fingerprint> {
|
||||||
@ -498,17 +455,20 @@ pub fn edge_deduplication_data(&self) -> (u64, u64) {
|
|||||||
pub fn serialize(&self) -> SerializedDepGraph {
|
pub fn serialize(&self) -> SerializedDepGraph {
|
||||||
let current_dep_graph = self.data.as_ref().unwrap().current.borrow();
|
let current_dep_graph = self.data.as_ref().unwrap().current.borrow();
|
||||||
|
|
||||||
let fingerprints = self.fingerprints.borrow().clone().convert_index_type();
|
let fingerprints: IndexVec<SerializedDepNodeIndex, _> =
|
||||||
let nodes = current_dep_graph.nodes.clone().convert_index_type();
|
current_dep_graph.data.iter().map(|d| d.fingerprint).collect();
|
||||||
|
let nodes: IndexVec<SerializedDepNodeIndex, _> =
|
||||||
|
current_dep_graph.data.iter().map(|d| d.node).collect();
|
||||||
|
|
||||||
let total_edge_count: usize = current_dep_graph.edges.iter()
|
let total_edge_count: usize = current_dep_graph.data.iter()
|
||||||
.map(|v| v.len())
|
.map(|d| d.edges.len())
|
||||||
.sum();
|
.sum();
|
||||||
|
|
||||||
let mut edge_list_indices = IndexVec::with_capacity(nodes.len());
|
let mut edge_list_indices = IndexVec::with_capacity(nodes.len());
|
||||||
let mut edge_list_data = Vec::with_capacity(total_edge_count);
|
let mut edge_list_data = Vec::with_capacity(total_edge_count);
|
||||||
|
|
||||||
for (current_dep_node_index, edges) in current_dep_graph.edges.iter_enumerated() {
|
for (current_dep_node_index, edges) in current_dep_graph.data.iter_enumerated()
|
||||||
|
.map(|(i, d)| (i, &d.edges)) {
|
||||||
let start = edge_list_data.len() as u32;
|
let start = edge_list_data.len() as u32;
|
||||||
// This should really just be a memcpy :/
|
// This should really just be a memcpy :/
|
||||||
edge_list_data.extend(edges.iter().map(|i| SerializedDepNodeIndex::new(i.index())));
|
edge_list_data.extend(edges.iter().map(|i| SerializedDepNodeIndex::new(i.index())));
|
||||||
@ -700,35 +660,15 @@ pub fn try_mark_green<'tcx>(&self,
|
|||||||
let (dep_node_index, did_allocation) = {
|
let (dep_node_index, did_allocation) = {
|
||||||
let mut current = data.current.borrow_mut();
|
let mut current = data.current.borrow_mut();
|
||||||
|
|
||||||
if let Some(&dep_node_index) = current.node_to_node_index.get(&dep_node) {
|
// Copy the fingerprint from the previous graph,
|
||||||
// Someone else allocated it before us
|
// so we don't have to recompute it
|
||||||
(dep_node_index, false)
|
let fingerprint = data.previous.fingerprint_by_index(prev_dep_node_index);
|
||||||
} else {
|
|
||||||
// We allocating an entry for the node in the current dependency graph and
|
// We allocating an entry for the node in the current dependency graph and
|
||||||
// adding all the appropriate edges imported from the previous graph
|
// adding all the appropriate edges imported from the previous graph
|
||||||
(current.alloc_node(*dep_node, current_deps), true)
|
current.intern_node(*dep_node, current_deps, fingerprint)
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ... copying the fingerprint from the previous graph too, so we don't
|
|
||||||
// have to recompute it ...
|
|
||||||
{
|
|
||||||
let fingerprint = data.previous.fingerprint_by_index(prev_dep_node_index);
|
|
||||||
let mut fingerprints = self.fingerprints.borrow_mut();
|
|
||||||
|
|
||||||
if dep_node_index.index() >= fingerprints.len() {
|
|
||||||
fingerprints.resize(dep_node_index.index() + 1, Fingerprint::ZERO);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Multiple threads can all write the same fingerprint here
|
|
||||||
#[cfg(not(parallel_queries))]
|
|
||||||
debug_assert!(fingerprints[dep_node_index] == Fingerprint::ZERO,
|
|
||||||
"DepGraph::try_mark_green() - Duplicate fingerprint \
|
|
||||||
insertion for {:?}", dep_node);
|
|
||||||
|
|
||||||
fingerprints[dep_node_index] = fingerprint;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ... emitting any stored diagnostic ...
|
// ... emitting any stored diagnostic ...
|
||||||
if did_allocation {
|
if did_allocation {
|
||||||
// Only the thread which did the allocation emits the error messages
|
// Only the thread which did the allocation emits the error messages
|
||||||
@ -814,7 +754,7 @@ pub fn exec_cache_promotions<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
|||||||
|
|
||||||
pub fn mark_loaded_from_cache(&self, dep_node_index: DepNodeIndex, state: bool) {
|
pub fn mark_loaded_from_cache(&self, dep_node_index: DepNodeIndex, state: bool) {
|
||||||
debug!("mark_loaded_from_cache({:?}, {})",
|
debug!("mark_loaded_from_cache({:?}, {})",
|
||||||
self.data.as_ref().unwrap().current.borrow().nodes[dep_node_index],
|
self.data.as_ref().unwrap().current.borrow().data[dep_node_index].node,
|
||||||
state);
|
state);
|
||||||
|
|
||||||
self.data
|
self.data
|
||||||
@ -877,9 +817,15 @@ pub enum WorkProductFileKind {
|
|||||||
BytecodeCompressed,
|
BytecodeCompressed,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct DepNodeData {
|
||||||
|
node: DepNode,
|
||||||
|
edges: SmallVec<[DepNodeIndex; 8]>,
|
||||||
|
fingerprint: Fingerprint,
|
||||||
|
}
|
||||||
|
|
||||||
pub(super) struct CurrentDepGraph {
|
pub(super) struct CurrentDepGraph {
|
||||||
nodes: IndexVec<DepNodeIndex, DepNode>,
|
data: IndexVec<DepNodeIndex, DepNodeData>,
|
||||||
edges: IndexVec<DepNodeIndex, SmallVec<[DepNodeIndex; 8]>>,
|
|
||||||
node_to_node_index: FxHashMap<DepNode, DepNodeIndex>,
|
node_to_node_index: FxHashMap<DepNode, DepNodeIndex>,
|
||||||
forbidden_edge: Option<EdgeFilter>,
|
forbidden_edge: Option<EdgeFilter>,
|
||||||
|
|
||||||
@ -901,7 +847,7 @@ pub(super) struct CurrentDepGraph {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CurrentDepGraph {
|
impl CurrentDepGraph {
|
||||||
fn new() -> CurrentDepGraph {
|
fn new(prev_graph_node_count: usize) -> CurrentDepGraph {
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
let duration = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
|
let duration = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
|
||||||
@ -924,10 +870,17 @@ fn new() -> CurrentDepGraph {
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Pre-allocate the dep node structures. We over-allocate a little so
|
||||||
|
// that we hopefully don't have to re-allocate during this compilation
|
||||||
|
// session.
|
||||||
|
let new_node_count_estimate = (prev_graph_node_count * 115) / 100;
|
||||||
|
|
||||||
CurrentDepGraph {
|
CurrentDepGraph {
|
||||||
nodes: IndexVec::new(),
|
data: IndexVec::with_capacity(new_node_count_estimate),
|
||||||
edges: IndexVec::new(),
|
node_to_node_index: FxHashMap::with_capacity_and_hasher(
|
||||||
node_to_node_index: Default::default(),
|
new_node_count_estimate,
|
||||||
|
Default::default(),
|
||||||
|
),
|
||||||
anon_id_seed: stable_hasher.finish(),
|
anon_id_seed: stable_hasher.finish(),
|
||||||
forbidden_edge,
|
forbidden_edge,
|
||||||
total_read_count: 0,
|
total_read_count: 0,
|
||||||
@ -935,7 +888,12 @@ fn new() -> CurrentDepGraph {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn complete_task(&mut self, key: DepNode, task: OpenTask) -> DepNodeIndex {
|
fn complete_task(
|
||||||
|
&mut self,
|
||||||
|
key: DepNode,
|
||||||
|
task: OpenTask,
|
||||||
|
fingerprint: Fingerprint
|
||||||
|
) -> DepNodeIndex {
|
||||||
if let OpenTask::Regular(task) = task {
|
if let OpenTask::Regular(task) = task {
|
||||||
let RegularOpenTask {
|
let RegularOpenTask {
|
||||||
node,
|
node,
|
||||||
@ -956,17 +914,17 @@ fn complete_task(&mut self, key: DepNode, task: OpenTask) -> DepNodeIndex {
|
|||||||
// better in general.
|
// better in general.
|
||||||
node.kind != DepKind::DefSpan &&
|
node.kind != DepKind::DefSpan &&
|
||||||
reads.iter().any(|&i| {
|
reads.iter().any(|&i| {
|
||||||
!(self.nodes[i].kind == DepKind::CrateMetadata ||
|
!(self.data[i].node.kind == DepKind::CrateMetadata ||
|
||||||
self.nodes[i].kind == DepKind::Krate)
|
self.data[i].node.kind == DepKind::Krate)
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
bug!("Input node {:?} with unexpected reads: {:?}",
|
bug!("Input node {:?} with unexpected reads: {:?}",
|
||||||
node,
|
node,
|
||||||
reads.iter().map(|&i| self.nodes[i]).collect::<Vec<_>>())
|
reads.iter().map(|&i| self.data[i].node).collect::<Vec<_>>())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.alloc_node(node, reads)
|
self.alloc_node(node, reads, fingerprint)
|
||||||
} else {
|
} else {
|
||||||
bug!("complete_task() - Expected regular task to be popped")
|
bug!("complete_task() - Expected regular task to be popped")
|
||||||
}
|
}
|
||||||
@ -984,7 +942,7 @@ fn pop_anon_task(&mut self, kind: DepKind, task: OpenTask) -> DepNodeIndex {
|
|||||||
let mut hasher = StableHasher::new();
|
let mut hasher = StableHasher::new();
|
||||||
|
|
||||||
for &read in reads.iter() {
|
for &read in reads.iter() {
|
||||||
let read_dep_node = self.nodes[read];
|
let read_dep_node = self.data[read].node;
|
||||||
|
|
||||||
::std::mem::discriminant(&read_dep_node.kind).hash(&mut hasher);
|
::std::mem::discriminant(&read_dep_node.kind).hash(&mut hasher);
|
||||||
|
|
||||||
@ -1001,23 +959,24 @@ fn pop_anon_task(&mut self, kind: DepKind, task: OpenTask) -> DepNodeIndex {
|
|||||||
hash: fingerprint,
|
hash: fingerprint,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(&index) = self.node_to_node_index.get(&target_dep_node) {
|
self.intern_node(target_dep_node, reads, Fingerprint::ZERO).0
|
||||||
index
|
|
||||||
} else {
|
|
||||||
self.alloc_node(target_dep_node, reads)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
bug!("pop_anon_task() - Expected anonymous task to be popped")
|
bug!("pop_anon_task() - Expected anonymous task to be popped")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn complete_eval_always_task(&mut self, key: DepNode, task: OpenTask) -> DepNodeIndex {
|
fn complete_eval_always_task(
|
||||||
|
&mut self,
|
||||||
|
key: DepNode,
|
||||||
|
task: OpenTask,
|
||||||
|
fingerprint: Fingerprint
|
||||||
|
) -> DepNodeIndex {
|
||||||
if let OpenTask::EvalAlways {
|
if let OpenTask::EvalAlways {
|
||||||
node,
|
node,
|
||||||
} = task {
|
} = task {
|
||||||
debug_assert_eq!(node, key);
|
debug_assert_eq!(node, key);
|
||||||
let krate_idx = self.node_to_node_index[&DepNode::new_no_params(DepKind::Krate)];
|
let krate_idx = self.node_to_node_index[&DepNode::new_no_params(DepKind::Krate)];
|
||||||
self.alloc_node(node, smallvec![krate_idx])
|
self.alloc_node(node, smallvec![krate_idx], fingerprint)
|
||||||
} else {
|
} else {
|
||||||
bug!("complete_eval_always_task() - Expected eval always task to be popped");
|
bug!("complete_eval_always_task() - Expected eval always task to be popped");
|
||||||
}
|
}
|
||||||
@ -1036,7 +995,7 @@ fn read_index(&mut self, source: DepNodeIndex) {
|
|||||||
if cfg!(debug_assertions) {
|
if cfg!(debug_assertions) {
|
||||||
if let Some(ref forbidden_edge) = self.forbidden_edge {
|
if let Some(ref forbidden_edge) = self.forbidden_edge {
|
||||||
let target = &task.node;
|
let target = &task.node;
|
||||||
let source = self.nodes[source];
|
let source = self.data[source].node;
|
||||||
if forbidden_edge.test(&source, &target) {
|
if forbidden_edge.test(&source, &target) {
|
||||||
bug!("forbidden edge {:?} -> {:?} created",
|
bug!("forbidden edge {:?} -> {:?} created",
|
||||||
source,
|
source,
|
||||||
@ -1061,18 +1020,37 @@ fn read_index(&mut self, source: DepNodeIndex) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn alloc_node(&mut self,
|
fn alloc_node(
|
||||||
|
&mut self,
|
||||||
dep_node: DepNode,
|
dep_node: DepNode,
|
||||||
edges: SmallVec<[DepNodeIndex; 8]>)
|
edges: SmallVec<[DepNodeIndex; 8]>,
|
||||||
-> DepNodeIndex {
|
fingerprint: Fingerprint
|
||||||
debug_assert_eq!(self.edges.len(), self.nodes.len());
|
) -> DepNodeIndex {
|
||||||
debug_assert_eq!(self.node_to_node_index.len(), self.nodes.len());
|
|
||||||
debug_assert!(!self.node_to_node_index.contains_key(&dep_node));
|
debug_assert!(!self.node_to_node_index.contains_key(&dep_node));
|
||||||
let dep_node_index = DepNodeIndex::new(self.nodes.len());
|
self.intern_node(dep_node, edges, fingerprint).0
|
||||||
self.nodes.push(dep_node);
|
}
|
||||||
self.node_to_node_index.insert(dep_node, dep_node_index);
|
|
||||||
self.edges.push(edges);
|
fn intern_node(
|
||||||
dep_node_index
|
&mut self,
|
||||||
|
dep_node: DepNode,
|
||||||
|
edges: SmallVec<[DepNodeIndex; 8]>,
|
||||||
|
fingerprint: Fingerprint
|
||||||
|
) -> (DepNodeIndex, bool) {
|
||||||
|
debug_assert_eq!(self.node_to_node_index.len(), self.data.len());
|
||||||
|
|
||||||
|
match self.node_to_node_index.entry(dep_node) {
|
||||||
|
Entry::Occupied(entry) => (*entry.get(), false),
|
||||||
|
Entry::Vacant(entry) => {
|
||||||
|
let dep_node_index = DepNodeIndex::new(self.data.len());
|
||||||
|
self.data.push(DepNodeData {
|
||||||
|
node: dep_node,
|
||||||
|
edges,
|
||||||
|
fingerprint
|
||||||
|
});
|
||||||
|
entry.insert(dep_node_index);
|
||||||
|
(dep_node_index, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,21 +41,69 @@ pub(super) struct NodeCollector<'a, 'hir> {
|
|||||||
|
|
||||||
// We are collecting DepNode::HirBody hashes here so we can compute the
|
// We are collecting DepNode::HirBody hashes here so we can compute the
|
||||||
// crate hash from then later on.
|
// crate hash from then later on.
|
||||||
hir_body_nodes: Vec<(DefPathHash, DepNodeIndex)>,
|
hir_body_nodes: Vec<(DefPathHash, Fingerprint)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn input_dep_node_and_hash<'a, I>(
|
||||||
|
dep_graph: &DepGraph,
|
||||||
|
hcx: &mut StableHashingContext<'a>,
|
||||||
|
dep_node: DepNode,
|
||||||
|
input: I,
|
||||||
|
) -> (DepNodeIndex, Fingerprint)
|
||||||
|
where
|
||||||
|
I: HashStable<StableHashingContext<'a>>,
|
||||||
|
{
|
||||||
|
let dep_node_index = dep_graph.input_task(dep_node, &mut *hcx, &input).1;
|
||||||
|
|
||||||
|
let hash = if dep_graph.is_fully_enabled() {
|
||||||
|
dep_graph.fingerprint_of(dep_node_index)
|
||||||
|
} else {
|
||||||
|
let mut stable_hasher = StableHasher::new();
|
||||||
|
input.hash_stable(hcx, &mut stable_hasher);
|
||||||
|
stable_hasher.finish()
|
||||||
|
};
|
||||||
|
|
||||||
|
(dep_node_index, hash)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn alloc_hir_dep_nodes<'a, I>(
|
||||||
|
dep_graph: &DepGraph,
|
||||||
|
hcx: &mut StableHashingContext<'a>,
|
||||||
|
def_path_hash: DefPathHash,
|
||||||
|
item_like: I,
|
||||||
|
hir_body_nodes: &mut Vec<(DefPathHash, Fingerprint)>,
|
||||||
|
) -> (DepNodeIndex, DepNodeIndex)
|
||||||
|
where
|
||||||
|
I: HashStable<StableHashingContext<'a>>,
|
||||||
|
{
|
||||||
|
let sig = dep_graph.input_task(
|
||||||
|
def_path_hash.to_dep_node(DepKind::Hir),
|
||||||
|
&mut *hcx,
|
||||||
|
HirItemLike { item_like: &item_like, hash_bodies: false },
|
||||||
|
).1;
|
||||||
|
let (full, hash) = input_dep_node_and_hash(
|
||||||
|
dep_graph,
|
||||||
|
hcx,
|
||||||
|
def_path_hash.to_dep_node(DepKind::HirBody),
|
||||||
|
HirItemLike { item_like: &item_like, hash_bodies: true },
|
||||||
|
);
|
||||||
|
hir_body_nodes.push((def_path_hash, hash));
|
||||||
|
(sig, full)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'hir> NodeCollector<'a, 'hir> {
|
impl<'a, 'hir> NodeCollector<'a, 'hir> {
|
||||||
pub(super) fn root(krate: &'hir Crate,
|
pub(super) fn root(krate: &'hir Crate,
|
||||||
dep_graph: &'a DepGraph,
|
dep_graph: &'a DepGraph,
|
||||||
definitions: &'a definitions::Definitions,
|
definitions: &'a definitions::Definitions,
|
||||||
hcx: StableHashingContext<'a>,
|
mut hcx: StableHashingContext<'a>,
|
||||||
source_map: &'a SourceMap)
|
source_map: &'a SourceMap)
|
||||||
-> NodeCollector<'a, 'hir> {
|
-> NodeCollector<'a, 'hir> {
|
||||||
let root_mod_def_path_hash = definitions.def_path_hash(CRATE_DEF_INDEX);
|
let root_mod_def_path_hash = definitions.def_path_hash(CRATE_DEF_INDEX);
|
||||||
|
|
||||||
|
let mut hir_body_nodes = Vec::new();
|
||||||
|
|
||||||
// Allocate DepNodes for the root module
|
// Allocate DepNodes for the root module
|
||||||
let (root_mod_sig_dep_index, root_mod_full_dep_index);
|
let (root_mod_sig_dep_index, root_mod_full_dep_index) = {
|
||||||
{
|
|
||||||
let Crate {
|
let Crate {
|
||||||
ref module,
|
ref module,
|
||||||
// Crate attributes are not copied over to the root `Mod`, so hash
|
// Crate attributes are not copied over to the root `Mod`, so hash
|
||||||
@ -73,28 +121,23 @@ pub(super) fn root(krate: &'hir Crate,
|
|||||||
body_ids: _,
|
body_ids: _,
|
||||||
} = *krate;
|
} = *krate;
|
||||||
|
|
||||||
root_mod_sig_dep_index = dep_graph.input_task(
|
alloc_hir_dep_nodes(
|
||||||
root_mod_def_path_hash.to_dep_node(DepKind::Hir),
|
dep_graph,
|
||||||
&hcx,
|
&mut hcx,
|
||||||
HirItemLike { item_like: (module, attrs, span), hash_bodies: false },
|
root_mod_def_path_hash,
|
||||||
).1;
|
(module, attrs, span),
|
||||||
root_mod_full_dep_index = dep_graph.input_task(
|
&mut hir_body_nodes,
|
||||||
root_mod_def_path_hash.to_dep_node(DepKind::HirBody),
|
)
|
||||||
&hcx,
|
};
|
||||||
HirItemLike { item_like: (module, attrs, span), hash_bodies: true },
|
|
||||||
).1;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
dep_graph.input_task(
|
dep_graph.input_task(
|
||||||
DepNode::new_no_params(DepKind::AllLocalTraitImpls),
|
DepNode::new_no_params(DepKind::AllLocalTraitImpls),
|
||||||
&hcx,
|
&mut hcx,
|
||||||
&krate.trait_impls,
|
&krate.trait_impls,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let hir_body_nodes = vec![(root_mod_def_path_hash, root_mod_full_dep_index)];
|
|
||||||
|
|
||||||
let mut collector = NodeCollector {
|
let mut collector = NodeCollector {
|
||||||
krate,
|
krate,
|
||||||
source_map,
|
source_map,
|
||||||
@ -129,10 +172,8 @@ pub(super) fn finalize_and_compute_crate_hash(mut self,
|
|||||||
let node_hashes = self
|
let node_hashes = self
|
||||||
.hir_body_nodes
|
.hir_body_nodes
|
||||||
.iter()
|
.iter()
|
||||||
.fold(Fingerprint::ZERO, |fingerprint, &(def_path_hash, dep_node_index)| {
|
.fold(Fingerprint::ZERO, |combined_fingerprint, &(def_path_hash, fingerprint)| {
|
||||||
fingerprint.combine(
|
combined_fingerprint.combine(def_path_hash.0.combine(fingerprint))
|
||||||
def_path_hash.0.combine(self.dep_graph.fingerprint_of(dep_node_index))
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut upstream_crates: Vec<_> = cstore.crates_untracked().iter().map(|&cnum| {
|
let mut upstream_crates: Vec<_> = cstore.crates_untracked().iter().map(|&cnum| {
|
||||||
@ -159,17 +200,19 @@ pub(super) fn finalize_and_compute_crate_hash(mut self,
|
|||||||
|
|
||||||
source_file_names.sort_unstable();
|
source_file_names.sort_unstable();
|
||||||
|
|
||||||
let (_, crate_dep_node_index) = self
|
let crate_hash_input = (
|
||||||
.dep_graph
|
((node_hashes, upstream_crates), source_file_names),
|
||||||
.input_task(DepNode::new_no_params(DepKind::Krate),
|
(commandline_args_hash, crate_disambiguator.to_fingerprint())
|
||||||
&self.hcx,
|
);
|
||||||
(((node_hashes, upstream_crates), source_file_names),
|
|
||||||
(commandline_args_hash,
|
|
||||||
crate_disambiguator.to_fingerprint())));
|
|
||||||
|
|
||||||
let svh = Svh::new(self.dep_graph
|
let (_, crate_hash) = input_dep_node_and_hash(
|
||||||
.fingerprint_of(crate_dep_node_index)
|
self.dep_graph,
|
||||||
.to_smaller_hash());
|
&mut self.hcx,
|
||||||
|
DepNode::new_no_params(DepKind::Krate),
|
||||||
|
crate_hash_input,
|
||||||
|
);
|
||||||
|
|
||||||
|
let svh = Svh::new(crate_hash.to_smaller_hash());
|
||||||
(self.map, svh)
|
(self.map, svh)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,19 +294,15 @@ fn with_dep_node_owner<T: HashStable<StableHashingContext<'a>>,
|
|||||||
|
|
||||||
let def_path_hash = self.definitions.def_path_hash(dep_node_owner);
|
let def_path_hash = self.definitions.def_path_hash(dep_node_owner);
|
||||||
|
|
||||||
self.current_signature_dep_index = self.dep_graph.input_task(
|
let (signature_dep_index, full_dep_index) = alloc_hir_dep_nodes(
|
||||||
def_path_hash.to_dep_node(DepKind::Hir),
|
self.dep_graph,
|
||||||
&self.hcx,
|
&mut self.hcx,
|
||||||
HirItemLike { item_like, hash_bodies: false },
|
def_path_hash,
|
||||||
).1;
|
item_like,
|
||||||
|
&mut self.hir_body_nodes,
|
||||||
self.current_full_dep_index = self.dep_graph.input_task(
|
);
|
||||||
def_path_hash.to_dep_node(DepKind::HirBody),
|
self.current_signature_dep_index = signature_dep_index;
|
||||||
&self.hcx,
|
self.current_full_dep_index = full_dep_index;
|
||||||
HirItemLike { item_like, hash_bodies: true },
|
|
||||||
).1;
|
|
||||||
|
|
||||||
self.hir_body_nodes.push((def_path_hash, self.current_full_dep_index));
|
|
||||||
|
|
||||||
self.current_dep_node_owner = dep_node_owner;
|
self.current_dep_node_owner = dep_node_owner;
|
||||||
self.currently_in_body = false;
|
self.currently_in_body = false;
|
||||||
|
Loading…
Reference in New Issue
Block a user