Skip to content

Commit 5545f9c

Browse files
committed
Auto merge of rust-lang#139758 - Zoxc:thread-local-graph, r=<try>
Use thread local dep graph encoding This adds thread local encoding of dep graph nodes. Each thread has a `MemEncoder` that gets flushed to the global `FileEncoder` when it exceeds 64 kB. Each thread also has a local cache of dep indices. This means there can now be empty gaps in `SerializedDepGraph`. Indices are marked green and also allocated by the new atomic operation `DepNodeColorMap::try_mark_green` as the encoder lock is removed. This is based on rust-lang#139636 and rust-lang#139756.
2 parents 092a284 + 8167fdb commit 5545f9c

File tree

8 files changed

+480
-206
lines changed

8 files changed

+480
-206
lines changed

compiler/rustc_data_structures/src/sync.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ pub use self::freeze::{FreezeLock, FreezeReadGuard, FreezeWriteGuard};
4343
pub use self::lock::{Lock, LockGuard, Mode};
4444
pub use self::mode::{is_dyn_thread_safe, set_dyn_thread_safe_mode};
4545
pub use self::parallel::{
46-
join, par_for_each_in, par_map, parallel_guard, scope, try_par_for_each_in,
46+
broadcast, join, par_for_each_in, par_map, parallel_guard, scope, try_par_for_each_in,
4747
};
4848
pub use self::vec::{AppendOnlyIndexVec, AppendOnlyVec};
4949
pub use self::worker_local::{Registry, WorkerLocal};

compiler/rustc_data_structures/src/sync/parallel.rs

+10
Original file line numberDiff line numberDiff line change
@@ -226,3 +226,13 @@ pub fn par_map<I: DynSend, T: IntoIterator<Item = I>, R: DynSend, C: FromIterato
226226
}
227227
})
228228
}
229+
230+
pub fn broadcast<R: DynSend>(op: impl Fn(usize) -> R + DynSync) -> Vec<R> {
231+
if mode::is_dyn_thread_safe() {
232+
let op = FromDyn::from(op);
233+
let results = rayon_core::broadcast(|context| op.derive(op(context.index())));
234+
results.into_iter().map(|r| r.into_inner()).collect()
235+
} else {
236+
vec![op(0)]
237+
}
238+
}

compiler/rustc_incremental/src/persist/save.rs

