Skip to content

Commit 2ad5f86

Browse files
committed
Auto merge of #140442 - osiewicz:collector-walk-less-fine-grained-locking, r=wesleywiser
mono collector: Reduce # of locking while walking the graph While profiling Zed's dev build I've noticed that while most of the time `upstream_monomorphizations` takes a lot of time in monomorpization_collector, in some cases (e.g. build of `editor` itself) the rest of monomorphization_collector_graph_walk dominates it. Most of the time is spent in collect_items_rec. This PR aims to reduce the number of locks taking place; instead of locking output MonoItems once per children of current node, we do so once per *current node*. We also get to reuse locks for mentioned and used items. While this commit does not reduce Wall time of Zed's build, it does shave off CPU time (measured with `cargo build -j1`) from 48s to 47s. I've also tested it with parallel frontend against Zed and ripgrep and found no regressions.
2 parents 2d5ffc5 + 578ea26 commit 2ad5f86

File tree

2 files changed

+38
-27
lines changed

2 files changed

+38
-27
lines changed

compiler/rustc_monomorphize/src/collector.rs

+37-27
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@
205205
//! this is not implemented however: a mono item will be produced
206206
//! regardless of whether it is actually needed or not.
207207
208+
use std::cell::OnceCell;
208209
use std::path::PathBuf;
209210

210211
use rustc_attr_parsing::InlineAttr;
@@ -348,6 +349,27 @@ impl<'tcx> Extend<Spanned<MonoItem<'tcx>>> for MonoItems<'tcx> {
348349
}
349350
}
350351

352+
fn collect_items_root<'tcx>(
353+
tcx: TyCtxt<'tcx>,
354+
starting_item: Spanned<MonoItem<'tcx>>,
355+
state: &SharedState<'tcx>,
356+
recursion_limit: Limit,
357+
) {
358+
if !state.visited.lock_mut().insert(starting_item.node) {
359+
// We've been here already, no need to search again.
360+
return;
361+
}
362+
let mut recursion_depths = DefIdMap::default();
363+
collect_items_rec(
364+
tcx,
365+
starting_item,
366+
state,
367+
&mut recursion_depths,
368+
recursion_limit,
369+
CollectionMode::UsedItems,
370+
);
371+
}
372+
351373
/// Collect all monomorphized items reachable from `starting_point`, and emit a note diagnostic if a
352374
/// post-monomorphization error is encountered during a collection step.
353375
///
@@ -362,24 +384,6 @@ fn collect_items_rec<'tcx>(
362384
recursion_limit: Limit,
363385
mode: CollectionMode,
364386
) {
365-
if mode == CollectionMode::UsedItems {
366-
if !state.visited.lock_mut().insert(starting_item.node) {
367-
// We've been here already, no need to search again.
368-
return;
369-
}
370-
} else {
371-
if state.visited.lock().contains(&starting_item.node) {
372-
// We've already done a *full* visit on this one, no need to do the "mention" visit.
373-
return;
374-
}
375-
if !state.mentioned.lock_mut().insert(starting_item.node) {
376-
// We've been here already, no need to search again.
377-
return;
378-
}
379-
// There's some risk that we first do a 'mention' visit and then a full visit. But there's no
380-
// harm in that, the mention visit will trigger all the queries and the results are cached.
381-
}
382-
383387
let mut used_items = MonoItems::new();
384388
let mut mentioned_items = MonoItems::new();
385389
let recursion_depth_reset;
@@ -536,6 +540,20 @@ fn collect_items_rec<'tcx>(
536540
state.usage_map.lock_mut().record_used(starting_item.node, &used_items);
537541
}
538542

543+
{
544+
let mut visited = OnceCell::default();
545+
if mode == CollectionMode::UsedItems {
546+
used_items
547+
.items
548+
.retain(|k, _| visited.get_mut_or_init(|| state.visited.lock_mut()).insert(*k));
549+
}
550+
551+
let mut mentioned = OnceCell::default();
552+
mentioned_items.items.retain(|k, _| {
553+
!visited.get_or_init(|| state.visited.lock()).contains(k)
554+
&& mentioned.get_mut_or_init(|| state.mentioned.lock_mut()).insert(*k)
555+
});
556+
}
539557
if mode == CollectionMode::MentionedItems {
540558
assert!(used_items.is_empty(), "'mentioned' collection should never encounter used items");
541559
} else {
@@ -1689,15 +1707,7 @@ pub(crate) fn collect_crate_mono_items<'tcx>(
16891707

16901708
tcx.sess.time("monomorphization_collector_graph_walk", || {
16911709
par_for_each_in(roots, |root| {
1692-
let mut recursion_depths = DefIdMap::default();
1693-
collect_items_rec(
1694-
tcx,
1695-
dummy_spanned(*root),
1696-
&state,
1697-
&mut recursion_depths,
1698-
recursion_limit,
1699-
CollectionMode::UsedItems,
1700-
);
1710+
collect_items_root(tcx, dummy_spanned(*root), &state, recursion_limit);
17011711
});
17021712
});
17031713

compiler/rustc_monomorphize/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#![feature(file_buffered)]
55
#![feature(if_let_guard)]
66
#![feature(impl_trait_in_assoc_type)]
7+
#![feature(once_cell_get_mut)]
78
// tidy-alphabetical-end
89

910
use rustc_hir::lang_items::LangItem;

0 commit comments

Comments
 (0)