Skip to content

Commit 09720ec

Browse files
authored
Rollup merge of #152329 - Zoxc:simple-parallel-macro, r=nnethercote
Simplify parallel! macro This replaces the `parallel!` macro with a `par_fns` function.
2 parents eaa6766 + 8c5ce26 commit 09720ec

7 files changed

Lines changed: 64 additions & 73 deletions

File tree

compiler/rustc_data_structures/src/sync.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ pub use self::freeze::{FreezeLock, FreezeReadGuard, FreezeWriteGuard};
4141
pub use self::lock::{Lock, LockGuard, Mode};
4242
pub use self::mode::{is_dyn_thread_safe, set_dyn_thread_safe_mode};
4343
pub use self::parallel::{
44-
broadcast, join, par_for_each_in, par_map, parallel_guard, scope, spawn, try_par_for_each_in,
44+
broadcast, par_fns, par_for_each_in, par_join, par_map, parallel_guard, spawn,
45+
try_par_for_each_in,
4546
};
4647
pub use self::vec::{AppendOnlyIndexVec, AppendOnlyVec};
4748
pub use self::worker_local::{Registry, WorkerLocal};

compiler/rustc_data_structures/src/sync/parallel.rs

Lines changed: 34 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -56,41 +56,6 @@ where
5656
(a.unwrap(), b.unwrap())
5757
}
5858

