Skip to content

Commit ae110c4

Browse files
committed
Auto merge of #122070 - Zoxc:dep-edges-from-previous, r=<try>
Encode dep graph edges directly from the previous graph when promoting This encodes dep graph edges directly from the previous graph when promoting nodes from a previous session, avoiding allocations / copies. Based on #122064 and #116375. <table><tr><td rowspan="2">Benchmark</td><td colspan="1"><b>Before</b></th><td colspan="2"><b>After</b></th></tr><tr><td align="right">Time</td><td align="right">Time</td><td align="right">%</th></tr><tr><td>🟣 <b>clap</b>:check:unchanged</td><td align="right">0.4177s</td><td align="right">0.4072s</td><td align="right">💚 -2.52%</td></tr><tr><td>🟣 <b>hyper</b>:check:unchanged</td><td align="right">0.1430s</td><td align="right">0.1420s</td><td align="right"> -0.69%</td></tr><tr><td>🟣 <b>regex</b>:check:unchanged</td><td align="right">0.3106s</td><td align="right">0.3038s</td><td align="right">💚 -2.19%</td></tr><tr><td>🟣 <b>syn</b>:check:unchanged</td><td align="right">0.5823s</td><td align="right">0.5688s</td><td align="right">💚 -2.33%</td></tr><tr><td>🟣 <b>syntex_syntax</b>:check:unchanged</td><td align="right">1.3992s</td><td align="right">1.3692s</td><td align="right">💚 -2.14%</td></tr><tr><td>Total</td><td align="right">2.8528s</td><td align="right">2.7910s</td><td align="right">💚 -2.17%</td></tr><tr><td>Summary</td><td align="right">1.0000s</td><td align="right">0.9803s</td><td align="right">💚 -1.97%</td></tr></table>
2 parents 46b180e + d9fe043 commit ae110c4

File tree

5 files changed

+300
-133
lines changed

5 files changed

+300
-133
lines changed

Diff for: compiler/rustc_incremental/src/persist/load.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use rustc_session::config::IncrementalStateAssertion;
1111
use rustc_session::{Session, StableCrateId};
1212
use rustc_span::{ErrorGuaranteed, Symbol};
1313
use std::path::{Path, PathBuf};
14+
use std::sync::Arc;
1415

1516
use super::data::*;
1617
use super::file_format;
@@ -88,7 +89,7 @@ fn delete_dirty_work_product(sess: &Session, swp: SerializedWorkProduct) {
8889
work_product::delete_workproduct_files(sess, &swp.work_product);
8990
}
9091

