Skip to content

Commit 28a1182

Browse files
committed
Add parallel abstractions
1 parent 022dff4 commit 28a1182

File tree

5 files changed

+101
-1
lines changed

5 files changed

+101
-1
lines changed

src/librustc/hir/itemlikevisit.rs

+30
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,33 @@ impl<'v, 'hir, V> ItemLikeVisitor<'hir> for DeepVisitor<'v, V>
8888
self.visitor.visit_impl_item(impl_item);
8989
}
9090
}
91+
92+
/// A parallel variant of ItemLikeVisitor
93+
pub trait ParItemLikeVisitor<'hir> {
94+
fn visit_item(&self, item: &'hir Item);
95+
fn visit_trait_item(&self, trait_item: &'hir TraitItem);
96+
fn visit_impl_item(&self, impl_item: &'hir ImplItem);
97+
}
98+
99+
pub trait IntoVisitor<'hir> {
100+
type Visitor: Visitor<'hir>;
101+
fn into_visitor(&self) -> Self::Visitor;
102+
}
103+
104+
pub struct ParDeepVisitor<V>(pub V);
105+
106+
impl<'hir, V> ParItemLikeVisitor<'hir> for ParDeepVisitor<V>
107+
where V: IntoVisitor<'hir>
108+
{
109+
fn visit_item(&self, item: &'hir Item) {
110+
self.0.into_visitor().visit_item(item);
111+
}
112+
113+
fn visit_trait_item(&self, trait_item: &'hir TraitItem) {
114+
self.0.into_visitor().visit_trait_item(trait_item);
115+
}
116+
117+
fn visit_impl_item(&self, impl_item: &'hir ImplItem) {
118+
self.0.into_visitor().visit_impl_item(impl_item);
119+
}
120+
}

src/librustc/hir/mod.rs

+26
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ use ty::AdtKind;
4848
use ty::maps::Providers;
4949

5050
use rustc_data_structures::indexed_vec;
51+
use rustc_data_structures::sync::{ParallelIterator, par_iter, Send, Sync, scope};
5152

5253
use serialize::{self, Encoder, Encodable, Decoder, Decodable};
5354
use std::collections::BTreeMap;
@@ -720,6 +721,31 @@ impl Crate {
720721
}
721722
}
722723

724+
/// A parallel version of visit_all_item_likes
725+
pub fn par_visit_all_item_likes<'hir, V>(&'hir self, visitor: &V)
726+
where V: itemlikevisit::ParItemLikeVisitor<'hir> + Sync + Send
727+
{
728+
scope(|s| {
729+
s.spawn(|_| {
730+
par_iter(&self.items).for_each(|(_, item)| {
731+
visitor.visit_item(item);
732+
});
733+
});
734+
735+
s.spawn(|_| {
736+
par_iter(&self.trait_items).for_each(|(_, trait_item)| {
737+
visitor.visit_trait_item(trait_item);
738+
});
739+
});
740+
741+
s.spawn(|_| {
742+
par_iter(&self.impl_items).for_each(|(_, impl_item)| {
743+
visitor.visit_impl_item(impl_item);
744+
});
745+
});
746+
});
747+
}
748+
723749
pub fn body(&self, id: BodyId) -> &Body {
724750
&self.bodies[&id]
725751
}

src/librustc_data_structures/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ serialize = { path = "../libserialize" }
1616
cfg-if = "0.1.2"
1717
stable_deref_trait = "1.0.0"
1818
parking_lot_core = "0.2.8"
19+
rustc-rayon = "0.1.0"
1920

2021
[dependencies.parking_lot]
2122
version = "0.5"

src/librustc_data_structures/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ extern crate parking_lot;
4444
#[macro_use]
4545
extern crate cfg_if;
4646
extern crate stable_deref_trait;
47+
extern crate rustc_rayon as rayon;
4748

4849
// See librustc_cratesio_shim/Cargo.toml for a comment explaining this.
4950
#[allow(unused_extern_crates)]

src/librustc_data_structures/sync.rs

+43-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
//! This mdoule defines types which are thread safe if cfg!(parallel_queries) is true.
11+
//! This module defines types which are thread safe if cfg!(parallel_queries) is true.
1212
//!
1313
//! `Lrc` is an alias of either Rc or Arc.
1414
//!
@@ -40,6 +40,29 @@ use std;
4040
use std::ops::{Deref, DerefMut};
4141
use owning_ref::{Erased, OwningRef};
4242

43+
pub fn serial_join<A, B, RA, RB>(oper_a: A, oper_b: B) -> (RA, RB)
44+
where A: FnOnce() -> RA,
45+
B: FnOnce() -> RB
46+
{
47+
(oper_a(), oper_b())
48+
}
49+
50+
pub struct SerialScope;
51+
52+
impl SerialScope {
53+
pub fn spawn<F>(&self, f: F)
54+
where F: FnOnce(&SerialScope)
55+
{
56+
f(self)
57+
}
58+
}
59+
60+
pub fn serial_scope<F, R>(f: F) -> R
61+
where F: FnOnce(&SerialScope) -> R
62+
{
63+
f(&SerialScope)
64+
}
65+
4366
cfg_if! {
4467
if #[cfg(not(parallel_queries))] {
4568
pub auto trait Send {}
@@ -55,9 +78,19 @@ cfg_if! {
5578
}
5679
}
5780

81+
pub use self::serial_join as join;
82+
pub use self::serial_scope as scope;
83+
84+
pub use std::iter::Iterator as ParallelIterator;
85+
86+
pub fn par_iter<T: IntoIterator>(t: T) -> T::IntoIter {
87+
t.into_iter()
88+
}
89+
5890
pub type MetadataRef = OwningRef<Box<Erased>, [u8]>;
5991

6092
pub use std::rc::Rc as Lrc;
93+
pub use std::rc::Weak as Weak;
6194
pub use std::cell::Ref as ReadGuard;
6295
pub use std::cell::RefMut as WriteGuard;
6396
pub use std::cell::RefMut as LockGuard;
@@ -160,13 +193,22 @@ cfg_if! {
160193
pub use parking_lot::MutexGuard as LockGuard;
161194

162195
pub use std::sync::Arc as Lrc;
196+
pub use std::sync::Weak as Weak;
163197

164198
pub use self::Lock as MTLock;
165199

166200
use parking_lot::Mutex as InnerLock;
167201
use parking_lot::RwLock as InnerRwLock;
168202

169203
use std::thread;
204+
pub use rayon::{join, scope};
205+
206+
pub use rayon::iter::ParallelIterator;
207+
use rayon::iter::IntoParallelIterator;
208+
209+
pub fn par_iter<T: IntoParallelIterator>(t: T) -> T::Iter {
210+
t.into_par_iter()
211+
}
170212

171213
pub type MetadataRef = OwningRef<Box<Erased + Send + Sync>, [u8]>;
172214

0 commit comments

Comments
 (0)