Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parallel tweaks #67870

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/librustc/hir/map/hir_id_validator.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::hir::map::Map;
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::sync::{par_iter, Lock, ParallelIterator};
use rustc_data_structures::sync::{par_for_each, Lock};
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX};
use rustc_hir::intravisit;
Expand All @@ -12,7 +12,7 @@ pub fn check_crate(hir_map: &Map<'_>) {

let errors = Lock::new(Vec::new());

par_iter(&hir_map.krate().modules).for_each(|(module_id, _)| {
par_for_each(&hir_map.krate().modules, |(module_id, _)| {
let local_def_id = hir_map.local_def_id(*module_id);
hir_map.visit_item_likes_in_module(
local_def_id,
Expand Down
38 changes: 37 additions & 1 deletion src/librustc/hir/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ use crate::middle::cstore::CrateStoreDyn;
use crate::ty::query::Providers;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::svh::Svh;

use rustc_data_structures::sync::{self, par_for_each};
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX};
use rustc_hir::intravisit;
use rustc_hir::itemlikevisit::ItemLikeVisitor;
use rustc_hir::itemlikevisit::{ItemLikeVisitor, ParItemLikeVisitor};
use rustc_hir::print::Nested;
use rustc_hir::*;
use rustc_index::vec::IndexVec;
Expand Down Expand Up @@ -582,6 +584,40 @@ impl<'hir> Map<'hir> {
}
}

/// A parallel version of `visit_item_likes_in_module`.
pub fn par_visit_item_likes_in_module<V>(&self, module: DefId, visitor: &V)
where
V: ParItemLikeVisitor<'hir> + sync::Sync,
{
let hir_id = self.as_local_hir_id(module).unwrap();

// Read the module so we'll be re-executed if new items
// appear immediately under in the module. If some new item appears
// in some nested item in the module, we'll be re-executed due to reads
// in the expect_* calls the loops below
self.read(hir_id);

let module = &self.forest.krate.modules[&hir_id];

parallel!(
{
par_for_each(&module.items, |id| {
visitor.visit_item(self.expect_item(*id));
});
},
{
par_for_each(&module.trait_items, |id| {
visitor.visit_trait_item(self.expect_trait_item(id.hir_id));
});
},
{
par_for_each(&module.impl_items, |id| {
visitor.visit_impl_item(self.expect_impl_item(id.hir_id));
});
}
);
}

/// Retrieves the `Node` corresponding to `id`, panicking if it cannot be found.
pub fn get(&self, id: HirId) -> Node<'hir> {
// read recorded by `find`
Expand Down
1 change: 1 addition & 0 deletions src/librustc/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,7 @@ rustc_queries! {

TypeChecking {
query typeck_item_bodies(_: CrateNum) -> () {
eval_always
desc { "type-checking all item bodies" }
}

Expand Down
7 changes: 4 additions & 3 deletions src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::{self, par_iter, Lrc, ParallelIterator};
use rustc_data_structures::sync::{self, par_for_each, Lrc};
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
Expand Down Expand Up @@ -2699,8 +2699,9 @@ impl<'tcx> TyCtxt<'tcx> {
}

pub fn par_body_owners<F: Fn(DefId) + sync::Sync + sync::Send>(self, f: F) {
par_iter(&self.hir().krate().body_ids)
.for_each(|&body_id| f(self.hir().body_owner_def_id(body_id)));
par_for_each(&self.hir().krate().body_ids, |&body_id| {
f(self.hir().body_owner_def_id(body_id))
});
}

pub fn provided_trait_methods(self, id: DefId) -> Vec<AssocItem> {
Expand Down
18 changes: 8 additions & 10 deletions src/librustc_codegen_ssa/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ use rustc_attr as attr;
use rustc_codegen_utils::{check_for_rustc_errors_attr, symbol_names_test};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::profiling::print_time_passes_entry;
use rustc_data_structures::sync::{par_iter, Lock, ParallelIterator};
use rustc_data_structures::sync::{par_map, Lock};
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_index::vec::Idx;
Expand Down Expand Up @@ -631,15 +631,13 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
.collect();

// Compile the found CGUs in parallel.
par_iter(cgus)
.map(|(i, _)| {
let start_time = Instant::now();
let module = backend.compile_codegen_unit(tcx, codegen_units[i].name());
let mut time = total_codegen_time.lock();
*time += start_time.elapsed();
(i, module)
})
.collect()
par_map(cgus, |(i, _)| {
let start_time = Instant::now();
let module = backend.compile_codegen_unit(tcx, codegen_units[i].name());
let mut time = total_codegen_time.lock();
*time += start_time.elapsed();
(i, module)
})
})
} else {
FxHashMap::default()
Expand Down
113 changes: 74 additions & 39 deletions src/librustc_data_structures/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,33 @@
//! depending on the value of cfg!(parallel_compiler).

use crate::owning_ref::{Erased, OwningRef};
use std::any::Any;
use std::collections::HashMap;
use std::hash::{BuildHasher, Hash};
use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};
use std::panic::{catch_unwind, resume_unwind, AssertUnwindSafe};

pub use std::sync::atomic::Ordering;
pub use std::sync::atomic::Ordering::SeqCst;

pub fn catch<R>(
store: &Lock<Option<Box<dyn Any + std::marker::Send + 'static>>>,
f: impl FnOnce() -> R,
) -> Option<R> {
catch_unwind(AssertUnwindSafe(f))
.map_err(|err| {
*store.lock() = Some(err);
})
.ok()
}

pub fn resume(store: Lock<Option<Box<dyn Any + std::marker::Send + 'static>>>) {
if let Some(panic) = store.into_inner() {
resume_unwind(panic);
}
}

cfg_if! {
if #[cfg(not(parallel_compiler))] {
pub auto trait Send {}
Expand All @@ -42,7 +61,6 @@ cfg_if! {
}

use std::ops::Add;
use std::panic::{resume_unwind, catch_unwind, AssertUnwindSafe};

/// This is a single threaded variant of AtomicCell provided by crossbeam.
/// Unlike `Atomic` this is intended for all `Copy` types,
Expand Down Expand Up @@ -157,7 +175,11 @@ cfg_if! {
where A: FnOnce() -> RA,
B: FnOnce() -> RB
{
(oper_a(), oper_b())
let panic = Lock::new(None);
let a = catch(&panic, oper_a);
let b = catch(&panic, oper_b);
resume(panic);
(a.unwrap(), b.unwrap())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This now uses the resumes the last instead of first panic.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which is fine, we only use a single panic value in rustc (excluding bugs).

}

pub struct SerialScope;
Expand All @@ -181,46 +203,40 @@ cfg_if! {
($($blocks:tt),*) => {
// We catch panics here ensuring that all the blocks execute.
// This makes behavior consistent with the parallel compiler.
let mut panic = None;
let panic = $crate::sync::Lock::new(None);
$(
if let Err(p) = ::std::panic::catch_unwind(
::std::panic::AssertUnwindSafe(|| $blocks)
) {
if panic.is_none() {
panic = Some(p);
}
}
$crate::sync::catch(&panic, || $blocks);
)*
if let Some(panic) = panic {
::std::panic::resume_unwind(panic);
$crate::sync::resume(panic);
}
}
}

pub use std::iter::Iterator as ParallelIterator;
use std::iter::{Iterator, IntoIterator, FromIterator};

pub fn par_iter<T: IntoIterator>(t: T) -> T::IntoIter {
t.into_iter()
}

pub fn par_for_each_in<T: IntoIterator>(
pub fn par_for_each<T: IntoIterator>(
t: T,
for_each:
impl Fn(<<T as IntoIterator>::IntoIter as Iterator>::Item) + Sync + Send
mut for_each: impl FnMut(<<T as IntoIterator>::IntoIter as Iterator>::Item),
) {
// We catch panics here ensuring that all the loop iterations execute.
// This makes behavior consistent with the parallel compiler.
let mut panic = None;
let panic = Lock::new(None);
t.into_iter().for_each(|i| {
if let Err(p) = catch_unwind(AssertUnwindSafe(|| for_each(i))) {
if panic.is_none() {
panic = Some(p);
}
}
catch(&panic, || for_each(i));
});
if let Some(panic) = panic {
resume_unwind(panic);
resume(panic);
}

pub fn par_map<T: IntoIterator, R, C: FromIterator<R>>(
t: T,
mut map: impl FnMut(<<T as IntoIterator>::IntoIter as Iterator>::Item) -> R,
) -> C {
// We catch panics here ensuring that all the loop iterations execute.
let panic = Lock::new(None);
let r = t.into_iter().filter_map(|i| {
catch(&panic, || map(i))
}).collect();
resume(panic);
r
}

pub type MetadataRef = OwningRef<Box<dyn Erased>, [u8]>;
Expand Down Expand Up @@ -371,7 +387,7 @@ cfg_if! {
parallel!(impl $fblock [$block, $($c,)*] [$($rest),*])
};
(impl $fblock:tt [$($blocks:tt,)*] []) => {
::rustc_data_structures::sync::scope(|s| {
$crate::sync::scope(|s| {
$(
s.spawn(|_| $blocks);
)*
Expand All @@ -388,20 +404,39 @@ cfg_if! {

pub use rayon_core::WorkerLocal;

pub use rayon::iter::ParallelIterator;
use rayon::iter::IntoParallelIterator;

pub fn par_iter<T: IntoParallelIterator>(t: T) -> T::Iter {
t.into_par_iter()
}
use rayon::iter::{ParallelIterator, FromParallelIterator, IntoParallelIterator};

pub fn par_for_each_in<T: IntoParallelIterator>(
pub fn par_for_each<T: IntoParallelIterator>(
t: T,
for_each: impl Fn(
<<T as IntoParallelIterator>::Iter as ParallelIterator>::Item
) + Sync + Send
) {
t.into_par_iter().for_each(for_each)
// We catch panics here ensuring that all the loop iterations execute.
let panic = Lock::new(None);
t.into_par_iter().for_each(|i| {
catch(&panic, || for_each(i));
});
resume(panic);
}

pub fn par_map<
T: IntoParallelIterator,
R: Send,
C: FromParallelIterator<R>
>(
t: T,
map: impl Fn(
<<T as IntoParallelIterator>::Iter as ParallelIterator>::Item
) -> R + Sync + Send
) -> C {
// We catch panics here ensuring that all the loop iterations execute.
let panic = Lock::new(None);
let r = t.into_par_iter().filter_map(|i| {
catch(&panic, || map(i))
}).collect();
resume(panic);
r
}

pub type MetadataRef = OwningRef<Box<dyn Erased + Send + Sync>, [u8]>;
Expand All @@ -414,7 +449,7 @@ cfg_if! {
macro_rules! rustc_erase_owner {
($v:expr) => {{
let v = $v;
::rustc_data_structures::sync::assert_send_val(&v);
$crate::sync::assert_send_val(&v);
v.erase_send_sync_owner()
}}
}
Expand Down
8 changes: 4 additions & 4 deletions src/librustc_hir/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ crate use FunctionRetTy::*;
crate use UnsafeSource::*;

use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::sync::{par_for_each_in, Send, Sync};
use rustc_data_structures::sync::{par_for_each, Send, Sync};
use rustc_errors::FatalError;
use rustc_macros::HashStable_Generic;
use rustc_span::source_map::{SourceMap, Spanned};
Expand Down Expand Up @@ -678,17 +678,17 @@ impl Crate<'_> {
{
parallel!(
{
par_for_each_in(&self.items, |(_, item)| {
par_for_each(&self.items, |(_, item)| {
visitor.visit_item(item);
});
},
{
par_for_each_in(&self.trait_items, |(_, trait_item)| {
par_for_each(&self.trait_items, |(_, trait_item)| {
visitor.visit_trait_item(trait_item);
});
},
{
par_for_each_in(&self.impl_items, |(_, impl_item)| {
par_for_each(&self.impl_items, |(_, impl_item)| {
visitor.visit_impl_item(impl_item);
});
}
Expand Down
7 changes: 7 additions & 0 deletions src/librustc_hir/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ pub trait IntoVisitor<'hir> {
fn into_visitor(&self) -> Self::Visitor;
}

impl<'hir, T: Clone + Visitor<'hir>> IntoVisitor<'hir> for T {
type Visitor = Self;
fn into_visitor(&self) -> Self::Visitor {
self.clone()
}
}

pub struct ParDeepVisitor<V>(pub V);

impl<'hir, V> ParItemLikeVisitor<'hir> for ParDeepVisitor<V>
Expand Down
Loading