Skip to content

Commit 7c6d8cc

Browse files
authored
Rollup merge of rust-lang#58679 - Zoxc:passes-refactor, r=michaelwoerister
Refactor passes and pass execution to be more parallel For `syntex_syntax` (with 16 threads and 8 cores): - Cuts `misc checking 1` from `0.096s` to `0.08325s`. - Cuts `misc checking 2` from `0.3575s` to `0.2545s`. - Cuts `misc checking 3` from `0.34625s` to `0.21375s`. - Cuts `wf checking` from `0.3085s` to `0.05025s`. Reduces overall execution time for `syntex_syntax` (with 8 threads and cores) from `4.92s` to `4.34s`. Subsumes rust-lang#58494 Blocked on rust-lang#58250 r? @michaelwoerister
2 parents 1b737b9 + 7985c6f commit 7c6d8cc

31 files changed

+305
-197
lines changed

src/librustc/dep_graph/dep_node.rs

+1
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,7 @@ define_dep_nodes!( <'tcx>
456456
[eval_always] CoherenceInherentImplOverlapCheck,
457457
[] CoherenceCheckTrait(DefId),
458458
[eval_always] PrivacyAccessLevels(CrateNum),
459+
[eval_always] CheckPrivateInPublic(CrateNum),
459460
[eval_always] Analysis(CrateNum),
460461

461462
// Represents the MIR for a fn; also used as the task node for

src/librustc/hir/check_attr.rs

-6
Original file line numberDiff line numberDiff line change
@@ -344,12 +344,6 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckAttrVisitor<'a, 'tcx> {
344344
}
345345
}
346346

