From f4342d2bc804243d8f2588cb52918ab14aadb523 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 2 Jan 2020 15:35:38 +0100 Subject: [PATCH] Increase parallelism in various locations --- .../rustc_hir_analysis/src/check/wfcheck.rs | 25 ++-- compiler/rustc_hir_analysis/src/lib.rs | 13 +- compiler/rustc_interface/src/passes.rs | 132 ++++++++++-------- compiler/rustc_middle/src/hir/mod.rs | 30 +++- compiler/rustc_monomorphize/src/collector.rs | 19 ++- compiler/rustc_privacy/src/lib.rs | 4 +- .../ui/macros/macro-span-issue-116502.stderr | 8 +- tests/ui/span/issue-35987.rs | 2 +- ...uggestion-trait-object-issue-139174.stderr | 12 +- .../typeck_type_placeholder_item.stderr | 108 +++++++------- 10 files changed, 201 insertions(+), 152 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 8b50eceb26e49..d463ecb956393 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -2305,15 +2305,22 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { pub(super) fn check_type_wf(tcx: TyCtxt<'_>, (): ()) -> Result<(), ErrorGuaranteed> { let items = tcx.hir_crate_items(()); - let res = items - .par_items(|item| tcx.ensure_ok().check_well_formed(item.owner_id.def_id)) - .and(items.par_impl_items(|item| tcx.ensure_ok().check_well_formed(item.owner_id.def_id))) - .and(items.par_trait_items(|item| tcx.ensure_ok().check_well_formed(item.owner_id.def_id))) - .and( - items.par_foreign_items(|item| tcx.ensure_ok().check_well_formed(item.owner_id.def_id)), - ) - .and(items.par_nested_bodies(|item| tcx.ensure_ok().check_well_formed(item))) - .and(items.par_opaques(|item| tcx.ensure_ok().check_well_formed(item))); + let res = + items + .try_par_items(|item| tcx.ensure_ok().check_well_formed(item.owner_id.def_id)) + .and( + items.try_par_impl_items(|item| { + tcx.ensure_ok().check_well_formed(item.owner_id.def_id) + }), + ) + .and(items.try_par_trait_items(|item| { + tcx.ensure_ok().check_well_formed(item.owner_id.def_id) + })) + .and(items.try_par_foreign_items(|item| { + tcx.ensure_ok().check_well_formed(item.owner_id.def_id) + })) + .and(items.try_par_nested_bodies(|item| tcx.ensure_ok().check_well_formed(item))) + .and(items.try_par_opaques(|item| tcx.ensure_ok().check_well_formed(item))); super::entry::check_for_entry_fn(tcx); res diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 3a4d894239fc6..0834c71f7e56a 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -84,7 +84,8 @@ mod variance; pub use errors::NoVariantNamed; use rustc_abi::{CVariadicStatus, ExternAbi}; -use rustc_hir::attrs::AttributeKind; + +use rustc_data_structures::sync::par_for_each_in;use rustc_hir::attrs::AttributeKind; use rustc_hir::def::DefKind; use rustc_hir::lints::DelayedLint; use rustc_hir::{ @@ -175,6 +176,9 @@ fn emit_delayed_lint(lint: &DelayedLint, tcx: TyCtxt<'_>) { pub fn check_crate(tcx: TyCtxt<'_>) { let _prof_timer = tcx.sess.timer("type_check_crate"); + // Run dependencies of type checking before entering the loops below + tcx.ensure_done().inferred_outlives_crate(()); + tcx.sess.time("coherence_checking", || { // When discarding query call results, use an explicit type to indicate // what we are intending to discard, to help future type-based refactoring. @@ -182,9 +186,10 @@ pub fn check_crate(tcx: TyCtxt<'_>) { let _: R = tcx.ensure_ok().check_type_wf(()); - for &trait_def_id in tcx.all_local_trait_impls(()).keys() { - let _: R = tcx.ensure_ok().coherent_trait(trait_def_id); - } + par_for_each_in(tcx.all_local_trait_impls(()), |(trait_def_id, _)| { + let _: R = tcx.ensure_ok().coherent_trait(*trait_def_id); + }); + // these queries are executed for side-effects (error reporting): let _: R = tcx.ensure_ok().crate_inherent_impls_validity_check(()); let _: R = tcx.ensure_ok().crate_inherent_impls_overlap_check(()); diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index f5fb8031ab0f0..8f8d290821737 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -1068,8 +1068,19 @@ fn run_required_analyses(tcx: TyCtxt<'_>) { { tcx.ensure_ok().exportable_items(LOCAL_CRATE); tcx.ensure_ok().stable_order_of_exportable_impls(LOCAL_CRATE); + + // Prefetch this as it is used later by the loop below + // to prevent multiple threads from blocking on it. + tcx.ensure_done().get_lang_items(()); + + let _timer = tcx.sess.timer("misc_module_passes"); tcx.par_hir_for_each_module(|module| { tcx.ensure_ok().check_mod_attrs(module); + }); + }, + { + let _timer = tcx.sess.timer("check_unstable_api_usage"); + tcx.par_hir_for_each_module(|module| { tcx.ensure_ok().check_mod_unstable_api_usage(module); }); }, @@ -1091,49 +1102,56 @@ fn run_required_analyses(tcx: TyCtxt<'_>) { // This improves performance by allowing lock-free access to them. tcx.untracked().definitions.freeze(); - sess.time("MIR_borrow_checking", || { - tcx.par_hir_body_owners(|def_id| { - let not_typeck_child = !tcx.is_typeck_child(def_id.to_def_id()); - if not_typeck_child { - // Child unsafety and borrowck happens together with the parent - tcx.ensure_ok().check_unsafety(def_id); - } - if tcx.is_trivial_const(def_id) { - return; - } - if not_typeck_child { - tcx.ensure_ok().mir_borrowck(def_id); - tcx.ensure_ok().check_transmutes(def_id); - } - tcx.ensure_ok().has_ffi_unwind_calls(def_id); - tcx.ensure_ok().check_liveness(def_id); - - // If we need to codegen, ensure that we emit all errors from - // `mir_drops_elaborated_and_const_checked` now, to avoid discovering - // them later during codegen. - if tcx.sess.opts.output_types.should_codegen() - || tcx.hir_body_const_context(def_id).is_some() + sess.time("misc_checking_2", || { + parallel!( { - tcx.ensure_ok().mir_drops_elaborated_and_const_checked(def_id); - } - if tcx.is_coroutine(def_id.to_def_id()) { - tcx.ensure_ok().mir_coroutine_witnesses(def_id); - let _ = tcx.ensure_ok().check_coroutine_obligations( - tcx.typeck_root_def_id(def_id.to_def_id()).expect_local(), - ); - if !tcx.is_async_drop_in_place_coroutine(def_id.to_def_id()) { - // Eagerly check the unsubstituted layout for cycles. - tcx.ensure_ok().layout_of( - ty::TypingEnv::post_analysis(tcx, def_id.to_def_id()) - .as_query_input(tcx.type_of(def_id).instantiate_identity()), - ); - } + // Prefetch this as it is used later by lint checking and privacy checking. + tcx.ensure_done().effective_visibilities(()); + }, + { + sess.time("misc_body_checking", || { + tcx.par_hir_body_owners(|def_id| { + if !tcx.is_typeck_child(def_id.to_def_id()) { + // Child unsafety and borrowck happens together with the parent + tcx.ensure_ok().check_unsafety(def_id); + tcx.ensure_ok().mir_borrowck(def_id); + tcx.ensure_ok().check_transmutes(def_id); + } + tcx.ensure_ok().has_ffi_unwind_calls(def_id); + + // If we need to codegen, ensure that we emit all errors from + // `mir_drops_elaborated_and_const_checked` now, to avoid discovering + // them later during codegen. + if tcx.sess.opts.output_types.should_codegen() + || tcx.hir_body_const_context(def_id).is_some() + { + tcx.ensure_ok().mir_drops_elaborated_and_const_checked(def_id); + } + + if tcx.is_coroutine(def_id.to_def_id()) { + tcx.ensure_ok().mir_coroutine_witnesses(def_id); + let _ = tcx.ensure_ok().check_coroutine_obligations( + tcx.typeck_root_def_id(def_id.to_def_id()).expect_local(), + ); + if !tcx.is_async_drop_in_place_coroutine(def_id.to_def_id()) { + // Eagerly check the unsubstituted layout for cycles. + tcx.ensure_ok().layout_of( + ty::TypingEnv::post_analysis(tcx, def_id.to_def_id()) + .as_query_input(tcx.type_of(def_id).instantiate_identity()), + ); + } + } + }); + }); + }, + { + sess.time("layout_testing", || layout_test::test_layout(tcx)); + sess.time("abi_testing", || abi_test::test_abi(tcx)); } - }); + ) }); - sess.time("layout_testing", || layout_test::test_layout(tcx)); - sess.time("abi_testing", || abi_test::test_abi(tcx)); + } } /// Runs the type-checking, region checking and other miscellaneous analysis @@ -1158,28 +1176,20 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) { sess.time("misc_checking_3", || { parallel!( { - tcx.ensure_ok().effective_visibilities(()); - - parallel!( - { - tcx.par_hir_for_each_module(|module| { - tcx.ensure_ok().check_private_in_public(module) - }) - }, - { - tcx.par_hir_for_each_module(|module| { - tcx.ensure_ok().check_mod_deathness(module) - }); - }, - { - sess.time("lint_checking", || { - rustc_lint::check_crate(tcx); - }); - }, - { - tcx.ensure_ok().clashing_extern_declarations(()); - } - ); + tcx.par_hir_for_each_module(|module| { + tcx.ensure_ok().check_private_in_public(module) + }) + }, + { + tcx.par_hir_for_each_module(|module| tcx.ensure_ok().check_mod_deathness(module)); + }, + { + sess.time("lint_checking", || { + rustc_lint::check_crate(tcx); + }); + }, + { + tcx.ensure_ok().clashing_extern_declarations(()); }, { sess.time("privacy_checking_modules", || { diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index ba2d8febad7c5..12f39ca1cd6a3 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -9,7 +9,7 @@ pub mod place; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_data_structures::sync::{DynSend, DynSync, try_par_for_each_in}; +use rustc_data_structures::sync::{DynSend, DynSync, par_for_each_in, try_par_for_each_in}; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId}; use rustc_hir::lints::DelayedLint; @@ -99,47 +99,63 @@ impl ModuleItems { } /// Closures and inline consts - pub fn par_nested_bodies( + pub fn try_par_nested_bodies( &self, f: impl Fn(LocalDefId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync, ) -> Result<(), ErrorGuaranteed> { try_par_for_each_in(&self.nested_bodies[..], |&&id| f(id)) } - pub fn par_items( + pub fn try_par_items( &self, f: impl Fn(ItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync, ) -> Result<(), ErrorGuaranteed> { try_par_for_each_in(&self.free_items[..], |&&id| f(id)) } - pub fn par_trait_items( + pub fn try_par_trait_items( &self, f: impl Fn(TraitItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync, ) -> Result<(), ErrorGuaranteed> { try_par_for_each_in(&self.trait_items[..], |&&id| f(id)) } - pub fn par_impl_items( + pub fn try_par_impl_items( &self, f: impl Fn(ImplItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync, ) -> Result<(), ErrorGuaranteed> { try_par_for_each_in(&self.impl_items[..], |&&id| f(id)) } - pub fn par_foreign_items( + pub fn try_par_foreign_items( &self, f: impl Fn(ForeignItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync, ) -> Result<(), ErrorGuaranteed> { try_par_for_each_in(&self.foreign_items[..], |&&id| f(id)) } - pub fn par_opaques( + pub fn try_par_opaques( &self, f: impl Fn(LocalDefId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync, ) -> Result<(), ErrorGuaranteed> { try_par_for_each_in(&self.opaques[..], |&&id| f(id)) } + + pub fn par_items(&self, f: impl Fn(ItemId) + DynSend + DynSync) { + par_for_each_in(&self.free_items[..], |&&id| f(id)) + } + + pub fn par_trait_items(&self, f: impl Fn(TraitItemId) + DynSend + DynSync) { + par_for_each_in(&self.trait_items[..], |&&id| f(id)) + } + + pub fn par_impl_items(&self, f: impl Fn(ImplItemId) + DynSend + DynSync) { + par_for_each_in(&self.impl_items[..], |&&id| f(id)) + } + + pub fn par_foreign_items(&self, f: impl Fn(ForeignItemId) + DynSend + DynSync) { + par_for_each_in(&self.foreign_items[..], |&&id| f(id)) + } } impl<'tcx> TyCtxt<'tcx> { diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 81d46e3b5b0d4..bf0f9e564e629 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -211,7 +211,7 @@ use std::cell::OnceCell; use std::ops::ControlFlow; use rustc_data_structures::fx::FxIndexMap; -use rustc_data_structures::sync::{MTLock, par_for_each_in}; +use rustc_data_structures::sync::{MTLock, join, par_for_each_in}; use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_hir as hir; use rustc_hir::attrs::InlineAttr; @@ -1806,9 +1806,20 @@ pub(crate) fn collect_crate_mono_items<'tcx>( ) -> (Vec>, UsageMap<'tcx>) { let _prof_timer = tcx.prof.generic_activity("monomorphization_collector"); - let roots = tcx - .sess - .time("monomorphization_collector_root_collections", || collect_roots(tcx, strategy)); + let (roots, _) = join( + || { + tcx.sess.time("monomorphization_collector_root_collections", || { + collect_roots(tcx, strategy) + }) + }, + || { + if tcx.sess.opts.share_generics() { + // Prefetch upstream_monomorphizations as it's very likely to be used in + // code generation later and this is decent spot to compute it. + tcx.ensure_ok().upstream_monomorphizations(()); + } + }, + ); debug!("building mono item graph, beginning at roots"); diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 8656ec6e39aed..e1ab4e65fd5f4 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -1882,6 +1882,6 @@ fn check_private_in_public(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { let checker = PrivateItemsInPublicInterfacesChecker { tcx, effective_visibilities }; let crate_items = tcx.hir_module_items(module_def_id); - let _ = crate_items.par_items(|id| Ok(checker.check_item(id))); - let _ = crate_items.par_foreign_items(|id| Ok(checker.check_foreign_item(id))); + crate_items.par_items(|id| checker.check_item(id)); + crate_items.par_foreign_items(|id| checker.check_foreign_item(id)); } diff --git a/tests/ui/macros/macro-span-issue-116502.stderr b/tests/ui/macros/macro-span-issue-116502.stderr index 024656e685f5b..4bf8d4a449498 100644 --- a/tests/ui/macros/macro-span-issue-116502.stderr +++ b/tests/ui/macros/macro-span-issue-116502.stderr @@ -5,7 +5,7 @@ LL | _ | ^ not allowed in type signatures ... LL | struct S(m!(), T) - | ---- in this macro invocation + | ---- in this macro invocation | = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -15,7 +15,7 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures LL | _ | ^ not allowed in type signatures ... -LL | T: Trait; +LL | struct S(m!(), T) | ---- in this macro invocation | = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -26,8 +26,8 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures LL | _ | ^ not allowed in type signatures ... -LL | struct S(m!(), T) - | ---- in this macro invocation +LL | T: Trait; + | ---- in this macro invocation | = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/span/issue-35987.rs b/tests/ui/span/issue-35987.rs index d52a3793af971..7fa1a33ac84c1 100644 --- a/tests/ui/span/issue-35987.rs +++ b/tests/ui/span/issue-35987.rs @@ -3,7 +3,7 @@ struct Foo(T); use std::ops::Add; impl Add for Foo { -//~^ ERROR expected trait, found type parameter + //~^ ERROR expected trait, found type parameter type Output = usize; fn add(self, rhs: Self) -> Self::Output { diff --git a/tests/ui/traits/object/suggestion-trait-object-issue-139174.stderr b/tests/ui/traits/object/suggestion-trait-object-issue-139174.stderr index 0d1ce85fc2888..80f91076ffc14 100644 --- a/tests/ui/traits/object/suggestion-trait-object-issue-139174.stderr +++ b/tests/ui/traits/object/suggestion-trait-object-issue-139174.stderr @@ -16,6 +16,12 @@ error[E0404]: expected trait, found builtin type `usize` LL | x: usize + 'a, | ^^^^^ not a trait +error[E0782]: expected a type, found a trait + --> $DIR/suggestion-trait-object-issue-139174.rs:16:8 + | +LL | x: usize + 'a, + | ^^^^^^^^^^ + error[E0782]: expected a type, found a trait --> $DIR/suggestion-trait-object-issue-139174.rs:3:36 | @@ -28,12 +34,6 @@ error[E0782]: expected a type, found a trait LL | fn create_adder<'a>(x: i32) -> usize + 'a { | ^^^^^^^^^^ -error[E0782]: expected a type, found a trait - --> $DIR/suggestion-trait-object-issue-139174.rs:16:8 - | -LL | x: usize + 'a, - | ^^^^^^^^^^ - error: aborting due to 6 previous errors Some errors have detailed explanations: E0404, E0782. diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr index 0b70ac97fd435..b26614238b268 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.stderr +++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr @@ -44,6 +44,60 @@ LL | struct BadStruct1<_, _>(_); | | | first use of `_` +error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/typeck_type_placeholder_item.rs:66:8 + | +LL | a: _, + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/typeck_type_placeholder_item.rs:68:9 + | +LL | b: (_, _), + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/typeck_type_placeholder_item.rs:68:12 + | +LL | b: (_, _), + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/typeck_type_placeholder_item.rs:123:12 + | +LL | a: _, + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/typeck_type_placeholder_item.rs:125:13 + | +LL | b: (_, _), + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/typeck_type_placeholder_item.rs:125:16 + | +LL | b: (_, _), + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/typeck_type_placeholder_item.rs:158:21 + | +LL | struct BadStruct<_>(_); + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/typeck_type_placeholder_item.rs:173:25 + | +LL | struct BadStruct1<_, _>(_); + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/typeck_type_placeholder_item.rs:178:25 + | +LL | struct BadStruct2<_, T>(_, T); + | ^ not allowed in type signatures + error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types --> $DIR/typeck_type_placeholder_item.rs:7:14 | @@ -138,60 +192,6 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures LL | fn test8(_f: fn() -> _) { } | ^ not allowed in type signatures -error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs - --> $DIR/typeck_type_placeholder_item.rs:66:8 - | -LL | a: _, - | ^ not allowed in type signatures - -error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs - --> $DIR/typeck_type_placeholder_item.rs:68:9 - | -LL | b: (_, _), - | ^ not allowed in type signatures - -error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs - --> $DIR/typeck_type_placeholder_item.rs:68:12 - | -LL | b: (_, _), - | ^ not allowed in type signatures - -error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs - --> $DIR/typeck_type_placeholder_item.rs:123:12 - | -LL | a: _, - | ^ not allowed in type signatures - -error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs - --> $DIR/typeck_type_placeholder_item.rs:125:13 - | -LL | b: (_, _), - | ^ not allowed in type signatures - -error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs - --> $DIR/typeck_type_placeholder_item.rs:125:16 - | -LL | b: (_, _), - | ^ not allowed in type signatures - -error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs - --> $DIR/typeck_type_placeholder_item.rs:158:21 - | -LL | struct BadStruct<_>(_); - | ^ not allowed in type signatures - -error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs - --> $DIR/typeck_type_placeholder_item.rs:173:25 - | -LL | struct BadStruct1<_, _>(_); - | ^ not allowed in type signatures - -error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs - --> $DIR/typeck_type_placeholder_item.rs:178:25 - | -LL | struct BadStruct2<_, T>(_, T); - | ^ not allowed in type signatures - error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types --> $DIR/typeck_type_placeholder_item.rs:47:26 |