+1-12
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,6 @@ pub(crate) fn save_dep_graph(tcx: TyCtxt<'_>) {
4444
sess.time("assert_dep_graph", || assert_dep_graph(tcx));
4545
sess.time("check_dirty_clean", || dirty_clean::check_dirty_clean_annotations(tcx));
4646

47-
if sess.opts.unstable_opts.incremental_info {
48-
tcx.dep_graph.print_incremental_info()
49-
}
50-
5147
join(
5248
move || {
5349
sess.time("incr_comp_persist_dep_graph", || {
@@ -172,12 +168,5 @@ pub(crate) fn build_dep_graph(
172168
// First encode the commandline arguments hash
173169
sess.opts.dep_tracking_hash(false).encode(&mut encoder);
174170

175-
Some(DepGraph::new(
176-
sess,
177-
prev_graph,
178-
prev_work_products,
179-
encoder,
180-
sess.opts.unstable_opts.query_dep_graph,
181-
sess.opts.unstable_opts.incremental_info,
182-
))
171+
Some(DepGraph::new(sess, prev_graph, prev_work_products, encoder))
183172
}

compiler/rustc_query_system/src/dep_graph/graph.rs

+42-34
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_data_structures::outline;
1111
use rustc_data_structures::profiling::QueryInvocationId;
1212
use rustc_data_structures::sharded::{self, ShardedHashMap};
1313
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
14-
use rustc_data_structures::sync::{AtomicU64, Lock};
14+
use rustc_data_structures::sync::{AtomicU64, Lock, is_dyn_thread_safe};
1515
use rustc_data_structures::unord::UnordMap;
1616
use rustc_errors::DiagInner;
1717
use rustc_index::IndexVec;
@@ -124,19 +124,11 @@ impl<D: Deps> DepGraph<D> {
124124
prev_graph: Arc<SerializedDepGraph>,
125125
prev_work_products: WorkProductMap,
126126
encoder: FileEncoder,
127-
record_graph: bool,
128-
record_stats: bool,
129127
) -> DepGraph<D> {
130128
let prev_graph_node_count = prev_graph.node_count();
131129

132-
let current = CurrentDepGraph::new(
133-
session,
134-
prev_graph_node_count,
135-
encoder,
136-
record_graph,
137-
record_stats,
138-
Arc::clone(&prev_graph),
139-
);
130+
let current =
131+
CurrentDepGraph::new(session, prev_graph_node_count, encoder, Arc::clone(&prev_graph));
140132

141133
let colors = DepNodeColorMap::new(prev_graph_node_count);
142134

@@ -1052,17 +1044,8 @@ impl<D: Deps> DepGraph<D> {
10521044
}
10531045
}
10541046

1055-
pub fn print_incremental_info(&self) {
1056-
if let Some(data) = &self.data {
1057-
data.current.encoder.print_incremental_info(
1058-
data.current.total_read_count.load(Ordering::Relaxed),
1059-
data.current.total_duplicate_read_count.load(Ordering::Relaxed),
1060-
)
1061-
}
1062-
}
1063-
10641047
pub fn finish_encoding(&self) -> FileEncodeResult {
1065-
if let Some(data) = &self.data { data.current.encoder.finish() } else { Ok(0) }
1048+
if let Some(data) = &self.data { data.current.encoder.finish(&data.current) } else { Ok(0) }
10661049
}
10671050

10681051
pub(crate) fn next_virtual_depnode_index(&self) -> DepNodeIndex {
@@ -1180,17 +1163,15 @@ pub(super) struct CurrentDepGraph<D: Deps> {
11801163

11811164
/// These are simple counters that are for profiling and
11821165
/// debugging and only active with `debug_assertions`.
1183-
total_read_count: AtomicU64,
1184-
total_duplicate_read_count: AtomicU64,
1166+
pub(super) total_read_count: AtomicU64,
1167+
pub(super) total_duplicate_read_count: AtomicU64,
11851168
}
11861169

11871170
impl<D: Deps> CurrentDepGraph<D> {
11881171
fn new(
11891172
session: &Session,
11901173
prev_graph_node_count: usize,
11911174
encoder: FileEncoder,
1192-
record_graph: bool,
1193-
record_stats: bool,
11941175
previous: Arc<SerializedDepGraph>,
11951176
) -> Self {
11961177
use std::time::{SystemTime, UNIX_EPOCH};
@@ -1216,14 +1197,7 @@ impl<D: Deps> CurrentDepGraph<D> {
12161197
session.opts.unstable_opts.incremental_verify_ich || cfg!(debug_assertions);
12171198

12181199
CurrentDepGraph {
1219-
encoder: GraphEncoder::new(
1220-
encoder,
1221-
prev_graph_node_count,
1222-
record_graph,
1223-
record_stats,
1224-
&session.prof,
1225-
previous,
1226-
),
1200+
encoder: GraphEncoder::new(session, encoder, prev_graph_node_count, previous),
12271201
anon_node_to_index: ShardedHashMap::with_capacity(
12281202
// FIXME: The count estimate is off as anon nodes are only a portion of the nodes.
12291203
new_node_count_estimate / sharded::shards(),
@@ -1350,6 +1324,7 @@ impl Default for TaskDeps {
13501324
// array, using one u32 per entry.
13511325
pub(super) struct DepNodeColorMap {
13521326
values: IndexVec<SerializedDepNodeIndex, AtomicU32>,
1327+
sync: bool,
13531328
}
13541329

13551330
const COMPRESSED_NONE: u32 = u32::MAX;
@@ -1358,7 +1333,10 @@ const COMPRESSED_RED: u32 = u32::MAX - 1;
13581333
impl DepNodeColorMap {
13591334
fn new(size: usize) -> DepNodeColorMap {
13601335
debug_assert!(COMPRESSED_RED > DepNodeIndex::MAX_AS_U32);
1361-
DepNodeColorMap { values: (0..size).map(|_| AtomicU32::new(COMPRESSED_NONE)).collect() }
1336+
DepNodeColorMap {
1337+
values: (0..size).map(|_| AtomicU32::new(COMPRESSED_NONE)).collect(),
1338+
sync: is_dyn_thread_safe(),
1339+
}
13621340
}
13631341

13641342
#[inline]
@@ -1367,6 +1345,36 @@ impl DepNodeColorMap {
13671345
if value <= DepNodeIndex::MAX_AS_U32 { Some(DepNodeIndex::from_u32(value)) } else { None }
13681346
}
13691347

1348+
/// This tries to atomically mark a node green and assign `index` as the new
1349+
/// index.
1350+
#[inline]
1351+
pub(super) fn try_mark_green(
1352+
&self,
1353+
prev_index: SerializedDepNodeIndex,
1354+
index: DepNodeIndex,
1355+
) -> Result<(), DepNodeIndex> {
1356+
let value = &self.values[prev_index];
1357+
if self.sync {
1358+
match value.compare_exchange(
1359+
COMPRESSED_NONE,
1360+
index.as_u32(),
1361+
Ordering::Relaxed,
1362+
Ordering::Relaxed,
1363+
) {
1364+
Ok(_) => Ok(()),
1365+
Err(v) => Err(DepNodeIndex::from_u32(v)),
1366+
}
1367+
} else {
1368+
let v = value.load(Ordering::Relaxed);
1369+
if v == COMPRESSED_NONE {
1370+
value.store(index.as_u32(), Ordering::Relaxed);
1371+
Ok(())
1372+
} else {
1373+
Err(DepNodeIndex::from_u32(v))
1374+
}
1375+
}
1376+
}
1377+
13701378
#[inline]
13711379
pub(super) fn get(&self, index: SerializedDepNodeIndex) -> Option<DepNodeColor> {
13721380
match self.values[index].load(Ordering::Acquire) {

compiler/rustc_query_system/src/dep_graph/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ pub(crate) use graph::DepGraphData;
1212
pub use graph::{DepGraph, DepNodeIndex, TaskDepsRef, WorkProduct, WorkProductMap, hash_result};
1313
pub use query::DepGraphQuery;
1414
use rustc_data_structures::profiling::SelfProfilerRef;
15+
use rustc_data_structures::sync::DynSync;
1516
use rustc_session::Session;
1617
pub use serialized::{SerializedDepGraph, SerializedDepNodeIndex};
1718
use tracing::instrument;
@@ -89,7 +90,7 @@ pub trait DepContext: Copy {
8990
}
9091
}
9192

92-
pub trait Deps {
93+
pub trait Deps: DynSync {
9394
/// Execute the operation with provided dependencies.
9495
fn with_deps<OP, R>(deps: TaskDepsRef<'_>, op: OP) -> R
9596
where

0 commit comments

Comments
 (0)