347-
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
348-
for &module in tcx.hir().krate().modules.keys() {
349-
tcx.ensure().check_mod_attrs(tcx.hir().local_def_id(module));
350-
}
351-
}
352-
353347
fn is_c_like_enum(item: &hir::Item) -> bool {
354348
if let hir::ItemKind::Enum(ref def, _) = item.node {
355349
for variant in &def.variants {

src/librustc/hir/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use syntax::util::parser::ExprPrecedence;
3030
use crate::ty::AdtKind;
3131
use crate::ty::query::Providers;
3232

33-
use rustc_data_structures::sync::{ParallelIterator, par_iter, Send, Sync};
33+
use rustc_data_structures::sync::{par_for_each_in, Send, Sync};
3434
use rustc_data_structures::thin_vec::ThinVec;
3535
use rustc_macros::HashStable;
3636

@@ -779,15 +779,15 @@ impl Crate {
779779
where V: itemlikevisit::ParItemLikeVisitor<'hir> + Sync + Send
780780
{
781781
parallel!({
782-
par_iter(&self.items).for_each(|(_, item)| {
782+
par_for_each_in(&self.items, |(_, item)| {
783783
visitor.visit_item(item);
784784
});
785785
}, {
786-
par_iter(&self.trait_items).for_each(|(_, trait_item)| {
786+
par_for_each_in(&self.trait_items, |(_, trait_item)| {
787787
visitor.visit_trait_item(trait_item);
788788
});
789789
}, {
790-
par_iter(&self.impl_items).for_each(|(_, impl_item)| {
790+
par_for_each_in(&self.impl_items, |(_, impl_item)| {
791791
visitor.visit_impl_item(impl_item);
792792
});
793793
});

src/librustc/middle/intrinsicck.rs

-6
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,6 @@ use syntax_pos::Span;
1010
use crate::hir::intravisit::{self, Visitor, NestedVisitorMap};
1111
use crate::hir;
1212

13-
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
14-
for &module in tcx.hir().krate().modules.keys() {
15-
tcx.ensure().check_mod_intrinsics(tcx.hir().local_def_id(module));
16-
}
17-
}
18-
1913
fn check_mod_intrinsics<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) {
2014
tcx.hir().visit_item_likes_in_module(
2115
module_def_id,

src/librustc/middle/liveness.rs

-6
Original file line numberDiff line numberDiff line change
@@ -185,12 +185,6 @@ fn check_mod_liveness<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) {
185185
tcx.hir().visit_item_likes_in_module(module_def_id, &mut IrMaps::new(tcx).as_deep_visitor());
186186
}
187187

188-
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
189-
for &module in tcx.hir().krate().modules.keys() {
190-
tcx.ensure().check_mod_liveness(tcx.hir().local_def_id(module));
191-
}
192-
}
193-
194188
pub fn provide(providers: &mut Providers<'_>) {
195189
*providers = Providers {
196190
check_mod_liveness,

src/librustc/middle/stability.rs

-6
Original file line numberDiff line numberDiff line change
@@ -456,12 +456,6 @@ impl<'a, 'tcx> Index<'tcx> {
456456
}
457457
}
458458

459-
pub fn check_unstable_api_usage<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
460-
for &module in tcx.hir().krate().modules.keys() {
461-
tcx.ensure().check_mod_unstable_api_usage(tcx.hir().local_def_id(module));
462-
}
463-
}
464-
465459
/// Cross-references the feature names of unstable APIs with enabled
466460
/// features and possibly prints errors.
467461
fn check_mod_unstable_api_usage<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) {

src/librustc/ty/query/config.rs

+6
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::privacy_access_levels<'tcx> {
369369
}
370370
}
371371

372+
impl<'tcx> QueryDescription<'tcx> for queries::check_private_in_public<'tcx> {
373+
fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
374+
"checking for private elements in public interfaces".into()
375+
}
376+
}
377+
372378
impl<'tcx> QueryDescription<'tcx> for queries::typeck_item_bodies<'tcx> {
373379
fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
374380
"type-checking all item bodies".into()

src/librustc/ty/query/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -350,8 +350,9 @@ define_queries! { <'tcx>
350350
[] fn check_match: CheckMatch(DefId)
351351
-> Result<(), ErrorReported>,
352352

353-
/// Performs the privacy check and computes "access levels".
353+
/// Performs part of the privacy check and computes "access levels".
354354
[] fn privacy_access_levels: PrivacyAccessLevels(CrateNum) -> Lrc<AccessLevels>,
355+
[] fn check_private_in_public: CheckPrivateInPublic(CrateNum) -> (),
355356
},
356357

357358
Other {

src/librustc/ty/query/plumbing.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1251,6 +1251,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
12511251
force!(crate_inherent_impls_overlap_check, LOCAL_CRATE)
12521252
},
12531253
DepKind::PrivacyAccessLevels => { force!(privacy_access_levels, LOCAL_CRATE); }
1254+
DepKind::CheckPrivateInPublic => { force!(check_private_in_public, LOCAL_CRATE); }
12541255
DepKind::MirBuilt => { force!(mir_built, def_id!()); }
12551256
DepKind::MirConstQualif => { force!(mir_const_qualif, def_id!()); }
12561257
DepKind::MirConst => { force!(mir_const, def_id!()); }

src/librustc_data_structures/sync.rs

+54-7
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ cfg_if! {
6565
}
6666

6767
use std::ops::Add;
68+
use std::panic::{resume_unwind, catch_unwind, AssertUnwindSafe};
6869

6970
#[derive(Debug)]
7071
pub struct Atomic<T: Copy>(Cell<T>);
@@ -130,7 +131,21 @@ cfg_if! {
130131
#[macro_export]
131132
macro_rules! parallel {
132133
($($blocks:tt),*) => {
133-
$($blocks)*;
134+
// We catch panics here ensuring that all the blocks execute.
135+
// This makes behavior consistent with the parallel compiler.
136+
let mut panic = None;
137+
$(
138+
if let Err(p) = ::std::panic::catch_unwind(
139+
::std::panic::AssertUnwindSafe(|| $blocks)
140+
) {
141+
if panic.is_none() {
142+
panic = Some(p);
143+
}
144+
}
145+
)*
146+
if let Some(panic) = panic {
147+
::std::panic::resume_unwind(panic);
148+
}
134149
}
135150
}
136151

@@ -140,6 +155,26 @@ cfg_if! {
140155
t.into_iter()
141156
}
142157

158+
pub fn par_for_each_in<T: IntoIterator>(
159+
t: T,
160+
for_each:
161+
impl Fn(<<T as IntoIterator>::IntoIter as Iterator>::Item) + Sync + Send
162+
) {
163+
// We catch panics here ensuring that all the loop iterations execute.
164+
// This makes behavior consistent with the parallel compiler.
165+
let mut panic = None;
166+
t.into_iter().for_each(|i| {
167+
if let Err(p) = catch_unwind(AssertUnwindSafe(|| for_each(i))) {
168+
if panic.is_none() {
169+
panic = Some(p);
170+
}
171+
}
172+
});
173+
if let Some(panic) = panic {
174+
resume_unwind(panic);
175+
}
176+
}
177+
143178
pub type MetadataRef = OwningRef<Box<dyn Erased>, [u8]>;
144179

145180
pub use std::rc::Rc as Lrc;
@@ -278,23 +313,26 @@ cfg_if! {
278313
use std::thread;
279314
pub use rayon::{join, scope};
280315

316+
/// Runs a list of blocks in parallel. The first block is executed immediately on
317+
/// the current thread. Use that for the longest running block.
281318
#[macro_export]
282319
macro_rules! parallel {
283-
(impl [$($c:tt,)*] [$block:tt $(, $rest:tt)*]) => {
284-
parallel!(impl [$block, $($c,)*] [$($rest),*])
320+
(impl $fblock:tt [$($c:tt,)*] [$block:tt $(, $rest:tt)*]) => {
321+
parallel!(impl $fblock [$block, $($c,)*] [$($rest),*])
285322
};
286-
(impl [$($blocks:tt,)*] []) => {
323+
(impl $fblock:tt [$($blocks:tt,)*] []) => {
287324
::rustc_data_structures::sync::scope(|s| {
288325
$(
289326
s.spawn(|_| $blocks);
290327
)*
328+
$fblock;
291329
})
292330
};
293-
($($blocks:tt),*) => {
294-
// Reverse the order of the blocks since Rayon executes them in reverse order
331+
($fblock:tt, $($blocks:tt),*) => {
332+
// Reverse the order of the later blocks since Rayon executes them in reverse order
295333
// when using a single thread. This ensures the execution order matches that
296334
// of a single threaded rustc
297-
parallel!(impl [] [$($blocks),*]);
335+
parallel!(impl $fblock [] [$($blocks),*]);
298336
};
299337
}
300338

@@ -307,6 +345,15 @@ cfg_if! {
307345
t.into_par_iter()
308346
}
309347

348+
pub fn par_for_each_in<T: IntoParallelIterator>(
349+
t: T,
350+
for_each: impl Fn(
351+
<<T as IntoParallelIterator>::Iter as ParallelIterator>::Item
352+
) + Sync + Send
353+
) {
354+
t.into_par_iter().for_each(for_each)
355+
}
356+
310357
pub type MetadataRef = OwningRef<Box<dyn Erased + Send + Sync>, [u8]>;
311358

312359
/// This makes locks panic if they are already held.

src/librustc_interface/passes.rs

+54-44
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use rustc_borrowck as borrowck;
2121
use rustc_codegen_utils::codegen_backend::CodegenBackend;
2222
use rustc_data_structures::fingerprint::Fingerprint;
2323
use rustc_data_structures::stable_hasher::StableHasher;
24-
use rustc_data_structures::sync::Lrc;
24+
use rustc_data_structures::sync::{Lrc, ParallelIterator, par_iter};
2525
use rustc_incremental;
2626
use rustc_metadata::creader::CrateLoader;
2727
use rustc_metadata::cstore::{self, CStore};
@@ -191,51 +191,50 @@ fn analysis<'tcx>(
191191

192192
let sess = tcx.sess;
193193

194-
parallel!({
195-
time(sess, "looking for entry point", || {
196-
middle::entry::find_entry_point(tcx)
197-
});
194+
time(sess, "misc checking 1", || {
195+
parallel!({
196+
time(sess, "looking for entry point", || {
197+
middle::entry::find_entry_point(tcx)
198+
});
198199

199-
time(sess, "looking for plugin registrar", || {
200-
plugin::build::find_plugin_registrar(tcx)
201-
});
200+
time(sess, "looking for plugin registrar", || {
201+
plugin::build::find_plugin_registrar(tcx)
202+
});
202203

203-
time(sess, "looking for derive registrar", || {
204-
proc_macro_decls::find(tcx)
205-
});
206-
}, {
207-
time(sess, "loop checking", || loops::check_crate(tcx));
208-
}, {
209-
time(sess, "attribute checking", || {
210-
hir::check_attr::check_crate(tcx)
211-
});
212-
}, {
213-
time(sess, "stability checking", || {
214-
stability::check_unstable_api_usage(tcx)
204+
time(sess, "looking for derive registrar", || {
205+
proc_macro_decls::find(tcx)
206+
});
207+
}, {
208+
par_iter(&tcx.hir().krate().modules).for_each(|(&module, _)| {
209+
tcx.ensure().check_mod_loops(tcx.hir().local_def_id(module));
210+
tcx.ensure().check_mod_attrs(tcx.hir().local_def_id(module));
211+
tcx.ensure().check_mod_unstable_api_usage(tcx.hir().local_def_id(module));
212+
});
215213
});
216214
});
217215

218216
// passes are timed inside typeck
219217
typeck::check_crate(tcx)?;
220218

221-
time(sess, "misc checking", || {
219+
time(sess, "misc checking 2", || {
222220
parallel!({
223-
time(sess, "rvalue promotion", || {
224-
rvalue_promotion::check_crate(tcx)
225-
});
226-
}, {
227-
time(sess, "intrinsic checking", || {
228-
middle::intrinsicck::check_crate(tcx)
221+
time(sess, "rvalue promotion + match checking", || {
222+
tcx.par_body_owners(|def_id| {
223+
tcx.ensure().const_is_rvalue_promotable_to_static(def_id);
224+
tcx.ensure().check_match(def_id);
225+
});
229226
});
230227
}, {
231-
time(sess, "match checking", || mir::matchck_crate(tcx));
232-
}, {
233-
// this must run before MIR dump, because
234-
// "not all control paths return a value" is reported here.
235-
//
236-
// maybe move the check to a MIR pass?
237-
time(sess, "liveness checking", || {
238-
middle::liveness::check_crate(tcx)
228+
time(sess, "liveness checking + intrinsic checking", || {
229+
par_iter(&tcx.hir().krate().modules).for_each(|(&module, _)| {
230+
// this must run before MIR dump, because
231+
// "not all control paths return a value" is reported here.
232+
//
233+
// maybe move the check to a MIR pass?
234+
tcx.ensure().check_mod_liveness(tcx.hir().local_def_id(module));
235+
236+
tcx.ensure().check_mod_intrinsics(tcx.hir().local_def_id(module));
237+
});
239238
});
240239
});
241240
});
@@ -276,19 +275,30 @@ fn analysis<'tcx>(
276275
return Err(ErrorReported);
277276
}
278277

279-
time(sess, "misc checking", || {
278+
time(sess, "misc checking 3", || {
280279
parallel!({
281-
time(sess, "privacy checking", || {
282-
rustc_privacy::check_crate(tcx)
280+
time(sess, "privacy access levels", || {
281+
tcx.ensure().privacy_access_levels(LOCAL_CRATE);
283282
});
284-
}, {
285-
time(sess, "death checking", || middle::dead::check_crate(tcx));
286-
}, {
287-
time(sess, "unused lib feature checking", || {
288-
stability::check_unused_or_stable_features(tcx)
283+
parallel!({
284+
time(sess, "private in public", || {
285+
tcx.ensure().check_private_in_public(LOCAL_CRATE);
286+
});
287+
}, {
288+
time(sess, "death checking", || middle::dead::check_crate(tcx));
289+
}, {
290+
time(sess, "unused lib feature checking", || {
291+
stability::check_unused_or_stable_features(tcx)
292+
});
293+
}, {
294+
time(sess, "lint checking", || lint::check_crate(tcx));
289295
});
290296
}, {
291-
time(sess, "lint checking", || lint::check_crate(tcx));
297+
time(sess, "privacy checking modules", || {
298+
par_iter(&tcx.hir().krate().modules).for_each(|(&module, _)| {
299+
tcx.ensure().check_mod_privacy(tcx.hir().local_def_id(module));
300+
});
301+
});
292302
});
293303
});
294304

src/librustc_mir/hair/pattern/check_match.rs

-7
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,6 @@ use std::slice;
2727
use syntax::ptr::P;
2828
use syntax_pos::{Span, DUMMY_SP, MultiSpan};
2929

30-
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
31-
for def_id in tcx.body_owners() {
32-
tcx.ensure().check_match(def_id);
33-
}
34-
tcx.sess.abort_if_errors();
35-
}
36-
3730
pub(crate) fn check_match<'a, 'tcx>(
3831
tcx: TyCtxt<'a, 'tcx, 'tcx>,
3932
def_id: DefId,

src/librustc_mir/hair/pattern/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
mod _match;
44
mod check_match;
55

6-
pub use self::check_match::check_crate;
76
pub(crate) use self::check_match::check_match;
87

98
use crate::const_eval::{const_field, const_variant_index};

src/librustc_mir/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ pub mod interpret;
5454
pub mod monomorphize;
5555
pub mod const_eval;
5656

57-
pub use hair::pattern::check_crate as matchck_crate;
5857
use rustc::ty::query::Providers;
5958

6059
pub fn provide(providers: &mut Providers<'_>) {

0 commit comments

Comments
 (0)