Skip to content

Commit 3ef8e64

Browse files
committed
Auto merge of #139758 - Zoxc:thread-local-graph, r=oli-obk
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.
2 parents db0e836 + cdd1049 commit 3ef8e64

6 files changed

Lines changed: 299 additions & 184 deletions

File tree

‎compiler/rustc_data_structures/src/sync.rs‎

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

‎compiler/rustc_data_structures/src/sync/parallel.rs‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,3 +237,13 @@ pub fn par_map<I: DynSend, T: IntoIterator<Item = I>, R: DynSend, C: FromIterato
237237
}
238238
})
239239
}
240+
241+
pubfnbroadcast<R:DynSend>(op:implFn(usize) -> R + DynSync) -> Vec<R>{
242+
if mode::is_dyn_thread_safe(){
243+
let op = FromDyn::from(op);
244+
let results = rayon_core::broadcast(|context| op.derive(op(context.index())));
245+
results.into_iter().map(|r| r.into_inner()).collect()
246+
}else{
247+
vec![op(0)]
248+
}
249+
}

‎compiler/rustc_incremental/src/persist/save.rs‎

Lines changed: 1 addition & 12 deletions
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‎

Lines changed: 43 additions & 34 deletions
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-
pubfnprint_incremental_info(&self){
1056-
ifletSome(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
pubfnfinish_encoding(&self) -> FileEncodeResult{
1065-
ifletSome(data) = &self.data{ data.current.encoder.finish()}else{Ok(0)}
1048+
ifletSome(data) = &self.data{ data.current.encoder.finish(&data.current)}else{Ok(0)}
10661049
}
10671050

10681051
pub(crate)fnnext_virtual_depnode_index(&self) -> DepNodeIndex{
@@ -1179,17 +1162,15 @@ pub(super) struct CurrentDepGraph<D: Deps> {
11791162

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

11861169
impl<D:Deps>CurrentDepGraph<D>{
11871170
fnnew(
11881171
session:&Session,
11891172
prev_graph_node_count:usize,
11901173
encoder:FileEncoder,
1191-
record_graph:bool,
1192-
record_stats:bool,
11931174
previous:Arc<SerializedDepGraph>,
11941175
) -> Self{
11951176
letmut stable_hasher = StableHasher::new();
@@ -1211,14 +1192,7 @@ impl<D: Deps> CurrentDepGraph<D> {
12111192
session.opts.unstable_opts.incremental_verify_ich || cfg!(debug_assertions);
12121193

12131194
CurrentDepGraph{
1214-
encoder:GraphEncoder::new(
1215-
encoder,
1216-
prev_graph_node_count,
1217-
record_graph,
1218-
record_stats,
1219-
&session.prof,
1220-
previous,
1221-
),
1195+
encoder:GraphEncoder::new(session, encoder, prev_graph_node_count, previous),
12221196
anon_node_to_index:ShardedHashMap::with_capacity(
12231197
// FIXME: The count estimate is off as anon nodes are only a portion of the nodes.
12241198
new_node_count_estimate / sharded::shards(),
@@ -1345,6 +1319,7 @@ impl Default for TaskDeps {
13451319
// array, using one u32 per entry.
13461320
pub(super)structDepNodeColorMap{
13471321
values:IndexVec<SerializedDepNodeIndex,AtomicU32>,
1322+
sync:bool,
13481323
}
13491324

13501325
constCOMPRESSED_NONE:u32 = u32::MAX;
@@ -1353,7 +1328,10 @@ const COMPRESSED_RED: u32 = u32::MAX - 1;
13531328
implDepNodeColorMap{
13541329
fnnew(size:usize) -> DepNodeColorMap{
13551330
debug_assert!(COMPRESSED_RED > DepNodeIndex::MAX_AS_U32);
1356-
DepNodeColorMap{values:(0..size).map(|_| AtomicU32::new(COMPRESSED_NONE)).collect()}
1331+
DepNodeColorMap{
1332+
values:(0..size).map(|_| AtomicU32::new(COMPRESSED_NONE)).collect(),
1333+
sync:is_dyn_thread_safe(),
1334+
}
13571335
}
13581336

13591337
#[inline]
@@ -1362,6 +1340,37 @@ impl DepNodeColorMap {
13621340
if value <= DepNodeIndex::MAX_AS_U32{Some(DepNodeIndex::from_u32(value))}else{None}
13631341
}
13641342

1343+
/// This tries to atomically mark a node green and assign `index` as the new
1344+
/// index. This returns `Ok` if `index` gets assigned, otherwise it returns
1345+
/// the alreadly allocated index in `Err`.
1346+
#[inline]
1347+
pub(super)fntry_mark_green(
1348+
&self,
1349+
prev_index:SerializedDepNodeIndex,
1350+
index:DepNodeIndex,
1351+
) -> Result<(),DepNodeIndex>{
1352+
let value = &self.values[prev_index];
1353+
ifself.sync{
1354+
match value.compare_exchange(
1355+
COMPRESSED_NONE,
1356+
index.as_u32(),
1357+
Ordering::Relaxed,
1358+
Ordering::Relaxed,
1359+
){
1360+
Ok(_) => Ok(()),
1361+
Err(v) => Err(DepNodeIndex::from_u32(v)),
1362+
}
1363+
}else{
1364+
let v = value.load(Ordering::Relaxed);
1365+
if v == COMPRESSED_NONE{
1366+
value.store(index.as_u32(),Ordering::Relaxed);
1367+
Ok(())
1368+
}else{
1369+
Err(DepNodeIndex::from_u32(v))
1370+
}
1371+
}
1372+
}
1373+
13651374
#[inline]
13661375
pub(super)fnget(&self,index:SerializedDepNodeIndex) -> Option<DepNodeColor>{
13671376
matchself.values[index].load(Ordering::Acquire){

‎compiler/rustc_query_system/src/dep_graph/mod.rs‎

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

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

0 commit comments

Comments
 (0)