about summary refs log tree commit diff
path: root/src/librustc_data_structures
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-03-09 17:18:20 +0100
committerGitHub <noreply@github.com>2019-03-09 17:18:20 +0100
commitf32d62e5ae28c8398630117a2aea4a5cf5fb13f1 (patch)
tree111900ad79035e738bce4a1d56296677ad778fc8 /src/librustc_data_structures
parent3f872b209ba573e28053885e9fc4a86581fb82ea (diff)
parent7985c6f8ecf680dcc960bb2ccc0c787274a449de (diff)
downloadrust-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.rs61
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.