Skip to content

Commit a9de504

Browse files
committed
Keep the previous dep-graph separately allocated.
1 parent 8e33f21 commit a9de504

File tree

2 files changed

+276
-189
lines changed

2 files changed

+276
-189
lines changed

compiler/rustc_query_system/src/dep_graph/graph.rs

Lines changed: 13 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ use std::sync::atomic::Ordering::Relaxed;
1616

1717
use super::debug::EdgeFilter;
1818
use super::query::DepGraphQuery;
19-
use super::serialized::{DepNodeColor, DepNodeIndex, SerializedDepGraph, SerializedDepNodeIndex};
19+
use super::serialized::{
20+
CurrentDepGraph, DepNodeColor, DepNodeIndex, SerializedDepGraph, SerializedDepNodeIndex,
21+
};
2022
use super::{DepContext, DepKind, DepNode, HasDepContext, WorkProductId};
2123
use crate::query::QueryContext;
2224

@@ -45,7 +47,7 @@ impl std::convert::From<DepNodeIndex> for QueryInvocationId {
4547
struct DepGraphData<K: DepKind> {
4648
/// The dep-graph from the previous compilation session. It contains all
4749
/// nodes and edges as well as all fingerprints of nodes that have them.
48-
previous: RwLock<SerializedDepGraph<K>>,
50+
previous: RwLock<CurrentDepGraph<K>>,
4951

5052
/// Used to trap when a specific edge is added to the graph.
5153
/// This is used for debug purposes and is only active with `debug_assertions`.
@@ -97,8 +99,6 @@ impl<K: DepKind> DepGraph<K> {
9799
prev_graph: SerializedDepGraph<K>,
98100
prev_work_products: FxHashMap<WorkProductId, WorkProduct>,
99101
) -> DepGraph<K> {
100-
let _prev_graph_node_count = prev_graph.serialized_node_count();
101-
102102
use std::time::{SystemTime, UNIX_EPOCH};
103103

104104
let duration = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
@@ -118,41 +118,6 @@ impl<K: DepKind> DepGraph<K> {
118118
None
119119
};
120120

121-
/*
122-
// Pre-allocate the dep node structures. We over-allocate a little so
123-
// that we hopefully don't have to re-allocate during this compilation
124-
// session. The over-allocation for new nodes is 2% plus a small
125-
// constant to account for the fact that in very small crates 2% might
126-
// not be enough. The allocation for red and green node data doesn't
127-
// include a constant, as we don't want to allocate anything for these
128-
// structures during full incremental builds, where they aren't used.
129-
//
130-
// These estimates are based on the distribution of node and edge counts
131-
// seen in rustc-perf benchmarks, adjusted somewhat to account for the
132-
// fact that these benchmarks aren't perfectly representative.
133-
//
134-
// FIXME Use a collection type that doesn't copy node and edge data and
135-
// grow multiplicatively on reallocation. Without such a collection or
136-
// solution having the same effect, there is a performance hazard here
137-
// in both time and space, as growing these collections means copying a
138-
// large amount of data and doubling already large buffer capacities. A
139-
// solution for this will also mean that it's less important to get
140-
// these estimates right.
141-
let new_node_count_estimate = (prev_graph_node_count * 2) / 100 + 200;
142-
let red_node_count_estimate = (prev_graph_node_count * 3) / 100;
143-
let light_green_node_count_estimate = (prev_graph_node_count * 25) / 100;
144-
let total_node_count_estimate = prev_graph_node_count + new_node_count_estimate;
145-
146-
let average_edges_per_node_estimate = 6;
147-
let unshared_edge_count_estimate = average_edges_per_node_estimate
148-
* (new_node_count_estimate + red_node_count_estimate + light_green_node_count_estimate);
149-
*/
150-
151-
// We store a large collection of these in `prev_index_to_index` during
152-
// non-full incremental builds, and want to ensure that the element size
153-
// doesn't inadvertently increase.
154-
static_assert_size!(Option<DepNodeIndex>, 4);
155-
156121
DepGraph {
157122
data: Some(Lrc::new(DepGraphData {
158123
previous_work_products: prev_work_products,
@@ -162,7 +127,7 @@ impl<K: DepKind> DepGraph<K> {
162127
total_read_count: AtomicU64::new(0),
163128
total_duplicate_read_count: AtomicU64::new(0),
164129
emitting_diagnostics: Default::default(),
165-
previous: RwLock::new(prev_graph),
130+
previous: RwLock::new(CurrentDepGraph::new(prev_graph)),
166131
})),
167132
virtual_dep_node_index: Lrc::new(AtomicU32::new(0)),
168133
}
@@ -627,21 +592,13 @@ impl<K: DepKind> DepGraph<K> {
627592
debug_assert!(!dep_node.kind.is_eval_always());
628593
debug_assert_eq!(data.previous.read().index_to_node(prev_dep_node_index), *dep_node);
629594

630-
// Do not keep a reference to the borrowed `previous` graph,
631-
// because the recursive calls.
632-
let prev_deps: Vec<_> =
633-
data.previous.read().edge_targets_from_serialized(prev_dep_node_index).collect();
634-
debug!(
635-
"try_mark_previous_green({:?}) --- {:?} -- deps={:?}",
636-
dep_node,
637-
prev_dep_node_index,
638-
prev_deps
639-
.iter()
640-
.map(|&d| (d, data.previous.read().index_to_node(d)))
641-
.collect::<Vec<_>>(),
642-
);
643-
644-
for dep_dep_node_index in prev_deps {
595+
let prev_deps = data.previous.read().color_or_edges(prev_dep_node_index);
596+
let prev_deps = match prev_deps {
597+
Err(prev_deps) => prev_deps,
598+
Ok(DepNodeColor::Green) => return Some(prev_dep_node_index.rejuvenate()),
599+
Ok(DepNodeColor::Red) | Ok(DepNodeColor::New) => return None,
600+
};
601+
for &dep_dep_node_index in prev_deps {
645602
self.try_mark_parent_green(tcx, data, dep_dep_node_index, dep_node)?
646603
}
647604

@@ -764,7 +721,7 @@ impl<K: DepKind> DepGraph<K> {
764721

765722
let mut stats: FxHashMap<_, Stat<K>> = FxHashMap::with_hasher(Default::default());
766723

767-
for index in prev.indices() {
724+
for index in prev.live_indices() {
768725
let kind = prev.dep_node_of(index).kind;
769726
let edge_count = prev.edge_targets_from(index).len();
770727

0 commit comments

Comments
 (0)