91-
fn load_dep_graph(sess: &Session) -> LoadResult<(SerializedDepGraph, WorkProductMap)> {
92+
fn load_dep_graph(sess: &Session) -> LoadResult<(Arc<SerializedDepGraph>, WorkProductMap)> {
9293
let prof = sess.prof.clone();
9394

9495
if sess.opts.incremental.is_none() {
@@ -161,7 +162,7 @@ fn load_dep_graph(sess: &Session) -> LoadResult<(SerializedDepGraph, WorkProduct
161162
return LoadResult::DataOutOfDate;
162163
}
163164

164-
let dep_graph = SerializedDepGraph::decode::<DepsType>(&mut decoder);
165+
let dep_graph = SerializedDepGraph::decode::<DepsType>(&mut decoder, sess);
165166

166167
LoadResult::Ok { data: (dep_graph, prev_work_products) }
167168
}

Diff for: compiler/rustc_incremental/src/persist/save.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
1010
use rustc_serialize::Encodable as RustcEncodable;
1111
use rustc_session::Session;
1212
use std::fs;
13+
use std::sync::Arc;
1314

1415
use super::data::*;
1516
use super::dirty_clean;
@@ -147,7 +148,7 @@ fn encode_query_cache(tcx: TyCtxt<'_>, encoder: FileEncoder) -> FileEncodeResult
147148
/// and moves it to the permanent dep-graph path
148149
pub(crate) fn build_dep_graph(
149150
sess: &Session,
150-
prev_graph: SerializedDepGraph,
151+
prev_graph: Arc<SerializedDepGraph>,
151152
prev_work_products: WorkProductMap,
152153
) -> Option<DepGraph> {
153154
if sess.opts.incremental.is_none() {

Diff for: compiler/rustc_middle/src/ty/context.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,7 @@ impl<'tcx> GlobalCtxt<'tcx> {
709709
}
710710

711711
pub fn finish(&self) -> FileEncodeResult {
712-
self.dep_graph.finish_encoding(&self.sess.prof)
712+
self.dep_graph.finish_encoding()
713713
}
714714
}
715715

Diff for: compiler/rustc_query_system/src/dep_graph/graph.rs

+31-73
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
use rustc_data_structures::fingerprint::Fingerprint;
22
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
3-
use rustc_data_structures::profiling::{EventId, QueryInvocationId, SelfProfilerRef};
3+
use rustc_data_structures::profiling::{QueryInvocationId, SelfProfilerRef};
44
use rustc_data_structures::sharded::{self, Sharded};
55
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
6-
use rustc_data_structures::steal::Steal;
76
use rustc_data_structures::sync::{AtomicU32, AtomicU64, Lock, Lrc};
87
use rustc_data_structures::unord::UnordMap;
98
use rustc_index::IndexVec;
@@ -14,6 +13,7 @@ use std::fmt::Debug;
1413
use std::hash::Hash;
1514
use std::marker::PhantomData;
1615
use std::sync::atomic::Ordering;
16+
use std::sync::Arc;
1717

1818
use super::query::DepGraphQuery;
1919
use super::serialized::{GraphEncoder, SerializedDepGraph, SerializedDepNodeIndex};
@@ -82,7 +82,7 @@ pub(crate) struct DepGraphData<D: Deps> {
8282

8383
/// The dep-graph from the previous compilation session. It contains all
8484
/// nodes and edges as well as all fingerprints of nodes that have them.
85-
previous: SerializedDepGraph,
85+
previous: Arc<SerializedDepGraph>,
8686

8787
colors: DepNodeColorMap,
8888

@@ -114,7 +114,7 @@ where
114114
impl<D: Deps> DepGraph<D> {
115115
pub fn new(
116116
profiler: &SelfProfilerRef,
117-
prev_graph: SerializedDepGraph,
117+
prev_graph: Arc<SerializedDepGraph>,
118118
prev_work_products: WorkProductMap,
119119
encoder: FileEncoder,
120120
record_graph: bool,
@@ -128,13 +128,13 @@ impl<D: Deps> DepGraph<D> {
128128
encoder,
129129
record_graph,
130130
record_stats,
131+
prev_graph.clone(),
131132
);
132133

133134
let colors = DepNodeColorMap::new(prev_graph_node_count);
134135

135136
// Instantiate a dependy-less node only once for anonymous queries.
136137
let _green_node_index = current.intern_new_node(
137-
profiler,
138138
DepNode { kind: D::DEP_KIND_NULL, hash: current.anon_id_seed.into() },
139139
EdgesVec::new(),
140140
Fingerprint::ZERO,
@@ -143,7 +143,6 @@ impl<D: Deps> DepGraph<D> {
143143

144144
// Instantiate a dependy-less red node only once for anonymous queries.
145145
let (red_node_index, red_node_prev_index_and_color) = current.intern_node(
146-
profiler,
147146
&prev_graph,
148147
DepNode { kind: D::DEP_KIND_RED, hash: Fingerprint::ZERO.into() },
149148
EdgesVec::new(),
@@ -196,7 +195,7 @@ impl<D: Deps> DepGraph<D> {
196195

197196
pub fn with_query(&self, f: impl Fn(&DepGraphQuery)) {
198197
if let Some(data) = &self.data {
199-
data.current.encoder.borrow().with_query(f)
198+
data.current.encoder.with_query(f)
200199
}
201200
}
202201

@@ -372,13 +371,8 @@ impl<D: Deps> DepGraphData<D> {
372371
hash_result.map(|f| dcx.with_stable_hashing_context(|mut hcx| f(&mut hcx, &result)));
373372

374373
// Intern the new `DepNode`.
375-
let (dep_node_index, prev_and_color) = self.current.intern_node(
376-
dcx.profiler(),
377-
&self.previous,
378-
key,
379-
edges,
380-
current_fingerprint,
381-
);
374+
let (dep_node_index, prev_and_color) =
375+
self.current.intern_node(&self.previous, key, edges, current_fingerprint);
382376

383377
hashing_timer.finish_with_query_invocation_id(dep_node_index.into());
384378

@@ -443,12 +437,7 @@ impl<D: Deps> DepGraphData<D> {
443437
hash: self.current.anon_id_seed.combine(hasher.finish()).into(),
444438
};
445439

446-
self.current.intern_new_node(
447-
cx.profiler(),
448-
target_dep_node,
449-
task_deps,
450-
Fingerprint::ZERO,
451-
)
440+
self.current.intern_new_node(target_dep_node, task_deps, Fingerprint::ZERO)
452441
}
453442
};
454443

@@ -585,13 +574,8 @@ impl<D: Deps> DepGraph<D> {
585574
});
586575

587576
// Intern the new `DepNode` with the dependencies up-to-now.
588-
let (dep_node_index, prev_and_color) = data.current.intern_node(
589-
cx.profiler(),
590-
&data.previous,
591-
node,
592-
edges,
593-
current_fingerprint,
594-
);
577+
let (dep_node_index, prev_and_color) =
578+
data.current.intern_node(&data.previous, node, edges, current_fingerprint);
595579

596580
hashing_timer.finish_with_query_invocation_id(dep_node_index.into());
597581

@@ -871,11 +855,8 @@ impl<D: Deps> DepGraphData<D> {
871855

872856
// We allocating an entry for the node in the current dependency graph and
873857
// adding all the appropriate edges imported from the previous graph
874-
let dep_node_index = self.current.promote_node_and_deps_to_current(
875-
qcx.dep_context().profiler(),
876-
&self.previous,
877-
prev_dep_node_index,
878-
);
858+
let dep_node_index =
859+
self.current.promote_node_and_deps_to_current(&self.previous, prev_dep_node_index);
879860

880861
// ... emitting any stored diagnostic ...
881862

@@ -974,19 +955,15 @@ impl<D: Deps> DepGraph<D> {
974955

975956
pub fn print_incremental_info(&self) {
976957
if let Some(data) = &self.data {
977-
data.current.encoder.borrow().print_incremental_info(
958+
data.current.encoder.print_incremental_info(
978959
data.current.total_read_count.load(Ordering::Relaxed),
979960
data.current.total_duplicate_read_count.load(Ordering::Relaxed),
980961
)
981962
}
982963
}
983964

984-
pub fn finish_encoding(&self, profiler: &SelfProfilerRef) -> FileEncodeResult {
985-
if let Some(data) = &self.data {
986-
data.current.encoder.steal().finish(profiler)
987-
} else {
988-
Ok(0)
989-
}
965+
pub fn finish_encoding(&self) -> FileEncodeResult {
966+
if let Some(data) = &self.data { data.current.encoder.finish() } else { Ok(0) }
990967
}
991968

992969
pub(crate) fn next_virtual_depnode_index(&self) -> DepNodeIndex {
@@ -1069,7 +1046,7 @@ rustc_index::newtype_index! {
10691046
/// manipulating both, we acquire `new_node_to_index` or `prev_index_to_index`
10701047
/// first, and `data` second.
10711048
pub(super) struct CurrentDepGraph<D: Deps> {
1072-
encoder: Steal<GraphEncoder<D>>,
1049+
encoder: GraphEncoder<D>,
10731050
new_node_to_index: Sharded<FxHashMap<DepNode, DepNodeIndex>>,
10741051
prev_index_to_index: Lock<IndexVec<SerializedDepNodeIndex, Option<DepNodeIndex>>>,
10751052

@@ -1100,12 +1077,6 @@ pub(super) struct CurrentDepGraph<D: Deps> {
11001077
/// debugging and only active with `debug_assertions`.
11011078
total_read_count: AtomicU64,
11021079
total_duplicate_read_count: AtomicU64,
1103-
1104-
/// The cached event id for profiling node interning. This saves us
1105-
/// from having to look up the event id every time we intern a node
1106-
/// which may incur too much overhead.
1107-
/// This will be None if self-profiling is disabled.
1108-
node_intern_event_id: Option<EventId>,
11091080
}
11101081

11111082
impl<D: Deps> CurrentDepGraph<D> {
@@ -1115,6 +1086,7 @@ impl<D: Deps> CurrentDepGraph<D> {
11151086
encoder: FileEncoder,
11161087
record_graph: bool,
11171088
record_stats: bool,
1089+
previous: Arc<SerializedDepGraph>,
11181090
) -> Self {
11191091
use std::time::{SystemTime, UNIX_EPOCH};
11201092

@@ -1140,17 +1112,15 @@ impl<D: Deps> CurrentDepGraph<D> {
11401112

11411113
let new_node_count_estimate = 102 * prev_graph_node_count / 100 + 200;
11421114

1143-
let node_intern_event_id = profiler
1144-
.get_or_alloc_cached_string("incr_comp_intern_dep_graph_node")
1145-
.map(EventId::from_label);
1146-
11471115
CurrentDepGraph {
1148-
encoder: Steal::new(GraphEncoder::new(
1116+
encoder: GraphEncoder::new(
11491117
encoder,
11501118
prev_graph_node_count,
11511119
record_graph,
11521120
record_stats,
1153-
)),
1121+
profiler,
1122+
previous,
1123+
),
11541124
new_node_to_index: Sharded::new(|| {
11551125
FxHashMap::with_capacity_and_hasher(
11561126
new_node_count_estimate / sharded::shards(),
@@ -1165,7 +1135,6 @@ impl<D: Deps> CurrentDepGraph<D> {
11651135
fingerprints: Lock::new(IndexVec::from_elem_n(None, new_node_count_estimate)),
11661136
total_read_count: AtomicU64::new(0),
11671137
total_duplicate_read_count: AtomicU64::new(0),
1168-
node_intern_event_id,
11691138
}
11701139
}
11711140

@@ -1183,16 +1152,14 @@ impl<D: Deps> CurrentDepGraph<D> {
11831152
#[inline(always)]
11841153
fn intern_new_node(
11851154
&self,
1186-
profiler: &SelfProfilerRef,
11871155
key: DepNode,
11881156
edges: EdgesVec,
11891157
current_fingerprint: Fingerprint,
11901158
) -> DepNodeIndex {
11911159
let dep_node_index = match self.new_node_to_index.lock_shard_by_value(&key).entry(key) {
11921160
Entry::Occupied(entry) => *entry.get(),
11931161
Entry::Vacant(entry) => {
1194-
let dep_node_index =
1195-
self.encoder.borrow().send(profiler, key, current_fingerprint, edges);
1162+
let dep_node_index = self.encoder.send(key, current_fingerprint, edges);
11961163
entry.insert(dep_node_index);
11971164
dep_node_index
11981165
}
@@ -1206,25 +1173,19 @@ impl<D: Deps> CurrentDepGraph<D> {
12061173

12071174
fn intern_node(
12081175
&self,
1209-
profiler: &SelfProfilerRef,
12101176
prev_graph: &SerializedDepGraph,
12111177
key: DepNode,
12121178
edges: EdgesVec,
12131179
fingerprint: Option<Fingerprint>,
12141180
) -> (DepNodeIndex, Option<(SerializedDepNodeIndex, DepNodeColor)>) {
1215-
// Get timer for profiling `DepNode` interning
1216-
let _node_intern_timer =
1217-
self.node_intern_event_id.map(|eid| profiler.generic_activity_with_event_id(eid));
1218-
12191181
if let Some(prev_index) = prev_graph.node_to_index_opt(&key) {
12201182
let get_dep_node_index = |fingerprint| {
12211183
let mut prev_index_to_index = self.prev_index_to_index.lock();
12221184

12231185
let dep_node_index = match prev_index_to_index[prev_index] {
12241186
Some(dep_node_index) => dep_node_index,
12251187
None => {
1226-
let dep_node_index =
1227-
self.encoder.borrow().send(profiler, key, fingerprint, edges);
1188+
let dep_node_index = self.encoder.send(key, fingerprint, edges);
12281189
prev_index_to_index[prev_index] = Some(dep_node_index);
12291190
dep_node_index
12301191
}
@@ -1261,15 +1222,14 @@ impl<D: Deps> CurrentDepGraph<D> {
12611222
let fingerprint = fingerprint.unwrap_or(Fingerprint::ZERO);
12621223

12631224
// This is a new node: it didn't exist in the previous compilation session.
1264-
let dep_node_index = self.intern_new_node(profiler, key, edges, fingerprint);
1225+
let dep_node_index = self.intern_new_node(key, edges, fingerprint);
12651226

12661227
(dep_node_index, None)
12671228
}
12681229
}
12691230

12701231
fn promote_node_and_deps_to_current(
12711232
&self,
1272-
profiler: &SelfProfilerRef,
12731233
prev_graph: &SerializedDepGraph,
12741234
prev_index: SerializedDepNodeIndex,
12751235
) -> DepNodeIndex {
@@ -1280,16 +1240,14 @@ impl<D: Deps> CurrentDepGraph<D> {
12801240
match prev_index_to_index[prev_index] {
12811241
Some(dep_node_index) => dep_node_index,
12821242
None => {
1283-
let key = prev_graph.index_to_node(prev_index);
1284-
let edges = prev_graph
1285-
.edge_targets_from(prev_index)
1286-
.map(|i| prev_index_to_index[i].unwrap())
1287-
.collect();
1288-
let fingerprint = prev_graph.fingerprint_by_index(prev_index);
1289-
let dep_node_index = self.encoder.borrow().send(profiler, key, fingerprint, edges);
1243+
let dep_node_index = self.encoder.promote(prev_index, &mut *prev_index_to_index);
12901244
prev_index_to_index[prev_index] = Some(dep_node_index);
12911245
#[cfg(debug_assertions)]
1292-
self.record_edge(dep_node_index, key, fingerprint);
1246+
self.record_edge(
1247+
dep_node_index,
1248+
prev_graph.index_to_node(prev_index),
1249+
prev_graph.fingerprint_by_index(prev_index),
1250+
);
12931251
dep_node_index
12941252
}
12951253
}

0 commit comments

Comments
 (0)