diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-03-09 17:18:20 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-03-09 17:18:20 +0100 |
| commit | f32d62e5ae28c8398630117a2aea4a5cf5fb13f1 (patch) | |
| tree | 111900ad79035e738bce4a1d56296677ad778fc8 /src/librustc_data_structures | |
| parent | 3f872b209ba573e28053885e9fc4a86581fb82ea (diff) | |
| parent | 7985c6f8ecf680dcc960bb2ccc0c787274a449de (diff) | |
| download | rust-f32d62e5ae28c8398630117a2aea4a5cf5fb13f1.tar.gz rust-f32d62e5ae28c8398630117a2aea4a5cf5fb13f1.zip | |
Rollup merge of #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 https://github.com/rust-lang/rust/pull/58494 Blocked on https://github.com/rust-lang/rust/pull/58250 r? @michaelwoerister
Diffstat (limited to 'src/librustc_data_structures')
| -rw-r--r-- | src/librustc_data_structures/sync.rs | 61 |
1 files changed, 54 insertions, 7 deletions
diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs index ba1f6eb56fe..73247c1469e 100644 --- a/src/librustc_data_structures/sync.rs +++ b/src/librustc_data_structures/sync.rs @@ -65,6 +65,7 @@ cfg_if! { } use std::ops::Add; + use std::panic::{resume_unwind, catch_unwind, AssertUnwindSafe}; #[derive(Debug)] pub struct Atomic<T: Copy>(Cell<T>); @@ -130,7 +131,21 @@ cfg_if! { #[macro_export] macro_rules! parallel { ($($blocks:tt),*) => { - $($blocks)*; + // We catch panics here ensuring that all the blocks execute. + // This makes behavior consistent with the parallel compiler. + let mut panic = None; + $( + if let Err(p) = ::std::panic::catch_unwind( + ::std::panic::AssertUnwindSafe(|| $blocks) + ) { + if panic.is_none() { + panic = Some(p); + } + } + )* + if let Some(panic) = panic { + ::std::panic::resume_unwind(panic); + } } } @@ -140,6 +155,26 @@ cfg_if! { t.into_iter() } + pub fn par_for_each_in<T: IntoIterator>( + t: T, + for_each: + impl Fn(<<T as IntoIterator>::IntoIter as Iterator>::Item) + Sync + Send + ) { + // We catch panics here ensuring that all the loop iterations execute. + // This makes behavior consistent with the parallel compiler. + let mut panic = None; + t.into_iter().for_each(|i| { + if let Err(p) = catch_unwind(AssertUnwindSafe(|| for_each(i))) { + if panic.is_none() { + panic = Some(p); + } + } + }); + if let Some(panic) = panic { + resume_unwind(panic); + } + } + pub type MetadataRef = OwningRef<Box<dyn Erased>, [u8]>; pub use std::rc::Rc as Lrc; @@ -278,23 +313,26 @@ cfg_if! { use std::thread; pub use rayon::{join, scope}; + /// Runs a list of blocks in parallel. The first block is executed immediately on + /// the current thread. Use that for the longest running block. #[macro_export] macro_rules! parallel { - (impl [$($c:tt,)*] [$block:tt $(, $rest:tt)*]) => { - parallel!(impl [$block, $($c,)*] [$($rest),*]) + (impl $fblock:tt [$($c:tt,)*] [$block:tt $(, $rest:tt)*]) => { + parallel!(impl $fblock [$block, $($c,)*] [$($rest),*]) }; - (impl [$($blocks:tt,)*] []) => { + (impl $fblock:tt [$($blocks:tt,)*] []) => { ::rustc_data_structures::sync::scope(|s| { $( s.spawn(|_| $blocks); )* + $fblock; }) }; - ($($blocks:tt),*) => { - // Reverse the order of the blocks since Rayon executes them in reverse order + ($fblock:tt, $($blocks:tt),*) => { + // Reverse the order of the later blocks since Rayon executes them in reverse order // when using a single thread. This ensures the execution order matches that // of a single threaded rustc - parallel!(impl [] [$($blocks),*]); + parallel!(impl $fblock [] [$($blocks),*]); }; } @@ -307,6 +345,15 @@ cfg_if! { t.into_par_iter() } + pub fn par_for_each_in<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) + } + pub type MetadataRef = OwningRef<Box<dyn Erased + Send + Sync>, [u8]>; /// This makes locks panic if they are already held. |
