Skip to content

Commit 4e914b4

Browse files
committed
Auto merge of rust-lang#140319 - Zoxc:dep-graph-index-chunks, r=<try>
Group dep nodes by chunks with sequential indices and only store the first index at the start of the chunk This groups dep nodes by chunks with sequential indices and only stores the first index at the start of the chunk. This should reduce the dep graph size overhead from rust-lang#139756. This is based on rust-lang#139758.
2 parents d3508a8 + d17b845 commit 4e914b4

File tree

6 files changed

+370
-235
lines changed

6 files changed

+370
-235
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

+43-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 {
@@ -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
fn new(
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
let mut 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) struct DepNodeColorMap {
13471321
values: IndexVec<SerializedDepNodeIndex, AtomicU32>,
1322+
sync: bool,
13481323
}
13491324

13501325
const COMPRESSED_NONE: u32 = u32::MAX;
@@ -1353,7 +1328,10 @@ const COMPRESSED_RED: u32 = u32::MAX - 1;
13531328
impl DepNodeColorMap {
13541329
fn new(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) fn try_mark_green(
1348+
&self,
1349+
prev_index: SerializedDepNodeIndex,
1350+
index: DepNodeIndex,
1351+
) -> Result<(), DepNodeIndex> {
1352+
let value = &self.values[prev_index];
1353+
if self.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) fn get(&self, index: SerializedDepNodeIndex) -> Option<DepNodeColor> {
13671376
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)