59-
/// Runs a list of blocks in parallel. The first block is executed immediately on
60-
/// the current thread. Use that for the longest running block.
61-
#[macro_export]
62-
macro_rules! parallel {
63-
(impl $fblock:block [$($c:expr,)*] [$block:expr $(, $rest:expr)*]) => {
64-
parallel!(impl $fblock [$block, $($c,)*] [$($rest),*])
65-
};
66-
(impl $fblock:block [$($blocks:expr,)*] []) => {
67-
$crate::sync::parallel_guard(|guard| {
68-
$crate::sync::scope(|s| {
69-
$(
70-
let block = $crate::sync::FromDyn::from(|| $blocks);
71-
s.spawn(move |_| {
72-
guard.run(move || block.into_inner()());
73-
});
74-
)*
75-
guard.run(|| $fblock);
76-
});
77-
});
78-
};
79-
($fblock:block, $($blocks:block),*) => {
80-
if $crate::sync::is_dyn_thread_safe() {
81-
// Reverse the order of the later blocks since Rayon executes them in reverse order
82-
// when using a single thread. This ensures the execution order matches that
83-
// of a single threaded rustc.
84-
parallel!(impl $fblock [] [$($blocks),*]);
85-
} else {
86-
$crate::sync::parallel_guard(|guard| {
87-
guard.run(|| $fblock);
88-
$(guard.run(|| $blocks);)*
89-
});
90-
}
91-
};
92-
}
93-
9459
pub fn spawn(func: impl FnOnce() + DynSend + 'static) {
9560
if mode::is_dyn_thread_safe() {
9661
let func = FromDyn::from(func);
@@ -102,18 +67,43 @@ pub fn spawn(func: impl FnOnce() + DynSend + 'static) {
10267
}
10368
}
10469

105-
// This function only works when `mode::is_dyn_thread_safe()`.
106-
pub fn scope<'scope, OP, R>(op: OP) -> R
107-
where
108-
OP: FnOnce(&rustc_thread_pool::Scope<'scope>) -> R + DynSend,
109-
R: DynSend,
110-
{
111-
let op = FromDyn::from(op);
112-
rustc_thread_pool::scope(|s| FromDyn::from(op.into_inner()(s))).into_inner()
70+
/// Runs the functions in parallel.
71+
///
72+
/// The first function is executed immediately on the current thread.
73+
/// Use that for the longest running function for better scheduling.
74+
pub fn par_fns(funcs: &mut [&mut (dyn FnMut() + DynSend)]) {
75+
parallel_guard(|guard: &ParallelGuard| {
76+
if mode::is_dyn_thread_safe() {
77+
let funcs = FromDyn::from(funcs);
78+
rustc_thread_pool::scope(|s| {
79+
let Some((first, rest)) = funcs.into_inner().split_at_mut_checked(1) else {
80+
return;
81+
};
82+
83+
// Reverse the order of the later functions since Rayon executes them in reverse
84+
// order when using a single thread. This ensures the execution order matches
85+
// that of a single threaded rustc.
86+
for f in rest.iter_mut().rev() {
87+
let f = FromDyn::from(f);
88+
s.spawn(|_| {
89+
guard.run(|| (f.into_inner())());
90+
});
91+
}
92+
93+
// Run the first function without spawning to
94+
// ensure it executes immediately on this thread.
95+
guard.run(|| first[0]());
96+
});
97+
} else {
98+
for f in funcs {
99+
guard.run(|| f());
100+
}
101+
}
102+
});
113103
}
114104

115105
#[inline]
116-
pub fn join<A, B, RA: DynSend, RB: DynSend>(oper_a: A, oper_b: B) -> (RA, RB)
106+
pub fn par_join<A, B, RA: DynSend, RB: DynSend>(oper_a: A, oper_b: B) -> (RA, RB)
117107
where
118108
A: FnOnce() -> RA + DynSend,
119109
B: FnOnce() -> RB + DynSend,

compiler/rustc_incremental/src/persist/save.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::fs;
22
use std::sync::Arc;
33

44
use rustc_data_structures::fx::FxIndexMap;
5-
use rustc_data_structures::sync::join;
5+
use rustc_data_structures::sync::par_join;
66
use rustc_middle::dep_graph::{
77
DepGraph, SerializedDepGraph, WorkProduct, WorkProductId, WorkProductMap,
88
};
@@ -44,7 +44,7 @@ pub(crate) fn save_dep_graph(tcx: TyCtxt<'_>) {
4444
sess.time("assert_dep_graph", || assert_dep_graph(tcx));
4545
sess.time("check_clean", || clean::check_clean_annotations(tcx));
4646

47-
join(
47+
par_join(
4848
move || {
4949
sess.time("incr_comp_persist_dep_graph", || {
5050
if let Err(err) = fs::rename(&staging_dep_graph_path, &dep_graph_path) {

compiler/rustc_interface/src/passes.rs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ use rustc_codegen_ssa::{CodegenResults, CrateInfo};
1212
use rustc_data_structures::indexmap::IndexMap;
1313
use rustc_data_structures::jobserver::Proxy;
1414
use rustc_data_structures::steal::Steal;
15-
use rustc_data_structures::sync::{AppendOnlyIndexVec, FreezeLock, WorkerLocal};
16-
use rustc_data_structures::{parallel, thousands};
15+
use rustc_data_structures::sync::{AppendOnlyIndexVec, FreezeLock, WorkerLocal, par_fns};
16+
use rustc_data_structures::thousands;
1717
use rustc_errors::timings::TimingSection;
1818
use rustc_expand::base::{ExtCtxt, LintStoreExpand};
1919
use rustc_feature::Features;
@@ -1052,8 +1052,8 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
10521052

10531053
let sess = tcx.sess;
10541054
sess.time("misc_checking_1", || {
1055-
parallel!(
1056-
{
1055+
par_fns(&mut [
1056+
&mut || {
10571057
sess.time("looking_for_entry_point", || tcx.ensure_ok().entry_fn(()));
10581058
sess.time("check_externally_implementable_items", || {
10591059
tcx.ensure_ok().check_externally_implementable_items(())
@@ -1065,22 +1065,22 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
10651065

10661066
CStore::from_tcx(tcx).report_unused_deps(tcx);
10671067
},
1068-
{
1068+
&mut || {
10691069
tcx.ensure_ok().exportable_items(LOCAL_CRATE);
10701070
tcx.ensure_ok().stable_order_of_exportable_impls(LOCAL_CRATE);
10711071
tcx.par_hir_for_each_module(|module| {
10721072
tcx.ensure_ok().check_mod_attrs(module);
10731073
tcx.ensure_ok().check_mod_unstable_api_usage(module);
10741074
});
10751075
},
1076-
{
1076+
&mut || {
10771077
// We force these queries to run,
10781078
// since they might not otherwise get called.
10791079
// This marks the corresponding crate-level attributes
10801080
// as used, and ensures that their values are valid.
10811081
tcx.ensure_ok().limits(());
1082-
}
1083-
);
1082+
},
1083+
]);
10841084
});
10851085

10861086
rustc_hir_analysis::check_crate(tcx);
@@ -1152,39 +1152,39 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) {
11521152
}
11531153

11541154
sess.time("misc_checking_3", || {
1155-
parallel!(
1156-
{
1155+
par_fns(&mut [
1156+
&mut || {
11571157
tcx.ensure_ok().effective_visibilities(());
11581158

1159-
parallel!(
1160-
{
1159+
par_fns(&mut [
1160+
&mut || {
11611161
tcx.par_hir_for_each_module(|module| {
11621162
tcx.ensure_ok().check_private_in_public(module)
11631163
})
11641164
},
1165-
{
1165+
&mut || {
11661166
tcx.par_hir_for_each_module(|module| {
11671167
tcx.ensure_ok().check_mod_deathness(module)
11681168
});
11691169
},
1170-
{
1170+
&mut || {
11711171
sess.time("lint_checking", || {
11721172
rustc_lint::check_crate(tcx);
11731173
});
11741174
},
1175-
{
1175+
&mut || {
11761176
tcx.ensure_ok().clashing_extern_declarations(());
1177-
}
1178-
);
1177+
},
1178+
]);
11791179
},
1180-
{
1180+
&mut || {
11811181
sess.time("privacy_checking_modules", || {
11821182
tcx.par_hir_for_each_module(|module| {
11831183
tcx.ensure_ok().check_mod_privacy(module);
11841184
});
11851185
});
1186-
}
1187-
);
1186+
},
1187+
]);
11881188

11891189
// This check has to be run after all lints are done processing. We don't
11901190
// define a lint filter, as all lint checks should have finished at this point.

compiler/rustc_lint/src/late.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::any::Any;
77
use std::cell::Cell;
88

99
use rustc_data_structures::stack::ensure_sufficient_stack;
10-
use rustc_data_structures::sync::join;
10+
use rustc_data_structures::sync::par_join;
1111
use rustc_hir::def_id::{LocalDefId, LocalModDefId};
1212
use rustc_hir::{self as hir, AmbigArg, HirId, intravisit as hir_visit};
1313
use rustc_middle::hir::nested_filter;
@@ -461,7 +461,7 @@ fn late_lint_crate_inner<'tcx, T: LateLintPass<'tcx>>(
461461

462462
/// Performs lint checking on a crate.
463463
pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>) {
464-
join(
464+
par_join(
465465
|| {
466466
tcx.sess.time("crate_lints", || {
467467
// Run whole crate non-incremental lints

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::sync::Arc;
77

88
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
99
use rustc_data_structures::memmap::{Mmap, MmapMut};
10-
use rustc_data_structures::sync::{join, par_for_each_in};
10+
use rustc_data_structures::sync::{par_for_each_in, par_join};
1111
use rustc_data_structures::temp_dir::MaybeTempDir;
1212
use rustc_data_structures::thousands::usize_with_underscores;
1313
use rustc_feature::Features;
@@ -2461,7 +2461,7 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path, ref_path: Option<&Path>) {
24612461
// Prefetch some queries used by metadata encoding.
24622462
// This is not necessary for correctness, but is only done for performance reasons.
24632463
// It can be removed if it turns out to cause trouble or be detrimental to performance.
2464-
join(
2464+
par_join(
24652465
|| prefetch_mir(tcx),
24662466
|| {
24672467
let _ = tcx.exported_non_generic_symbols(LOCAL_CRATE);

compiler/rustc_monomorphize/src/partitioning.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ use std::io::Write;
9999
use std::path::{Path, PathBuf};
100100

101101
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
102-
use rustc_data_structures::sync;
102+
use rustc_data_structures::sync::par_join;
103103
use rustc_data_structures::unord::{UnordMap, UnordSet};
104104
use rustc_hir::LangItem;
105105
use rustc_hir::attrs::{InlineAttr, Linkage};
@@ -1145,7 +1145,7 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> MonoItemPartitio
11451145
tcx.dcx().abort_if_errors();
11461146

11471147
let (codegen_units, _) = tcx.sess.time("partition_and_assert_distinct_symbols", || {
1148-
sync::join(
1148+
par_join(
11491149
|| {
11501150
let mut codegen_units = partition(tcx, items.iter().copied(), &usage_map);
11511151
codegen_units[0].make_primary();

0 commit comments

Comments
 (0)