From d19b1ac414bc55506f597511a312404709e07842 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Fri, 6 Apr 2018 12:56:59 +0200 Subject: [PATCH 01/17] queries --- src/librustc/ty/context.rs | 44 +++- src/librustc/ty/maps/job.rs | 383 ++++++++++++++++++++++++++++++- src/librustc/ty/maps/mod.rs | 4 +- src/librustc/ty/maps/plumbing.rs | 62 ++++- 4 files changed, 484 insertions(+), 9 deletions(-) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 35b2ce50da79d..b69290f503bec 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -69,6 +69,7 @@ use std::ops::Deref; use std::iter; use std::sync::mpsc; use std::sync::Arc; +use std::sync::Mutex; use rustc_target::spec::abi; use syntax::ast::{self, NodeId}; use syntax::attr; @@ -1477,6 +1478,7 @@ impl<'gcx: 'tcx, 'tcx> GlobalCtxt<'gcx> { query: icx.query.clone(), layout_depth: icx.layout_depth, task: icx.task, + waiter_cycle: None, }; ty::tls::enter_context(&new_icx, |new_icx| { f(new_icx.tcx) @@ -1699,15 +1701,21 @@ impl<'a, 'tcx> Lift<'tcx> for &'a Slice { pub mod tls { use super::{GlobalCtxt, TyCtxt}; + #[cfg(not(parallel_queries))] use std::cell::Cell; use std::fmt; use std::mem; use syntax_pos; + use syntax_pos::Span; use ty::maps; + use ty::maps::CycleError; use errors::{Diagnostic, TRACK_DIAGNOSTICS}; use rustc_data_structures::OnDrop; - use rustc_data_structures::sync::{self, Lrc}; + use rayon_core; use dep_graph::OpenTask; + use rustc_data_structures::sync::{self, Lrc, Lock}; + use std::sync::Arc; + use std::sync::Mutex; /// This is the implicit state of rustc. It contains the current /// TyCtxt and query. It is updated when creating a local interner or @@ -1730,11 +1738,25 @@ pub mod tls { /// The current dep graph task. This is used to add dependencies to queries /// when executing them pub task: &'a OpenTask, + + pub waiter_cycle: Option<&'a (Span, Lock>>)>, + } + + #[cfg(parallel_queries)] + fn set_tlv R, R>(value: usize, f: F) -> R { + rayon_core::fiber::tlv::set(value, f) + } + + #[cfg(parallel_queries)] + fn get_tlv() -> usize { + rayon_core::fiber::tlv::get() } // A thread local value which stores a pointer to the current ImplicitCtxt + #[cfg(not(parallel_queries))] thread_local!(static TLV: Cell = Cell::new(0)); + #[cfg(not(parallel_queries))] fn set_tlv R, R>(value: usize, f: F) -> R { let old = get_tlv(); let _reset = OnDrop(move || TLV.with(|tlv| tlv.set(old))); @@ -1742,6 +1764,7 @@ pub mod tls { f() } + #[cfg(not(parallel_queries))] fn get_tlv() -> usize { TLV.with(|tlv| tlv.get()) } @@ -1819,6 +1842,7 @@ pub mod tls { query: None, layout_depth: 0, task: &OpenTask::Ignore, + waiter_cycle: None, }; enter_context(&icx, |_| { f(tcx) @@ -1826,6 +1850,24 @@ pub mod tls { }) } + pub unsafe fn with_global_query(f: F) -> R + where F: for<'a, 'gcx, 'tcx> FnOnce(TyCtxt<'a, 'gcx, 'tcx>) -> R + { + let gcx = &*(gcx_ptr as *const GlobalCtxt<'static>); + let tcx = TyCtxt { + gcx, + interners: &gcx.global_interners, + }; + let icx = ImplicitCtxt { + query: None, + tcx, + layout_depth: 0, + task: &OpenTask::Ignore, + waiter_cycle: None, + }; + enter_context(&icx, |_| f(tcx)) + } + /// Allows access to the current ImplicitCtxt in a closure if one is available pub fn with_context_opt(f: F) -> R where F: for<'a, 'gcx, 'tcx> FnOnce(Option<&ImplicitCtxt<'a, 'gcx, 'tcx>>) -> R diff --git a/src/librustc/ty/maps/job.rs b/src/librustc/ty/maps/job.rs index 3b6af018d6b78..351be29e4f528 100644 --- a/src/librustc/ty/maps/job.rs +++ b/src/librustc/ty/maps/job.rs @@ -8,13 +8,33 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use rustc_data_structures::sync::{Lock, Lrc}; +#![allow(warnings)] + +use std::mem; +use std::sync::atomic::AtomicBool; +use std::sync::atomic::Ordering; +use rustc_data_structures::sync::{Lock, LockGuard, Lrc, Weak}; +use rustc_data_structures::OnDrop; +use rayon_core::registry::{self, Registry, WorkerThread}; +use rayon_core::fiber::{Fiber, Waitable, WaiterLatch}; +use rayon_core::latch::{LatchProbe, Latch}; use syntax_pos::Span; use ty::tls; use ty::maps::Query; use ty::maps::plumbing::CycleError; use ty::context::TyCtxt; use errors::Diagnostic; +use std::process; +use std::fmt; +use std::sync::{Arc, Mutex}; +use std::collections::HashSet; +#[cfg(parallel_queries)] +use { + std::iter, + std::iter::FromIterator, + syntax_pos::DUMMY_SP, + rustc_data_structures::stable_hasher::{StableHasherResult, StableHasher, HashStable}, +}; /// Indicates the state of a query for a given key in a query map pub(super) enum QueryResult<'tcx> { @@ -42,6 +62,8 @@ pub struct QueryJob<'tcx> { /// Diagnostic messages which are emitted while the query executes pub diagnostics: Lock>, + + latch: Lock, } impl<'tcx> QueryJob<'tcx> { @@ -51,6 +73,7 @@ impl<'tcx> QueryJob<'tcx> { diagnostics: Lock::new(Vec::new()), info, parent, + latch: Lock::new(QueryLatch::new()), } } @@ -62,6 +85,45 @@ impl<'tcx> QueryJob<'tcx> { &self, tcx: TyCtxt<'_, 'tcx, 'lcx>, span: Span, + ) -> Result<(), CycleError<'tcx>> { + #[cfg(not(parallel_queries))] + { + self.find_cycle_in_stack(tcx, span) + } + + #[cfg(parallel_queries)] + { + tls::with_related_context(tcx, move |icx| { + let cycle = (span, Lock::new(None)); + + { + let icx = tls::ImplicitCtxt { + waiter_cycle: Some(&cycle), + ..icx.clone() + }; + + tls::enter_context(&icx, |_| { + registry::in_worker(|worker, _| { + unsafe { + worker.wait_enqueue(self); + } + }); + }) + } + + match cycle.1.into_inner() { + None => Ok(()), + Some(cycle) => Err(cycle) + } + }) + } + } + + #[cfg(not(parallel_queries))] + fn find_cycle_in_stack<'lcx>( + &self, + tcx: TyCtxt<'_, 'tcx, 'lcx>, + span: Span, ) -> Result<(), CycleError<'tcx>> { // Get the current executing query (waiter) and find the waitee amongst its parents let mut current_job = tls::with_related_context(tcx, |icx| icx.query.clone()); @@ -93,5 +155,322 @@ impl<'tcx> QueryJob<'tcx> { /// /// This does nothing for single threaded rustc, /// as there are no concurrent jobs which could be waiting on us - pub fn signal_complete(&self) {} + pub fn signal_complete(&self) { + #[cfg(parallel_queries)] + self.latch.lock().set(); + } +} + +#[cfg(parallel_queries)] +impl<'tcx> LatchProbe for QueryJob<'tcx> { + #[inline] + fn probe(&self) -> bool { + self.latch.lock().complete + } +} + +#[cfg(parallel_queries)] +impl<'tcx> Latch for QueryJob<'tcx> { + fn set(&self) { + self.latch.lock().set(); + } +} + +#[cfg(parallel_queries)] +impl<'tcx> Waitable for QueryJob<'tcx> { + fn complete(&self, _worker_thread: &WorkerThread) -> bool { + self.probe() + } + + fn await(&self, worker_thread: &WorkerThread, waiter: Fiber, tlv: usize) { + let mut latch = self.latch.lock(); + if latch.complete { + worker_thread.registry.resume_fiber(worker_thread.index(), waiter); + } else { + latch.waiters.push(QueryWaiter { + worker_index: worker_thread.index(), + fiber: waiter, + tlv, + }); + } + } +} + +#[cfg(parallel_queries)] +struct QueryWaiter { + worker_index: usize, + fiber: Fiber, + tlv: usize, +} + +#[cfg(parallel_queries)] +impl QueryWaiter { + fn icx<'a, 'b, 'gcx, 'tcx>(&'a self) -> *const tls::ImplicitCtxt<'b, 'gcx, 'tcx> { + self.tlv as *const tls::ImplicitCtxt + } +} + +#[cfg(parallel_queries)] +struct QueryLatch { + complete: bool, + waiters: Vec, +} + +#[cfg(parallel_queries)] +impl QueryLatch { + fn new() -> Self { + QueryLatch { + complete: false, + waiters: Vec::new(), + } + } + + fn set(&mut self) { + debug_assert!(!self.complete); + self.complete = true; + if !self.waiters.is_empty() { + let registry = Registry::current(); + for waiter in self.waiters.drain(..) { + registry.resume_fiber(waiter.worker_index, waiter.fiber); + } + registry.signal(); + } + } + + fn resume_waiter(&mut self, waiter: usize, error: CycleError) { + debug_assert!(!self.complete); + // Remove the waiter from the list of waiters + let waiter = self.waiters.remove(waiter); + + // Set the cycle error in its icx so it can pick it up when resumed + { + let icx = unsafe { &*waiter.icx() }; + *icx.waiter_cycle.unwrap().1.lock() = Some(error); + } + + // Resume the waiter + let registry = Registry::current(); + registry.resume_fiber(waiter.worker_index, waiter.fiber); + } +} + +fn print_job<'a, 'tcx, 'lcx>(tcx: TyCtxt<'a, 'tcx, 'lcx>, job: &QueryJob<'tcx>) -> String { + format!("[{}] {:x} {:?}", + 0/*entry.id*/, job as *const _ as usize, job.info.query.describe(tcx)) +} + +type Ref<'tcx> = *const QueryJob<'tcx>; + +type Waiter<'tcx> = (Ref<'tcx>, usize); + +fn visit_waiters<'tcx, F>(query_ref: Ref<'tcx>, mut visit: F) -> Option>> +where + F: FnMut(Span, Ref<'tcx>) -> Option>> +{ + let query = unsafe { &*query_ref }; + if let Some(ref parent) = query.parent { + //eprintln!("visiting parent {:?} of query {:?}", parent, query_ref); + if let Some(cycle) = visit(query.info.span, &**parent as Ref) { + return Some(cycle); + } + } + for (i, waiter) in query.latch.lock().waiters.iter().enumerate() { + let icx = unsafe { &*waiter.icx() }; + if let Some(ref waiter_query) = icx.query { + //eprintln!("visiting waiter {:?} of query {:?}", waiter, query_ref); + if visit(icx.waiter_cycle.unwrap().0, &**waiter_query as Ref).is_some() { + // We found a cycle, return this edge as the waiter + return Some(Some((query_ref, i))); + } + } + } + None +} + +fn cycle_check<'tcx>(query: Ref<'tcx>, + span: Span, + stack: &mut Vec<(Span, Ref<'tcx>)>, + visited: &mut HashSet>) -> Option>> { + if visited.contains(&query) { + //eprintln!("visited query {:?} already for cycle {:#?}", query, stack); + + return if let Some(p) = stack.iter().position(|q| q.1 == query) { + // Remove previous stack entries + stack.splice(0..p, iter::empty()); + // Replace the span for the first query with the cycle cause + stack[0].0 = span; + //eprintln!("[found on stack] visited query {:?} already for cycle {:#?}", query, stack); + Some(None) + } else { + /*eprintln!("[not found on stack] visited query {:?} already for cycle {:#?}", + query, stack);*/ + None + } + } + + //eprintln!("looking for cycle {:#?} in query {:?}", stack, query); + + visited.insert(query); + stack.push((span, query)); + + let r = visit_waiters(query, |span, successor| { + //eprintln!("found successor {:?} in query {:?}", successor, query); + cycle_check(successor, span, stack, visited) + }); + + //eprintln!("result for query {:?} {:?}", query, r); + + if r.is_none() { + stack.pop(); + } + + r +} + +fn connected_to_root<'tcx>(query: Ref<'tcx>, visited: &mut HashSet>) -> bool { + if visited.contains(&query) { + return false; + } + + if unsafe { (*query).parent.is_none() } { + return true; + } + + visited.insert(query); + + let mut connected = false; + + visit_waiters(query, |_, successor| { + if connected_to_root(successor, visited) { + Some(None) + } else { + None + } + }).is_some() +} + +fn query_entry<'tcx>(r: Ref<'tcx>) -> QueryInfo<'tcx> { + unsafe { (*r).info.clone() } +} + +fn remove_cycle<'tcx>(jobs: &mut Vec>, tcx: TyCtxt<'_, 'tcx, '_>) { + let mut visited = HashSet::new(); + let mut stack = Vec::new(); + if let Some(waiter) = cycle_check(jobs.pop().unwrap(), + DUMMY_SP, + &mut stack, + &mut visited) { + // Reverse the stack so earlier entries require later entries + stack.reverse(); + + let mut spans: Vec<_> = stack.iter().map(|e| e.0).collect(); + let queries = stack.iter().map(|e| e.1); + + // Shift the spans so that a query is matched the span for its waitee + let last = spans.pop().unwrap(); + spans.insert(0, last); + + let mut stack: Vec<_> = spans.into_iter().zip(queries).collect(); + + // Remove the queries in our cycle from the list of jobs to look at + for r in &stack { + jobs.remove_item(&r.1); + } + + let (waitee_query, waiter_idx) = waiter.unwrap(); + let waitee_query = unsafe { &*waitee_query }; + +/* eprintln!("found cycle {:#?} with waitee {:?}", stack, waitee_query.info.query); + + for r in &stack { unsafe { + eprintln!("- query: {}", (*r.1).info.query.describe(tcx)); + } } +*/ + // Find the queries in the cycle which are + // connected to queries outside the cycle + let entry_points: Vec> = stack.iter().filter_map(|query| { + // Mark all the other queries in the cycle as already visited + let mut visited = HashSet::from_iter(stack.iter().filter_map(|q| { + if q.1 != query.1 { + Some(q.1) + } else { + None + } + })); + + if connected_to_root(query.1, &mut visited) { + Some(query.1) + } else { + None + } + }).collect(); + + //eprintln!("entry_points {:#?}", entry_points); + + // Deterministically pick an entry point + // FIXME: Sort this instead + let mut hcx = tcx.create_stable_hashing_context(); + let entry_point = *entry_points.iter().min_by_key(|&&q| { + let mut stable_hasher = StableHasher::::new(); + unsafe { (*q).info.query.hash_stable(&mut hcx, &mut stable_hasher); } + stable_hasher.finish() + }).unwrap(); + + /*unsafe { + eprintln!("found entry point {:?} {:?}", + entry_point, (*entry_point).info.query); + }*/ + + // Shift the stack until our entry point is first + while stack[0].1 != entry_point { + let last = stack.pop().unwrap(); + stack.insert(0, last); + } + + let mut error = CycleError { + usage: None, + cycle: stack.iter().map(|&(s, q)| QueryInfo { + span: s, + query: unsafe { (*q).info.query.clone() }, + } ).collect(), + }; + + waitee_query.latch.lock().resume_waiter(waiter_idx, error); + } +} + +pub fn deadlock() { + let on_panic = OnDrop(|| { + eprintln!("deadlock handler panicked, aborting process"); + process::abort(); + }); + + //eprintln!("saw rayon deadlock"); + unsafe { tls::with_global_query(|tcx| { + let mut jobs: Vec<_> = tcx.maps.collect_active_jobs().iter().map(|j| &**j as Ref).collect(); +/* + for job in &jobs { unsafe { + eprintln!("still active query: {}", print_job(tcx, &**job)); + if let Some(ref parent) = (**job).parent { + eprintln!(" - has parent: {}", print_job(tcx, &**parent)); + } + for (i, waiter) in (**job).latch.lock().waiters.iter().enumerate() { + let icx = &*waiter.icx(); + if let Some(ref query) = icx.query { + eprintln!(" - has waiter d{}: {}", i, print_job(tcx, &**query)); + + } else { + eprintln!(" - has no-query waiter d{}", i); + } + } + } } +*/ + while jobs.len() > 0 { + remove_cycle(&mut jobs, tcx); + } + })}; + //eprintln!("aborting due to deadlock"); + //process::abort(); + mem::forget(on_panic); + Registry::current().signal(); } diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index 6556e47720c62..e14fd112efb10 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -63,10 +63,10 @@ use syntax::symbol::Symbol; #[macro_use] mod plumbing; use self::plumbing::*; -pub use self::plumbing::force_from_dep_node; +pub use self::plumbing::{force_from_dep_node, CycleError}; mod job; -pub use self::job::{QueryJob, QueryInfo}; +pub use self::job::{QueryJob, QueryInfo, deadlock}; mod keys; pub use self::keys::Key; diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index 4a9d44b7403b9..cca2a48c63be7 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -16,6 +16,8 @@ use dep_graph::{DepNodeIndex, DepNode, DepKind, DepNodeColor}; use errors::DiagnosticBuilder; use errors::Level; use errors::Diagnostic; + +#[cfg(not(parallel_queries))] use errors::FatalError; use ty::tls; use ty::{TyCtxt}; @@ -35,6 +37,15 @@ use std::collections::hash_map::Entry; use syntax_pos::Span; use syntax::codemap::DUMMY_SP; +#[cfg(parallel_queries)] +use { + rayon_core, + std::panic, +}; + +#[cfg(not(parallel_queries))] +use errors::FatalError; + pub struct QueryMap<'tcx, D: QueryConfig<'tcx> + ?Sized> { pub(super) results: FxHashMap>, pub(super) active: FxHashMap>, @@ -126,7 +137,16 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> { Entry::Occupied(entry) => { match *entry.get() { QueryResult::Started(ref job) => job.clone(), - QueryResult::Poisoned => FatalError.raise(), + QueryResult::Poisoned => { + #[cfg(not(parallel_queries))] + { + FatalError.raise(); + } + #[cfg(parallel_queries)] + { + panic::resume_unwind(Box::new(rayon_core::PoisonedJob)) + } + }, } } Entry::Vacant(entry) => { @@ -197,6 +217,7 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> { query: Some(self.job.clone()), layout_depth: current_icx.layout_depth, task: current_icx.task, + waiter_cycle: None, }; // Use the ImplicitCtxt while we execute the query @@ -223,7 +244,7 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> Drop for JobOwner<'a, 'tcx, Q> { } #[derive(Clone)] -pub(super) struct CycleError<'tcx> { +pub struct CycleError<'tcx> { /// The query and related span which uses the cycle pub(super) usage: Option<(Span, Query<'tcx>)>, pub(super) cycle: Vec>, @@ -632,7 +653,15 @@ macro_rules! define_maps { $($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident: $node:ident($K:ty) -> $V:ty,)*) => { + use std::mem; + use ty::maps::job::QueryResult; use rustc_data_structures::sync::Lock; + use { + rustc_data_structures::stable_hasher::HashStable, + rustc_data_structures::stable_hasher::StableHasherResult, + rustc_data_structures::stable_hasher::StableHasher, + ich::StableHashingContext + }; define_map_struct! { tcx: $tcx, @@ -647,10 +676,23 @@ macro_rules! define_maps { $($name: Lock::new(QueryMap::new())),* } } + + pub fn collect_active_jobs(&self) -> Vec>> { + let mut jobs = Vec::new(); + + $(for v in self.$name.lock().active.values() { + match *v { + QueryResult::Started(ref job) => jobs.push(job.clone()), + _ => (), + } + })* + + return jobs; + } } #[allow(bad_style)] - #[derive(Copy, Clone, Debug, PartialEq, Eq)] + #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub enum Query<$tcx> { $($(#[$attr])* $name($K)),* } @@ -692,6 +734,17 @@ macro_rules! define_maps { } } + impl<'a, $tcx> HashStable> for Query<$tcx> { + fn hash_stable(&self, + hcx: &mut StableHashingContext<'a>, + hasher: &mut StableHasher) { + mem::discriminant(self).hash_stable(hcx, hasher); + match *self { + $(Query::$name(key) => key.hash_stable(hcx, hasher),)* + } + } + } + pub mod queries { use std::marker::PhantomData; @@ -929,7 +982,8 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, profq_query_msg!(::ty::maps::queries::$query::NAME, tcx, $key), ) ); - + // Forcing doesn't add a read edge, but executing the query may add read edges. + // Could this add a `read edge too? match tcx.force_query::<::ty::maps::queries::$query>($key, DUMMY_SP, *dep_node) { Ok(_) => {}, Err(e) => { From ce33c332f9f079a33b4d9edb3ebe5638f4ae9408 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 15 Mar 2018 10:05:33 +0100 Subject: [PATCH 02/17] parallel abs --- src/librustc/ty/mod.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 0bb0208e2a1b4..bee244963b4c2 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -44,7 +44,7 @@ use std::cmp::{self, Ordering}; use std::fmt; use std::hash::{Hash, Hasher}; use std::ops::Deref; -use rustc_data_structures::sync::Lrc; +use rustc_data_structures::sync::{ParallelIterator, par_iter, Send, Sync, Lrc}; use std::slice; use std::vec::IntoIter; use std::mem; @@ -2434,6 +2434,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { .map(move |&body_id| self.hir.body_owner_def_id(body_id)) } + pub fn par_body_owners(self, f: F) { + par_iter(&self.hir.krate().body_ids).for_each(|&body_id| { + f(self.hir.body_owner_def_id(body_id)) + }); + } + pub fn expr_span(self, id: NodeId) -> Span { match self.hir.find(id) { Some(hir_map::NodeExpr(e)) => { From 8f96b377abbb3f61d02cdcd806a90c2d412242c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 15 Mar 2018 10:06:13 +0100 Subject: [PATCH 03/17] timing changes --- src/librustc/Cargo.toml | 4 +- src/librustc/lib.rs | 5 ++ src/librustc/util/common.rs | 114 +++++++++++++++++++++++++++++++++--- 3 files changed, 115 insertions(+), 8 deletions(-) diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index 1d1166ad2c4fd..626e1665680bf 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -59,4 +59,6 @@ chalk-engine = { version = "0.6.0", default-features=false } flate2 = "1.0" tempdir = "0.3" - +[target.'cfg(windows)'.dependencies] +kernel32-sys = "0.2.2" +winapi = "0.2.8" diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 10e8905054d11..d8d113a466e1d 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -40,6 +40,7 @@ html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] +#![feature(asm)] #![feature(box_patterns)] #![feature(box_syntax)] #![feature(const_fn)] @@ -86,6 +87,10 @@ extern crate graphviz; #[cfg(windows)] extern crate libc; extern crate polonius_engine; +#[cfg(windows)] +extern crate kernel32; +#[cfg(windows)] +extern crate winapi; extern crate rustc_target; #[macro_use] extern crate rustc_data_structures; extern crate serialize; diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index 85533caffce2e..cc49b1919fafb 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -176,6 +176,20 @@ pub fn time_ext(do_it: bool, sess: Option<&Session>, what: &str, f: F) -> profq_msg(sess, ProfileQueriesMsg::TimeBegin(what.to_string())) } } + + #[cfg(not(all(windows, parallel_queries, any(target_arch = "x86", target_arch = "x86_64"))))] + let rv = time_impl(sess, what, f); + #[cfg(all(windows, parallel_queries, any(target_arch = "x86", target_arch = "x86_64")))] + let rv = time_threads_impl(sess, what, f); + + TIME_DEPTH.with(|slot| slot.set(old)); + + rv +} + +fn time_impl(sess: Option<&Session>, what: &str, f: F) -> T where + F: FnOnce() -> T, +{ let start = Instant::now(); let rv = f(); let dur = start.elapsed(); @@ -184,12 +198,98 @@ pub fn time_ext(do_it: bool, sess: Option<&Session>, what: &str, f: F) -> profq_msg(sess, ProfileQueriesMsg::TimeEnd) } } + print_time_passes_entry_internal(what, duration_to_secs_str(dur)); + rv +} - print_time_passes_entry_internal(what, dur); +#[cfg(all(windows, parallel_queries, any(target_arch = "x86", target_arch = "x86_64")))] +fn time_threads_impl(sess: Option<&Session>, what: &str, f: F) -> T where + F: FnOnce() -> T, +{ + use rayon_core::registry; + use std::iter; + use winapi; + use kernel32; - TIME_DEPTH.with(|slot| slot.set(old)); + #[allow(unused_mut)] + fn read_counter() -> u64 { + let mut low: u32; + let mut high: u32; - rv + unsafe { + asm!("xor %rax, %rax; cpuid; rdtsc" + : "={eax}" (low), "={edx}" (high) :: "memory", "rbx", "rcx"); + } + + ((high as u64) << 32) | (low as u64) + } + + let registry = registry::get_current_registry(); + if let Some(registry) = registry { + let freq = unsafe { + let mut freq = 0; + assert!(kernel32::QueryPerformanceFrequency(&mut freq) == winapi::TRUE); + freq as u64 * 1000 + }; + + let threads: Vec<_> = { + let threads = registry.handles.lock(); + let current = unsafe { + iter::once(kernel32::GetCurrentThread()) + }; + current.chain(threads.iter().map(|t| t.0)).collect() + }; + let mut begin: Vec = iter::repeat(0).take(threads.len()).collect(); + let mut end: Vec = iter::repeat(0).take(threads.len()).collect(); + for (i, &handle) in threads.iter().enumerate() { + unsafe { + assert!(kernel32::QueryThreadCycleTime(handle, &mut begin[i]) == winapi::TRUE); + } + } + + let time_start = read_counter(); + let result = f(); + let time_end = read_counter(); + for (i, &handle) in threads.iter().enumerate() { + unsafe { + assert!(kernel32::QueryThreadCycleTime(handle, &mut end[i]) == winapi::TRUE); + } + } + if let Some(sess) = sess { + if cfg!(debug_assertions) { + profq_msg(sess, ProfileQueriesMsg::TimeEnd) + } + } + let time = time_end - time_start; + let time_secs = time as f64 / freq as f64; + + let thread_times: Vec = end.iter().zip(begin.iter()).map(|(e, b)| *e - *b).collect(); + + let total_thread_time: u64 = thread_times.iter().cloned().sum(); + let core_usage = total_thread_time as f64 / time as f64; + + let mut data = format!("{:.6} - cores {:.2}x - cpu {:.2} - threads (", + time_secs, + core_usage, + core_usage / (thread_times.len() - 1) as f64); + + for (i, thread_time) in thread_times.into_iter().enumerate() { + data.push_str(&format!("{:.2}", thread_time as f64 / time as f64)); + if i == 0 { + data.push_str(" - "); + } + else if i < begin.len() - 1 { + data.push_str(" "); + } + } + + data.push_str(")"); + + print_time_passes_entry_internal(what, data); + result + } else { + time_impl(sess, what, f) + } } pub fn print_time_passes_entry(do_it: bool, what: &str, dur: Duration) { @@ -203,12 +303,12 @@ pub fn print_time_passes_entry(do_it: bool, what: &str, dur: Duration) { r }); - print_time_passes_entry_internal(what, dur); + print_time_passes_entry_internal(what, duration_to_secs_str(dur)); TIME_DEPTH.with(|slot| slot.set(old)); } -fn print_time_passes_entry_internal(what: &str, dur: Duration) { +fn print_time_passes_entry_internal(what: &str, data: String) { let indentation = TIME_DEPTH.with(|slot| slot.get()); let mem_string = match get_resident() { @@ -220,7 +320,7 @@ fn print_time_passes_entry_internal(what: &str, dur: Duration) { }; println!("{}time: {}{}\t{}", repeat(" ").take(indentation).collect::(), - duration_to_secs_str(dur), + data, mem_string, what); } @@ -232,7 +332,7 @@ pub fn duration_to_secs_str(dur: Duration) -> String { let secs = dur.as_secs() as f64 + dur.subsec_nanos() as f64 / NANOS_PER_SEC; - format!("{:.3}", secs) + format!("{:.6}", secs) } pub fn to_readable_str(mut val: usize) -> String { From 8bd5144fd8881fbcf8d4a452427604c3398170eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 15 Mar 2018 10:08:52 +0100 Subject: [PATCH 04/17] Parallel code --- src/librustc_borrowck/borrowck/mod.rs | 4 ++-- src/librustc_borrowck/lib.rs | 2 ++ src/librustc_driver/driver.rs | 19 +++++++++---------- src/librustc_typeck/check/mod.rs | 16 ++++++++-------- .../coherence/inherent_impls_overlap.rs | 12 ++++++------ src/librustc_typeck/coherence/mod.rs | 5 +++-- src/librustc_typeck/coherence/orphan.rs | 14 +++++++------- src/librustc_typeck/coherence/unsafety.rs | 16 ++++++++-------- src/librustc_typeck/collect.rs | 14 ++++++++++++-- src/librustc_typeck/impl_wf_check.rs | 12 ++++++------ src/librustc_typeck/lib.rs | 2 ++ src/librustc_typeck/variance/test.rs | 12 ++++++------ 12 files changed, 71 insertions(+), 57 deletions(-) diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index e063880028fc9..2b817d4da30d9 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -67,9 +67,9 @@ pub struct LoanDataFlowOperator; pub type LoanDataFlow<'a, 'tcx> = DataFlowContext<'a, 'tcx, LoanDataFlowOperator>; pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { - for body_owner_def_id in tcx.body_owners() { + tcx.par_body_owners(|body_owner_def_id| { tcx.borrowck(body_owner_def_id); - } + }); } pub fn provide(providers: &mut Providers) { diff --git a/src/librustc_borrowck/lib.rs b/src/librustc_borrowck/lib.rs index 52a357e1a1d31..a5a20af0e4e4a 100644 --- a/src/librustc_borrowck/lib.rs +++ b/src/librustc_borrowck/lib.rs @@ -17,6 +17,8 @@ #![feature(from_ref)] #![feature(quote)] +#![recursion_limit="256"] + #[macro_use] extern crate log; extern crate syntax; extern crate syntax_pos; diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index ed28b05c12551..256ae9120f3fe 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -1195,21 +1195,20 @@ where time(sess, "borrow checking", || borrowck::check_crate(tcx)); - time(sess, "MIR borrow checking", || { - for def_id in tcx.body_owners() { - tcx.mir_borrowck(def_id); - } - }); + time(sess, + "MIR borrow checking", + || tcx.par_body_owners(|def_id| { tcx.mir_borrowck(def_id); })); time(sess, "dumping chalk-like clauses", || { rustc_traits::lowering::dump_program_clauses(tcx); }); - time(sess, "MIR effect checking", || { - for def_id in tcx.body_owners() { - mir::transform::check_unsafety::check_unsafety(tcx, def_id) - } - }); + time(sess, + "MIR effect checking", + || tcx.par_body_owners(|def_id| { + mir::transform::check_unsafety::check_unsafety(tcx.global_tcx(), def_id) + })); + // Avoid overwhelming user with errors if type checking failed. // I'm not sure how helpful this is, to be honest, but it avoids // a diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index c2c71d90f0674..0787e7e1d5f78 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -128,7 +128,7 @@ use syntax::util::lev_distance::find_best_match_for_name; use syntax_pos::{self, BytePos, Span, MultiSpan}; use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; -use rustc::hir::itemlikevisit::ItemLikeVisitor; +use rustc::hir::itemlikevisit::ParItemLikeVisitor; use rustc::hir::map::Node; use rustc::hir::{self, PatKind, Item_}; use rustc::middle::lang_items; @@ -672,12 +672,12 @@ impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> { struct CheckItemTypesVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx> } -impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> { - fn visit_item(&mut self, i: &'tcx hir::Item) { +impl<'a, 'tcx> ParItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> { + fn visit_item(&self, i: &'tcx hir::Item) { check_item_type(self.tcx, i); } - fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem) { } - fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) { } + fn visit_trait_item(&self, _: &'tcx hir::TraitItem) { } + fn visit_impl_item(&self, _: &'tcx hir::ImplItem) { } } pub fn check_wf_new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), ErrorReported> { @@ -689,7 +689,7 @@ pub fn check_wf_new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), ErrorRe pub fn check_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), ErrorReported> { tcx.sess.track_errors(|| { - tcx.hir.krate().visit_all_item_likes(&mut CheckItemTypesVisitor { tcx }); + tcx.hir.krate().par_visit_all_item_likes(&CheckItemTypesVisitor { tcx }); }) } @@ -702,9 +702,9 @@ fn typeck_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum { debug_assert!(crate_num == LOCAL_CRATE); Ok(tcx.sess.track_errors(|| { - for body_owner_def_id in tcx.body_owners() { + tcx.par_body_owners(|body_owner_def_id| { ty::maps::queries::typeck_tables_of::ensure(tcx, body_owner_def_id); - } + }); })?) } diff --git a/src/librustc_typeck/coherence/inherent_impls_overlap.rs b/src/librustc_typeck/coherence/inherent_impls_overlap.rs index 88a2dc817ae63..c9644bb1fdaaf 100644 --- a/src/librustc_typeck/coherence/inherent_impls_overlap.rs +++ b/src/librustc_typeck/coherence/inherent_impls_overlap.rs @@ -11,7 +11,7 @@ use namespace::Namespace; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc::hir; -use rustc::hir::itemlikevisit::ItemLikeVisitor; +use rustc::hir::itemlikevisit::ParItemLikeVisitor; use rustc::traits::{self, IntercrateMode}; use rustc::ty::TyCtxt; @@ -21,7 +21,7 @@ pub fn crate_inherent_impls_overlap_check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) { assert_eq!(crate_num, LOCAL_CRATE); let krate = tcx.hir.krate(); - krate.visit_all_item_likes(&mut InherentOverlapChecker { tcx }); + krate.par_visit_all_item_likes(&InherentOverlapChecker { tcx }); } struct InherentOverlapChecker<'a, 'tcx: 'a> { @@ -119,8 +119,8 @@ impl<'a, 'tcx> InherentOverlapChecker<'a, 'tcx> { } } -impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentOverlapChecker<'a, 'tcx> { - fn visit_item(&mut self, item: &'v hir::Item) { +impl<'a, 'tcx, 'v> ParItemLikeVisitor<'v> for InherentOverlapChecker<'a, 'tcx> { + fn visit_item(&self, item: &'v hir::Item) { match item.node { hir::ItemEnum(..) | hir::ItemStruct(..) | @@ -133,9 +133,9 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentOverlapChecker<'a, 'tcx> { } } - fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) { + fn visit_trait_item(&self, _trait_item: &hir::TraitItem) { } - fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) { + fn visit_impl_item(&self, _impl_item: &hir::ImplItem) { } } diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 07b7c600b9f30..1a52e36b103e8 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -19,6 +19,7 @@ use hir::def_id::{DefId, LOCAL_CRATE}; use rustc::traits; use rustc::ty::{self, TyCtxt, TypeFoldable}; use rustc::ty::maps::Providers; +use rustc_data_structures::sync::{ParallelIterator, par_iter}; use syntax::ast; @@ -126,9 +127,9 @@ fn coherent_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) { } pub fn check_coherence<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { - for &trait_def_id in tcx.hir.krate().trait_impls.keys() { + par_iter(&tcx.hir.krate().trait_impls).for_each(|(&trait_def_id, _)| { ty::maps::queries::coherent_trait::ensure(tcx, trait_def_id); - } + }); unsafety::check(tcx); orphan::check(tcx); diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index 6d6594e55437d..1598437ba02d1 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -13,25 +13,25 @@ use rustc::traits; use rustc::ty::{self, TyCtxt}; -use rustc::hir::itemlikevisit::ItemLikeVisitor; +use rustc::hir::itemlikevisit::ParItemLikeVisitor; use rustc::hir; pub fn check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { - let mut orphan = OrphanChecker { tcx: tcx }; - tcx.hir.krate().visit_all_item_likes(&mut orphan); + let orphan = OrphanChecker { tcx: tcx }; + tcx.hir.krate().par_visit_all_item_likes(&orphan); } struct OrphanChecker<'cx, 'tcx: 'cx> { tcx: TyCtxt<'cx, 'tcx, 'tcx>, } -impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> { +impl<'cx, 'tcx, 'v> ParItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> { /// Checks exactly one impl for orphan rules and other such /// restrictions. In this fn, it can happen that multiple errors /// apply to a specific impl, so just return after reporting one /// to prevent inundating the user with a bunch of similar error /// reports. - fn visit_item(&mut self, item: &hir::Item) { + fn visit_item(&self, item: &hir::Item) { let def_id = self.tcx.hir.local_def_id(item.id); match item.node { hir::ItemImpl(.., Some(_), _, _) => { @@ -161,9 +161,9 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> { } } - fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) { + fn visit_trait_item(&self, _trait_item: &hir::TraitItem) { } - fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) { + fn visit_impl_item(&self, _impl_item: &hir::ImplItem) { } } diff --git a/src/librustc_typeck/coherence/unsafety.rs b/src/librustc_typeck/coherence/unsafety.rs index 4aa876e85b69a..60d88b5c7ee07 100644 --- a/src/librustc_typeck/coherence/unsafety.rs +++ b/src/librustc_typeck/coherence/unsafety.rs @@ -12,12 +12,12 @@ //! crate or pertains to a type defined in this crate. use rustc::ty::TyCtxt; -use rustc::hir::itemlikevisit::ItemLikeVisitor; +use rustc::hir::itemlikevisit::ParItemLikeVisitor; use rustc::hir::{self, Unsafety}; pub fn check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { - let mut unsafety = UnsafetyChecker { tcx: tcx }; - tcx.hir.krate().visit_all_item_likes(&mut unsafety); + let unsafety = UnsafetyChecker { tcx: tcx }; + tcx.hir.krate().par_visit_all_item_likes(&unsafety); } struct UnsafetyChecker<'cx, 'tcx: 'cx> { @@ -25,7 +25,7 @@ struct UnsafetyChecker<'cx, 'tcx: 'cx> { } impl<'cx, 'tcx, 'v> UnsafetyChecker<'cx, 'tcx> { - fn check_unsafety_coherence(&mut self, + fn check_unsafety_coherence(&self, item: &'v hir::Item, impl_generics: Option<&hir::Generics>, unsafety: hir::Unsafety, @@ -78,8 +78,8 @@ impl<'cx, 'tcx, 'v> UnsafetyChecker<'cx, 'tcx> { } } -impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for UnsafetyChecker<'cx, 'tcx> { - fn visit_item(&mut self, item: &'v hir::Item) { +impl<'cx, 'tcx, 'v> ParItemLikeVisitor<'v> for UnsafetyChecker<'cx, 'tcx> { + fn visit_item(&self, item: &'v hir::Item) { match item.node { hir::ItemImpl(unsafety, polarity, _, ref generics, ..) => { self.check_unsafety_coherence(item, Some(generics), unsafety, polarity); @@ -88,9 +88,9 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for UnsafetyChecker<'cx, 'tcx> { } } - fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) { + fn visit_trait_item(&self, _trait_item: &hir::TraitItem) { } - fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) { + fn visit_impl_item(&self, _impl_item: &hir::ImplItem) { } } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index a982724f957e9..0c98f6c0fa100 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -50,6 +50,7 @@ use syntax_pos::{Span, DUMMY_SP}; use rustc::hir::{self, map as hir_map, CodegenFnAttrs, CodegenFnAttrFlags, Unsafety}; use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; +use rustc::hir::itemlikevisit::{IntoVisitor, ParDeepVisitor}; use rustc::hir::def::{Def, CtorKind}; use rustc::hir::def_id::{DefId, LOCAL_CRATE}; @@ -57,8 +58,8 @@ use rustc::hir::def_id::{DefId, LOCAL_CRATE}; // Main entry point pub fn collect_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { - let mut visitor = CollectItemTypesVisitor { tcx: tcx }; - tcx.hir.krate().visit_all_item_likes(&mut visitor.as_deep_visitor()); + let visitor = CollectItemTypesVisitor { tcx: tcx }; + tcx.hir.krate().par_visit_all_item_likes(&ParDeepVisitor(visitor)); } pub fn provide(providers: &mut Providers) { @@ -98,10 +99,19 @@ pub struct ItemCtxt<'a,'tcx:'a> { /////////////////////////////////////////////////////////////////////////// +#[derive(Clone)] struct CollectItemTypesVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx> } +impl<'a, 'tcx: 'a> IntoVisitor<'tcx> for CollectItemTypesVisitor<'a, 'tcx> { + type Visitor = Self; + + fn into_visitor(&self) -> Self { + self.clone() + } +} + impl<'a, 'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'a, 'tcx> { fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { NestedVisitorMap::OnlyBodies(&self.tcx.hir) diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs index 7b7cb25497978..51cbd7ea92b69 100644 --- a/src/librustc_typeck/impl_wf_check.rs +++ b/src/librustc_typeck/impl_wf_check.rs @@ -20,7 +20,7 @@ use constrained_type_params as ctp; use rustc::hir; -use rustc::hir::itemlikevisit::ItemLikeVisitor; +use rustc::hir::itemlikevisit::ParItemLikeVisitor; use rustc::hir::def_id::DefId; use rustc::ty::{self, TyCtxt}; use rustc::util::nodemap::{FxHashMap, FxHashSet}; @@ -62,15 +62,15 @@ pub fn impl_wf_check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { // We will tag this as part of the WF check -- logically, it is, // but it's one that we must perform earlier than the rest of // WfCheck. - tcx.hir.krate().visit_all_item_likes(&mut ImplWfCheck { tcx: tcx }); + tcx.hir.krate().par_visit_all_item_likes(&ImplWfCheck { tcx: tcx }); } struct ImplWfCheck<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, } -impl<'a, 'tcx> ItemLikeVisitor<'tcx> for ImplWfCheck<'a, 'tcx> { - fn visit_item(&mut self, item: &'tcx hir::Item) { +impl<'a, 'tcx> ParItemLikeVisitor<'tcx> for ImplWfCheck<'a, 'tcx> { + fn visit_item(&self, item: &'tcx hir::Item) { match item.node { hir::ItemImpl(.., ref impl_item_refs) => { let impl_def_id = self.tcx.hir.local_def_id(item.id); @@ -83,9 +83,9 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for ImplWfCheck<'a, 'tcx> { } } - fn visit_trait_item(&mut self, _trait_item: &'tcx hir::TraitItem) { } + fn visit_trait_item(&self, _trait_item: &'tcx hir::TraitItem) { } - fn visit_impl_item(&mut self, _impl_item: &'tcx hir::ImplItem) { } + fn visit_impl_item(&self, _impl_item: &'tcx hir::ImplItem) { } } fn enforce_impl_params_are_constrained<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 5b7d92944edf2..8af3a338dc194 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -83,6 +83,8 @@ This API is completely unstable and subject to change. #![feature(slice_sort_by_cached_key)] #![feature(never_type)] +#![recursion_limit="256"] + #[macro_use] extern crate log; #[macro_use] extern crate syntax; extern crate syntax_pos; diff --git a/src/librustc_typeck/variance/test.rs b/src/librustc_typeck/variance/test.rs index 1acadb7e77236..007c828576080 100644 --- a/src/librustc_typeck/variance/test.rs +++ b/src/librustc_typeck/variance/test.rs @@ -9,19 +9,19 @@ // except according to those terms. use rustc::hir; -use rustc::hir::itemlikevisit::ItemLikeVisitor; +use rustc::hir::itemlikevisit::ParItemLikeVisitor; use rustc::ty::TyCtxt; pub fn test_variance<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { - tcx.hir.krate().visit_all_item_likes(&mut VarianceTest { tcx }); + tcx.hir.krate().par_visit_all_item_likes(&VarianceTest { tcx }); } struct VarianceTest<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx> } -impl<'a, 'tcx> ItemLikeVisitor<'tcx> for VarianceTest<'a, 'tcx> { - fn visit_item(&mut self, item: &'tcx hir::Item) { +impl<'a, 'tcx> ParItemLikeVisitor<'tcx> for VarianceTest<'a, 'tcx> { + fn visit_item(&self, item: &'tcx hir::Item) { let item_def_id = self.tcx.hir.local_def_id(item.id); // For unit testing: check for a special "rustc_variance" @@ -36,6 +36,6 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for VarianceTest<'a, 'tcx> { } } - fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem) { } - fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) { } + fn visit_trait_item(&self, _: &'tcx hir::TraitItem) { } + fn visit_impl_item(&self, _: &'tcx hir::ImplItem) { } } From 9d9a40a60b121bcac6c7e490d7028fa2eb212068 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 15 Mar 2018 10:14:32 +0100 Subject: [PATCH 05/17] misc --- src/librustc/Cargo.toml | 3 +++ src/librustc/lib.rs | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index 626e1665680bf..a7a35c9a62cca 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -18,6 +18,9 @@ lazy_static = "1.0.0" log = { version = "0.4", features = ["release_max_level_info", "std"] } polonius-engine = "0.5.0" proc_macro = { path = "../libproc_macro" } +rustc-rayon = { git = "https://github.com/Zoxc/rayon.git", branch = "fiber" } +rustc-rayon-core = { git = "https://github.com/Zoxc/rayon.git", branch = "fiber", features=["tlv"] } +scoped-tls = { version = "0.1.1", features = ["nightly"] } rustc_apfloat = { path = "../librustc_apfloat" } rustc_target = { path = "../librustc_target" } rustc_data_structures = { path = "../librustc_data_structures" } diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index d8d113a466e1d..728014e20901b 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -41,6 +41,7 @@ html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(asm)] +#![feature(attr_literals)] #![feature(box_patterns)] #![feature(box_syntax)] #![feature(const_fn)] @@ -49,6 +50,7 @@ #![feature(entry_or_default)] #![feature(from_ref)] #![feature(fs_read_write)] +#![feature(iterator_step_by)] #![feature(iterator_find_map)] #![cfg_attr(windows, feature(libc))] #![cfg_attr(stage0, feature(macro_lifetime_matcher))] @@ -62,6 +64,7 @@ #![feature(optin_builtin_traits)] #![feature(refcell_replace_swap)] #![feature(rustc_diagnostic_macros)] +#![feature(set_stdio)] #![feature(slice_patterns)] #![feature(slice_sort_by_cached_key)] #![feature(specialization)] @@ -74,6 +77,7 @@ #![feature(in_band_lifetimes)] #![feature(macro_at_most_once_rep)] #![feature(inclusive_range_methods)] +#![feature(vec_remove_item)] #![recursion_limit="512"] @@ -95,9 +99,12 @@ extern crate rustc_target; #[macro_use] extern crate rustc_data_structures; extern crate serialize; extern crate rustc_errors as errors; +extern crate rustc_rayon as rayon; +extern crate rustc_rayon_core as rayon_core; #[macro_use] extern crate log; #[macro_use] extern crate syntax; extern crate syntax_pos; +#[macro_use] extern crate scoped_tls; extern crate jobserver; extern crate proc_macro; extern crate chalk_engine; From 192a896d95f73ec7ab1f1c3218afe56336e841b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 15 Mar 2018 10:15:19 +0100 Subject: [PATCH 06/17] rayon abs --- src/librustc_data_structures/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml index 17ee771e52940..456b999f621b0 100644 --- a/src/librustc_data_structures/Cargo.toml +++ b/src/librustc_data_structures/Cargo.toml @@ -16,8 +16,8 @@ serialize = { path = "../libserialize" } cfg-if = "0.1.2" stable_deref_trait = "1.0.0" parking_lot_core = "0.2.8" -rustc-rayon = "0.1.0" -rustc-rayon-core = "0.1.0" +rustc-rayon = { git = "https://github.com/Zoxc/rayon.git", branch = "fiber" } +rustc-rayon-core = { git = "https://github.com/Zoxc/rayon.git", branch = "fiber" } rustc-hash = "1.0.1" [dependencies.parking_lot] From bc8512a72d46c13338b01414388e333fd9a80e9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 15 Mar 2018 10:16:14 +0100 Subject: [PATCH 07/17] thread pool --- src/librustc/ty/context.rs | 11 ++++++++++- src/librustc_driver/driver.rs | 19 +++++++++++++------ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index b69290f503bec..1c5f8b775aa42 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1833,6 +1833,13 @@ pub mod tls { where F: for<'a> FnOnce(TyCtxt<'a, 'gcx, 'gcx>) -> R { with_thread_locals(|| { + GCX_PTR.with(|lock| { + *lock.lock() = gcx as *const _ as usize; + }); + let _on_drop = OnDrop(move || { + GCX_PTR.with(|lock| *lock.lock() = 0); + }); + let tcx = TyCtxt { gcx, interners: &gcx.global_interners, @@ -1850,10 +1857,12 @@ pub mod tls { }) } + scoped_thread_local!(pub static GCX_PTR: Lock); + pub unsafe fn with_global_query(f: F) -> R where F: for<'a, 'gcx, 'tcx> FnOnce(TyCtxt<'a, 'gcx, 'tcx>) -> R { - let gcx = &*(gcx_ptr as *const GlobalCtxt<'static>); + let gcx = &*(GCX_PTR.with(|lock| *lock.lock()) as *const GlobalCtxt<'static>); let tcx = TyCtxt { gcx, interners: &gcx.global_interners, diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 256ae9120f3fe..4c9d076ea4bfc 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -49,7 +49,7 @@ use std::fs; use std::io::{self, Write}; use std::iter; use std::path::{Path, PathBuf}; -use rustc_data_structures::sync::{self, Lrc}; +use rustc_data_structures::sync::{self, Lrc, Lock}; use std::sync::mpsc; use syntax::{self, ast, attr, diagnostics, visit}; use syntax::ext::base::ExtCtxt; @@ -69,7 +69,9 @@ pub fn spawn_thread_pool R + sync::Send, R: sync:: opts: config::Options, f: F ) -> R { - f(opts) + ty::tls::GCX_PTR.set(&Lock::new(0), || { + f(opts) + }) } #[cfg(parallel_queries)] @@ -79,10 +81,13 @@ pub fn spawn_thread_pool R + sync::Send, R: sync:: ) -> R { use syntax; use syntax_pos; - use rayon::{ThreadPoolBuilder, ThreadPool}; + use rayon::{Configuration, ThreadPool}; + + let gcx_ptr = &Lock::new(0); - let config = ThreadPoolBuilder::new().num_threads(Session::query_threads_from_opts(&opts)) - .stack_size(16 * 1024 * 1024); + let config = Configuration::new().num_threads(Session::query_threads_from_opts(&opts)) + .deadlock_handler(ty::maps::deadlock) + .stack_size(16 * 1024 * 1024); let with_pool = move |pool: &ThreadPool| { pool.install(move || f(opts)) @@ -98,7 +103,9 @@ pub fn spawn_thread_pool R + sync::Send, R: sync:: syntax::GLOBALS.set(syntax_globals, || { syntax_pos::GLOBALS.set(syntax_pos_globals, || { ty::tls::with_thread_locals(|| { - worker() + ty::tls::GCX_PTR.set(gcx_ptr, || { + worker() + }) }) }) }) From 1e7e80003679b3ca10e4448f79bb53548db941e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 15 Mar 2018 10:17:32 +0100 Subject: [PATCH 08/17] misc --- src/librustc_driver/Cargo.toml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index 24bf07d793f3d..8a450b634192f 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -13,7 +13,10 @@ arena = { path = "../libarena" } graphviz = { path = "../libgraphviz" } log = "0.4" env_logger = { version = "0.5", default-features = false } -rustc-rayon = "0.1.0" + +rustc-rayon-core = { git = "https://github.com/Zoxc/rayon.git", branch = "fiber" } +rustc-rayon = { git = "https://github.com/Zoxc/rayon.git", branch = "fiber" } + scoped-tls = { version = "0.1.1", features = ["nightly"] } rustc = { path = "../librustc" } rustc_allocator = { path = "../librustc_allocator" } From 1e630eb0d3f9fedf2a10d061c3e20292b8b7ec71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 7 Dec 2017 17:23:15 +0100 Subject: [PATCH 09/17] Parallelize passes --- src/librustc/hir/itemlikevisit.rs | 11 +++++++++++ src/librustc/hir/mod.rs | 7 +++++++ src/librustc/middle/intrinsicck.rs | 6 ++---- src/librustc/middle/stability.rs | 7 ++++--- src/librustc/traits/mod.rs | 3 +-- src/librustc/traits/select.rs | 5 ++--- src/librustc/traits/structural_impls.rs | 4 ++-- src/librustc/ty/structural_impls.rs | 11 +++++++++++ src/librustc_codegen_llvm/lib.rs | 2 ++ src/librustc_codegen_utils/symbol_names_test.rs | 2 ++ src/librustc_mir/hair/pattern/check_match.rs | 3 ++- src/librustc_passes/lib.rs | 2 ++ src/librustc_passes/rvalue_promotion.rs | 5 +---- src/librustc_typeck/check/mod.rs | 4 ++-- src/librustc_typeck/check/wfcheck.rs | 1 + src/librustc_typeck/collect.rs | 12 +----------- src/librustc_typeck/outlives/test.rs | 14 ++++++-------- 17 files changed, 59 insertions(+), 40 deletions(-) diff --git a/src/librustc/hir/itemlikevisit.rs b/src/librustc/hir/itemlikevisit.rs index a62000e10c79f..bbf3fb3eb68c3 100644 --- a/src/librustc/hir/itemlikevisit.rs +++ b/src/librustc/hir/itemlikevisit.rs @@ -101,6 +101,17 @@ pub trait IntoVisitor<'hir> { fn into_visitor(&self) -> Self::Visitor; } +#[derive(Clone)] +pub struct ClonableVisitor(pub V); + +impl<'hir, V: Visitor<'hir> + Clone> IntoVisitor<'hir> for ClonableVisitor { + type Visitor = V; + + fn into_visitor(&self) -> V { + self.clone().0 + } +} + pub struct ParDeepVisitor(pub V); impl<'hir, V> ParItemLikeVisitor<'hir> for ParDeepVisitor diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index b7c66398f8500..a6142c95674a2 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -758,6 +758,13 @@ impl Crate { }); } + pub fn par_deep_visit_items<'hir, V>(&'hir self, visitor: V) + where V: intravisit::Visitor<'hir> + Clone + Sync + Send + { + let visitor = itemlikevisit::ClonableVisitor(visitor); + self.par_visit_all_item_likes(&itemlikevisit::ParDeepVisitor(visitor)); + } + pub fn body(&self, id: BodyId) -> &Body { &self.bodies[&id] } diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs index 27f7dbf508db0..cb6036760be55 100644 --- a/src/librustc/middle/intrinsicck.rs +++ b/src/librustc/middle/intrinsicck.rs @@ -19,12 +19,10 @@ use hir::intravisit::{self, Visitor, NestedVisitorMap}; use hir; pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { - let mut visitor = ItemVisitor { - tcx, - }; - tcx.hir.krate().visit_all_item_likes(&mut visitor.as_deep_visitor()); + tcx.hir.krate().par_deep_visit_items(ItemVisitor { tcx }); } +#[derive(Clone)] struct ItemVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx> } diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index d6a7d5e8472ac..875023b65588a 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -324,6 +324,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> { } } +#[derive(Clone)] struct MissingStabilityAnnotations<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, access_levels: &'a AccessLevels, @@ -466,8 +467,7 @@ impl<'a, 'tcx> Index<'tcx> { /// Cross-references the feature names of unstable APIs with enabled /// features and possibly prints errors. pub fn check_unstable_api_usage<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { - let mut checker = Checker { tcx: tcx }; - tcx.hir.krate().visit_all_item_likes(&mut checker.as_deep_visitor()); + tcx.hir.krate().par_deep_visit_items(Checker { tcx: tcx }); } /// Check whether an item marked with `deprecated(since="X")` is currently @@ -494,6 +494,7 @@ pub fn deprecation_in_effect(since: &str) -> bool { } } +#[derive(Clone)] struct Checker<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, } @@ -807,7 +808,7 @@ pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { }; missing.check_missing_stability(ast::CRATE_NODE_ID, krate.span); intravisit::walk_crate(&mut missing, krate); - krate.visit_all_item_likes(&mut missing.as_deep_visitor()); + krate.par_deep_visit_items(missing); } let ref declared_lib_features = tcx.features().declared_lib_features; diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 3bd4e11b0e8b9..1e46b5d6d9355 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -32,7 +32,6 @@ use infer::{InferCtxt}; use rustc_data_structures::sync::Lrc; use std::fmt::Debug; -use std::rc::Rc; use syntax::ast; use syntax_pos::{Span, DUMMY_SP}; @@ -261,7 +260,7 @@ pub struct DerivedObligationCause<'tcx> { parent_trait_ref: ty::PolyTraitRef<'tcx>, /// The parent trait had this cause - parent_code: Rc> + parent_code: Lrc> } pub type Obligations<'tcx, O> = Vec>; diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 7a52a5cbf5acc..5eeac8f76a78c 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -44,13 +44,12 @@ use ty::relate::TypeRelation; use middle::lang_items; use mir::interpret::{GlobalId}; -use rustc_data_structures::sync::Lock; +use rustc_data_structures::sync::{Lrc, Lock}; use rustc_data_structures::bitvec::BitVector; use std::iter; use std::cmp; use std::fmt; use std::mem; -use std::rc::Rc; use rustc_target::spec::abi::Abi; use hir; use util::nodemap::{FxHashMap, FxHashSet}; @@ -3406,7 +3405,7 @@ impl<'tcx> TraitObligation<'tcx> { if obligation.recursion_depth >= 0 { let derived_cause = DerivedObligationCause { parent_trait_ref: obligation.predicate.to_poly_trait_ref(), - parent_code: Rc::new(obligation.cause.code.clone()) + parent_code: Lrc::new(obligation.cause.code.clone()) }; let derived_code = variant(derived_cause); ObligationCause::new(obligation.cause.span, obligation.cause.body_id, derived_code) diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index d1304a0a3f887..5e782daa19efb 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -16,7 +16,7 @@ use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use ty::{self, Lift, TyCtxt}; use std::fmt; -use std::rc::Rc; +use rustc_data_structures::sync::Lrc; // structural impls for the structs in traits @@ -246,7 +246,7 @@ impl<'a, 'tcx> Lift<'tcx> for traits::DerivedObligationCause<'a> { tcx.lift(&*self.parent_code) .map(|code| traits::DerivedObligationCause { parent_trait_ref: trait_ref, - parent_code: Rc::new(code), + parent_code: Lrc::new(code), }) }) } diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index e77ede72143b1..a2a6ca40de36d 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -22,6 +22,7 @@ use rustc_data_structures::sync::Lrc; use mir::interpret; use std::rc::Rc; +use std::sync::Arc; /////////////////////////////////////////////////////////////////////////// // Atomic structs @@ -699,6 +700,16 @@ EnumTypeFoldableImpl! { } where T: TypeFoldable<'tcx> } +impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Arc { + fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { + Arc::new((**self).fold_with(folder)) + } + + fn super_visit_with>(&self, visitor: &mut V) -> bool { + (**self).visit_with(visitor) + } +} + impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { Rc::new((**self).fold_with(folder)) diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 0b0bab96dfdfd..4a5c371189e4a 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -30,6 +30,8 @@ #![feature(slice_sort_by_cached_key)] #![feature(optin_builtin_traits)] +#![recursion_limit="256"] + use rustc::dep_graph::WorkProduct; use syntax_pos::symbol::Symbol; diff --git a/src/librustc_codegen_utils/symbol_names_test.rs b/src/librustc_codegen_utils/symbol_names_test.rs index 47bbd67fb5c70..773663819249e 100644 --- a/src/librustc_codegen_utils/symbol_names_test.rs +++ b/src/librustc_codegen_utils/symbol_names_test.rs @@ -33,10 +33,12 @@ pub fn report_symbol_names<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { tcx.dep_graph.with_ignore(|| { let mut visitor = SymbolNamesTest { tcx: tcx }; + // FIXME: Try parallel version tcx.hir.krate().visit_all_item_likes(&mut visitor); }) } +#[derive(Clone)] struct SymbolNamesTest<'a, 'tcx:'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, } diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 0a1139700984d..466a0c9ef10e7 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -37,6 +37,7 @@ use syntax::ast; use syntax::ptr::P; use syntax_pos::{Span, DUMMY_SP}; +#[derive(Clone)] struct OuterVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx> } impl<'a, 'tcx> Visitor<'tcx> for OuterVisitor<'a, 'tcx> { @@ -52,7 +53,7 @@ impl<'a, 'tcx> Visitor<'tcx> for OuterVisitor<'a, 'tcx> { } pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { - tcx.hir.krate().visit_all_item_likes(&mut OuterVisitor { tcx: tcx }.as_deep_visitor()); + tcx.hir.krate().par_deep_visit_items(OuterVisitor { tcx: tcx }); tcx.sess.abort_if_errors(); } diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs index b6b5edc094003..708c33fca804d 100644 --- a/src/librustc_passes/lib.rs +++ b/src/librustc_passes/lib.rs @@ -20,6 +20,8 @@ #![feature(rustc_diagnostic_macros)] +#![recursion_limit="256"] + #[macro_use] extern crate rustc; extern crate rustc_mir; diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs index 82ac112b534e9..2f07addbcb306 100644 --- a/src/librustc_passes/rvalue_promotion.rs +++ b/src/librustc_passes/rvalue_promotion.rs @@ -51,10 +51,7 @@ pub fn provide(providers: &mut Providers) { } pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { - for &body_id in &tcx.hir.krate().body_ids { - let def_id = tcx.hir.body_owner_def_id(body_id); - tcx.const_is_rvalue_promotable_to_static(def_id); - } + tcx.par_body_owners(|def_id| { tcx.const_is_rvalue_promotable_to_static(def_id); }); tcx.sess.abort_if_errors(); } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 0787e7e1d5f78..1ae7ef05c8c6b 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -682,8 +682,8 @@ impl<'a, 'tcx> ParItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> { pub fn check_wf_new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), ErrorReported> { tcx.sess.track_errors(|| { - let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx); - tcx.hir.krate().visit_all_item_likes(&mut visit.as_deep_visitor()); + let visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx); + tcx.hir.krate().par_deep_visit_items(visit); }) } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 4b4b982b1be41..61120b5b54b29 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -727,6 +727,7 @@ fn check_false_global_bounds<'a, 'gcx, 'tcx>( fcx.select_all_obligations_or_error(); } +#[derive(Clone)] pub struct CheckTypeWellFormedVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 0c98f6c0fa100..129b60193f267 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -50,7 +50,6 @@ use syntax_pos::{Span, DUMMY_SP}; use rustc::hir::{self, map as hir_map, CodegenFnAttrs, CodegenFnAttrFlags, Unsafety}; use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; -use rustc::hir::itemlikevisit::{IntoVisitor, ParDeepVisitor}; use rustc::hir::def::{Def, CtorKind}; use rustc::hir::def_id::{DefId, LOCAL_CRATE}; @@ -58,8 +57,7 @@ use rustc::hir::def_id::{DefId, LOCAL_CRATE}; // Main entry point pub fn collect_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { - let visitor = CollectItemTypesVisitor { tcx: tcx }; - tcx.hir.krate().par_visit_all_item_likes(&ParDeepVisitor(visitor)); + tcx.hir.krate().par_deep_visit_items(CollectItemTypesVisitor { tcx: tcx }); } pub fn provide(providers: &mut Providers) { @@ -104,14 +102,6 @@ struct CollectItemTypesVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx> } -impl<'a, 'tcx: 'a> IntoVisitor<'tcx> for CollectItemTypesVisitor<'a, 'tcx> { - type Visitor = Self; - - fn into_visitor(&self) -> Self { - self.clone() - } -} - impl<'a, 'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'a, 'tcx> { fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { NestedVisitorMap::OnlyBodies(&self.tcx.hir) diff --git a/src/librustc_typeck/outlives/test.rs b/src/librustc_typeck/outlives/test.rs index c3c2ae667ddd9..bdb0999cbeecb 100644 --- a/src/librustc_typeck/outlives/test.rs +++ b/src/librustc_typeck/outlives/test.rs @@ -9,21 +9,19 @@ // except according to those terms. use rustc::hir; -use rustc::hir::itemlikevisit::ItemLikeVisitor; +use rustc::hir::itemlikevisit::ParItemLikeVisitor; use rustc::ty::TyCtxt; pub fn test_inferred_outlives<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { - tcx.hir - .krate() - .visit_all_item_likes(&mut OutlivesTest { tcx }); + tcx.hir.krate().par_visit_all_item_likes(&mut OutlivesTest { tcx }); } struct OutlivesTest<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, } -impl<'a, 'tcx> ItemLikeVisitor<'tcx> for OutlivesTest<'a, 'tcx> { - fn visit_item(&mut self, item: &'tcx hir::Item) { +impl<'a, 'tcx> ParItemLikeVisitor<'tcx> for OutlivesTest<'a, 'tcx> { + fn visit_item(&self, item: &'tcx hir::Item) { let item_def_id = self.tcx.hir.local_def_id(item.id); // For unit testing: check for a special "rustc_outlives" @@ -40,6 +38,6 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for OutlivesTest<'a, 'tcx> { } } - fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem) {} - fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) {} + fn visit_trait_item(&self, _: &'tcx hir::TraitItem) { } + fn visit_impl_item(&self, _: &'tcx hir::ImplItem) { } } From 9d0d0712d8a661a212f0c50001ac199217b8bd6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 24 Jan 2018 09:59:08 +0100 Subject: [PATCH 10/17] Save query results and the dep graph in parallel --- src/librustc_incremental/lib.rs | 2 ++ src/librustc_incremental/persist/save.rs | 22 ++++++++++++++-------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/librustc_incremental/lib.rs b/src/librustc_incremental/lib.rs index ababce69e3170..3839c133a6eb2 100644 --- a/src/librustc_incremental/lib.rs +++ b/src/librustc_incremental/lib.rs @@ -17,6 +17,8 @@ #![feature(fs_read_write)] #![feature(specialization)] +#![recursion_limit="256"] + extern crate graphviz; #[macro_use] extern crate rustc; extern crate rustc_data_structures; diff --git a/src/librustc_incremental/persist/save.rs b/src/librustc_incremental/persist/save.rs index be725b1793321..dcef0c662c3a1 100644 --- a/src/librustc_incremental/persist/save.rs +++ b/src/librustc_incremental/persist/save.rs @@ -13,6 +13,7 @@ use rustc::session::Session; use rustc::ty::TyCtxt; use rustc::util::common::time; use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::sync::join; use rustc_serialize::Encodable as RustcEncodable; use rustc_serialize::opaque::Encoder; use std::io::{self, Cursor}; @@ -33,23 +34,28 @@ pub fn save_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { return; } - time(sess, "persist query result cache", || { - save_in(sess, - query_cache_path(sess), - |e| encode_query_cache(tcx, e)); - }); + let query_cache_path = query_cache_path(sess); + let dep_graph_path = dep_graph_path(sess); - if tcx.sess.opts.debugging_opts.incremental_queries { + join(move || { + if tcx.sess.opts.debugging_opts.incremental_queries { + time(sess, "persist query result cache", || { + save_in(sess, + query_cache_path, + |e| encode_query_cache(tcx, e)); + }); + } + }, || { time(sess, "persist dep-graph", || { save_in(sess, - dep_graph_path(sess), + dep_graph_path, |e| { time(sess, "encode dep-graph", || { encode_dep_graph(tcx, e) }) }); }); - } + }); dirty_clean::check_dirty_clean_annotations(tcx); }) From 804b3cd82bab9c3b71a5e1dd1fda2b165335cc71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sun, 21 Jan 2018 18:27:18 +0100 Subject: [PATCH 11/17] Force parallel queries --- src/bootstrap/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 47feb8a8ab66d..a5f5248c7526d 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -536,7 +536,7 @@ impl Config { } set(&mut config.wasm_syscall, rust.wasm_syscall); set(&mut config.lld_enabled, rust.lld); - config.rustc_parallel_queries = rust.experimental_parallel_queries.unwrap_or(false); + config.rustc_parallel_queries = rust.experimental_parallel_queries.unwrap_or(true); config.rustc_default_linker = rust.default_linker.clone(); config.musl_root = rust.musl_root.clone().map(PathBuf::from); config.save_toolstates = rust.save_toolstates.clone().map(PathBuf::from); From e2ab5827093de1d228c4231237468ad782433088 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sun, 21 Jan 2018 19:46:14 +0100 Subject: [PATCH 12/17] Parallelize trans item collection --- src/librustc_mir/lib.rs | 3 ++ src/librustc_mir/monomorphize/collector.rs | 42 ++++++++++++---------- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 34eb444fdc0cb..6ba5d02243cde 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -34,7 +34,10 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(specialization)] #![feature(try_trait)] +#![recursion_limit="256"] + extern crate arena; + #[macro_use] extern crate bitflags; #[macro_use] extern crate log; diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index a8a50e14c6822..f509a54d9c725 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -207,10 +207,12 @@ use rustc::mir::interpret::{Scalar, GlobalId, AllocType}; use monomorphize::{self, Instance}; use rustc::util::nodemap::{FxHashSet, FxHashMap, DefIdMap}; +use rustc::util::common::time; use monomorphize::item::{MonoItemExt, DefPathBasedNames, InstantiationMode}; use rustc_data_structures::bitvec::BitVector; +use rustc_data_structures::sync::{ParallelIterator, par_iter, Lock}; #[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)] pub enum MonoItemCollectionMode { @@ -298,22 +300,26 @@ pub fn collect_crate_mono_items<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mode: MonoItemCollectionMode) -> (FxHashSet>, InliningMap<'tcx>) { - let roots = collect_roots(tcx, mode); + let roots = time(tcx.sess, "collecting roots", || { + collect_roots(tcx, mode) + }); debug!("Building mono item graph, beginning at roots"); - let mut visited = FxHashSet(); - let mut recursion_depths = DefIdMap(); - let mut inlining_map = InliningMap::new(); - - for root in roots { - collect_items_rec(tcx, - root, - &mut visited, - &mut recursion_depths, - &mut inlining_map); - } + let visited = Lock::new(FxHashSet()); + let inlining_map = Lock::new(InliningMap::new()); + + time(tcx.sess, "collecting mono items", || { + par_iter(roots).for_each(|root| { + let mut recursion_depths = DefIdMap(); + collect_items_rec(tcx, + root, + &visited, + &mut recursion_depths, + &inlining_map); + }); + }); - (visited, inlining_map) + (visited.into_inner(), inlining_map.into_inner()) } // Find all non-generic items by walking the HIR. These items serve as roots to @@ -354,10 +360,10 @@ fn collect_roots<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Collect all monomorphized items reachable from `starting_point` fn collect_items_rec<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, starting_point: MonoItem<'tcx>, - visited: &mut FxHashSet>, + visited: &Lock>>, recursion_depths: &mut DefIdMap, - inlining_map: &mut InliningMap<'tcx>) { - if !visited.insert(starting_point.clone()) { + inlining_map: &Lock>) { + if !visited.lock().insert(starting_point.clone()) { // We've been here already, no need to search again. return; } @@ -425,7 +431,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn record_accesses<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, caller: MonoItem<'tcx>, callees: &[MonoItem<'tcx>], - inlining_map: &mut InliningMap<'tcx>) { + inlining_map: &Lock>) { let is_inlining_candidate = |mono_item: &MonoItem<'tcx>| { mono_item.instantiation_mode(tcx) == InstantiationMode::LocalCopy }; @@ -435,7 +441,7 @@ fn record_accesses<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, (*mono_item, is_inlining_candidate(mono_item)) }); - inlining_map.record_accesses(caller, accesses); + inlining_map.lock().record_accesses(caller, accesses); } fn check_recursion_limit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, From 917c1987a9c0f1820141665f2f79b399dff472d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Mon, 22 Jan 2018 14:31:23 +0100 Subject: [PATCH 13/17] Have thread-local GlobalArenas --- src/librustc/ty/context.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 1c5f8b775aa42..fd9e7031cc4d5 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -69,7 +69,6 @@ use std::ops::Deref; use std::iter; use std::sync::mpsc; use std::sync::Arc; -use std::sync::Mutex; use rustc_target::spec::abi; use syntax::ast::{self, NodeId}; use syntax::attr; @@ -1714,8 +1713,6 @@ pub mod tls { use rayon_core; use dep_graph::OpenTask; use rustc_data_structures::sync::{self, Lrc, Lock}; - use std::sync::Arc; - use std::sync::Mutex; /// This is the implicit state of rustc. It contains the current /// TyCtxt and query. It is updated when creating a local interner or From 05887d8ec4d564587648f80d0abc39758ed74f91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Fri, 9 Feb 2018 10:33:29 +0100 Subject: [PATCH 14/17] Force 8 query threads --- src/librustc/session/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 076d56fb80842..942fd685eaf78 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -872,8 +872,8 @@ impl Session { /// Returns the number of query threads that should be used for this /// compilation - pub fn query_threads_from_opts(opts: &config::Options) -> usize { - opts.debugging_opts.query_threads.unwrap_or(1) + pub fn query_threads_from_opts(_opts: &config::Options) -> usize { + /*opts.debugging_opts.query_threads.unwrap_or(1)*/8 } /// Returns the number of query threads that should be used for this From a336145a70dc8e17ce23834dda7181cee59f87b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 14 Mar 2018 21:25:52 +0100 Subject: [PATCH 15/17] Add crates to whitelist --- src/tools/tidy/src/deps.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index cef548b0d94da..b4f7b10d3a700 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -70,6 +70,9 @@ static WHITELIST: &'static [Crate] = &[ Crate("chalk-macros"), Crate("cfg-if"), Crate("cmake"), + Crate("coco"), + Crate("context"), + Crate("crossbeam-channel"), Crate("crossbeam-deque"), Crate("crossbeam-epoch"), Crate("crossbeam-utils"), @@ -81,6 +84,7 @@ static WHITELIST: &'static [Crate] = &[ Crate("flate2"), Crate("fuchsia-zircon"), Crate("fuchsia-zircon-sys"), + Crate("gcc"), Crate("getopts"), Crate("humantime"), Crate("jobserver"), @@ -94,6 +98,7 @@ static WHITELIST: &'static [Crate] = &[ Crate("miniz-sys"), Crate("nodrop"), Crate("num_cpus"), + Crate("nodrop"), Crate("owning_ref"), Crate("parking_lot"), Crate("parking_lot_core"), @@ -101,6 +106,8 @@ static WHITELIST: &'static [Crate] = &[ Crate("pkg-config"), Crate("quick-error"), Crate("rand"), + Crate("rayon"), + Crate("rayon-core"), Crate("redox_syscall"), Crate("redox_termios"), Crate("regex"), From 9d131f6bf134f472dee352bfa3d38c4cf4a38e21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Tue, 17 Apr 2018 17:36:53 +0200 Subject: [PATCH 16/17] Fix tests --- src/test/compile-fail/issue-20413.rs | 1 + src/test/compile-fail/issue-21946.rs | 1 + src/test/compile-fail/issue-23122-1.rs | 1 + src/test/compile-fail/issue-23122-2.rs | 1 + src/test/ui/cycle-trait-supertrait-indirect.stderr | 5 ----- src/test/ui/impl-trait/auto-trait-leak.stderr | 1 - src/test/ui/span/issue-35987.rs | 1 + src/test/ui/span/issue-35987.stderr | 13 +++++++++++-- 8 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/test/compile-fail/issue-20413.rs b/src/test/compile-fail/issue-20413.rs index a48c03aa178c3..a19584f80973f 100644 --- a/src/test/compile-fail/issue-20413.rs +++ b/src/test/compile-fail/issue-20413.rs @@ -18,6 +18,7 @@ struct NoData; impl Foo for T where NoData: Foo { //~^ ERROR: overflow evaluating the requirement fn answer(self) { + //~^ ERROR: overflow evaluating the requirement let val: NoData = NoData; } } diff --git a/src/test/compile-fail/issue-21946.rs b/src/test/compile-fail/issue-21946.rs index 0d652be5c2611..d93b9caa20a91 100644 --- a/src/test/compile-fail/issue-21946.rs +++ b/src/test/compile-fail/issue-21946.rs @@ -17,6 +17,7 @@ struct FooStruct; impl Foo for FooStruct { //~^ ERROR overflow evaluating the requirement `::A` type A = ::A; + //~^ ERROR overflow evaluating the requirement `::A` } fn main() {} diff --git a/src/test/compile-fail/issue-23122-1.rs b/src/test/compile-fail/issue-23122-1.rs index 36d8450848d05..7d591c1bad02e 100644 --- a/src/test/compile-fail/issue-23122-1.rs +++ b/src/test/compile-fail/issue-23122-1.rs @@ -17,6 +17,7 @@ struct GetNext { t: T } impl Next for GetNext { //~^ ERROR overflow evaluating the requirement type Next = as Next>::Next; + //~^ ERROR overflow evaluating the requirement } fn main() {} diff --git a/src/test/compile-fail/issue-23122-2.rs b/src/test/compile-fail/issue-23122-2.rs index faaf78f894b05..21d5d5cbd0beb 100644 --- a/src/test/compile-fail/issue-23122-2.rs +++ b/src/test/compile-fail/issue-23122-2.rs @@ -17,6 +17,7 @@ struct GetNext { t: T } impl Next for GetNext { //~^ ERROR overflow evaluating the requirement type Next = as Next>::Next; + //~^ ERROR overflow evaluating the requirement } fn main() {} diff --git a/src/test/ui/cycle-trait-supertrait-indirect.stderr b/src/test/ui/cycle-trait-supertrait-indirect.stderr index 85681b478e21d..ae1d164bc9b93 100644 --- a/src/test/ui/cycle-trait-supertrait-indirect.stderr +++ b/src/test/ui/cycle-trait-supertrait-indirect.stderr @@ -10,11 +10,6 @@ note: ...which requires computing the supertraits of `C`... LL | trait C: B { } | ^^^^^^^^^^ = note: ...which again requires computing the supertraits of `B`, completing the cycle -note: cycle used when computing the supertraits of `A` - --> $DIR/cycle-trait-supertrait-indirect.rs:14:1 - | -LL | trait A: B { - | ^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr index efa9a58d63310..02d40c687db94 100644 --- a/src/test/ui/impl-trait/auto-trait-leak.stderr +++ b/src/test/ui/impl-trait/auto-trait-leak.stderr @@ -52,7 +52,6 @@ note: ...which requires processing `cycle1::{{impl-Trait}}`... LL | fn cycle1() -> impl Clone { | ^^^^^^^^^^ = note: ...which again requires processing `cycle1`, completing the cycle -note: cycle used when type-checking all item bodies error: aborting due to 3 previous errors diff --git a/src/test/ui/span/issue-35987.rs b/src/test/ui/span/issue-35987.rs index 19e05f33825f7..5bd516fa46ab7 100644 --- a/src/test/ui/span/issue-35987.rs +++ b/src/test/ui/span/issue-35987.rs @@ -17,6 +17,7 @@ impl Add for Foo { type Output = usize; fn add(self, rhs: Self) -> Self::Output { + //~^ ERROR ambiguous associated type unimplemented!(); } } diff --git a/src/test/ui/span/issue-35987.stderr b/src/test/ui/span/issue-35987.stderr index 1dd45bb1e5efe..b53b514f8a61d 100644 --- a/src/test/ui/span/issue-35987.stderr +++ b/src/test/ui/span/issue-35987.stderr @@ -8,6 +8,15 @@ help: possible better candidate is found in another module, you can import it in LL | use std::ops::Add; | -error: aborting due to previous error +error[E0223]: ambiguous associated type + --> $DIR/issue-35987.rs:19:32 + | +LL | fn add(self, rhs: Self) -> Self::Output { + | ^^^^^^^^^^^^ ambiguous associated type + | + = note: specify the type using the syntax ` as Trait>::Output` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0404`. +Some errors occurred: E0223, E0404. +For more information about an error, try `rustc --explain E0223`. From be5b986567a4a5ef3c47f8b4f180b7086e689bb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Tue, 5 Jun 2018 23:40:18 +0200 Subject: [PATCH 17/17] Update Cargo.lock --- src/Cargo.lock | 104 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 101 insertions(+), 3 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index d17faef82b563..4d650aa69af4f 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -375,6 +375,15 @@ dependencies = [ "cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "coco" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "colored" version = "1.6.0" @@ -449,6 +458,17 @@ dependencies = [ name = "completion" version = "0.1.0" +[[package]] +name = "context" +version = "2.0.0" +source = "git+https://github.com/Zoxc/context-rs.git#f932ce270044194fec0572f719ab903af0248c0d" +dependencies = [ + "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "core" version = "0.0.0" @@ -487,6 +507,16 @@ name = "crossbeam" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "crossbeam-channel" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-epoch 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "crossbeam-deque" version = "0.2.0" @@ -510,6 +540,19 @@ dependencies = [ "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "crossbeam-epoch" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "crossbeam-utils" version = "0.2.2" @@ -518,6 +561,14 @@ dependencies = [ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "crossbeam-utils" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "crypto-hash" version = "0.3.1" @@ -804,6 +855,11 @@ name = "futures" version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "gcc" +version = "0.3.54" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "getopts" version = "0.2.17" @@ -1784,18 +1840,23 @@ dependencies = [ "fmt_macros 0.0.0", "graphviz 0.0.0", "jobserver 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "polonius-engine 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "proc_macro 0.0.0", + "rustc-rayon 0.9.0 (git+https://github.com/Zoxc/rayon.git?branch=fiber)", + "rustc-rayon-core 1.3.0 (git+https://github.com/Zoxc/rayon.git?branch=fiber)", "rustc_apfloat 0.0.0", "rustc_data_structures 0.0.0", "rustc_errors 0.0.0", "rustc_target 0.0.0", + "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "serialize 0.0.0", "syntax 0.0.0", "syntax_pos 0.0.0", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1918,6 +1979,15 @@ dependencies = [ "rustc-rayon-core 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rustc-rayon" +version = "0.9.0" +source = "git+https://github.com/Zoxc/rayon.git?branch=fiber#e3840ded67c686bb55d16131cdd7423463be3e5c" +dependencies = [ + "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-rayon-core 1.3.0 (git+https://github.com/Zoxc/rayon.git?branch=fiber)", +] + [[package]] name = "rustc-rayon-core" version = "0.1.0" @@ -1930,6 +2000,25 @@ dependencies = [ "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rustc-rayon-core" +version = "1.3.0" +source = "git+https://github.com/Zoxc/rayon.git?branch=fiber#e3840ded67c686bb55d16131cdd7423463be3e5c" +dependencies = [ + "coco 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "context 2.0.0 (git+https://github.com/Zoxc/context-rs.git)", + "crossbeam-channel 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rustc-serialize" version = "0.3.24" @@ -2044,8 +2133,8 @@ dependencies = [ "parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-rayon 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-rayon-core 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-rayon 0.9.0 (git+https://github.com/Zoxc/rayon.git?branch=fiber)", + "rustc-rayon-core 1.3.0 (git+https://github.com/Zoxc/rayon.git?branch=fiber)", "rustc_cratesio_shim 0.0.0", "serialize 0.0.0", "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2061,7 +2150,8 @@ dependencies = [ "graphviz 0.0.0", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", - "rustc-rayon 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-rayon 0.9.0 (git+https://github.com/Zoxc/rayon.git?branch=fiber)", + "rustc-rayon-core 1.3.0 (git+https://github.com/Zoxc/rayon.git?branch=fiber)", "rustc_allocator 0.0.0", "rustc_borrowck 0.0.0", "rustc_codegen_utils 0.0.0", @@ -3070,16 +3160,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f16b89cbb9ee36d87483dc939fe9f1e13c05898d56d7b230a0d4dff033a536" "checksum clippy_lints 0.0.205 (registry+https://github.com/rust-lang/crates.io-index)" = "1dcb837d7510bf9e4e3b6f470c450c6d25e61116db5503a6f565bb6283860622" "checksum cmake 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)" = "5cf678ceebedde428000cb3a34465cf3606d1a48da17014948a916deac39da7c" +"checksum coco 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04d5eef9c9354cbb35d5069c39054c657469d2aa7789d4c71d0a6b686dc48bea" "checksum colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b0aa3473e85a3161b59845d6096b289bb577874cafeaf75ea1b1beaa6572c7fc" "checksum commoncrypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d056a8586ba25a1e4d61cb090900e495952c7886786fc55f909ab2f819b69007" "checksum commoncrypto-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fed34f46747aa73dfaa578069fd8279d2818ade2b55f38f22a9401c7f4083e2" "checksum compiletest_rs 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "608d9d3ccc45b63bf337d2ff5e65def5a5a52c187122232509f6b72707f61b1b" +"checksum context 2.0.0 (git+https://github.com/Zoxc/context-rs.git)" = "" "checksum core-foundation 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7caa6cb9e76ddddbea09a03266d6b3bc98cd41e9fb9b017c473e7cca593ec25" "checksum core-foundation-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b2a53cce0ddcf7e7e1f998738d757d5a3bf08bf799a180e50ebe50d298f52f5a" "checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19" +"checksum crossbeam-channel 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "862becd07e73da5746de6d9b3ba055c9bb8b10afd0d2b51155a6e30d81cd20b3" "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" "checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" +"checksum crossbeam-epoch 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9b4e2817eb773f770dcb294127c011e22771899c21d18fce7dd739c0b9832e81" "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" +"checksum crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d636a8b3bcc1b409d7ffd3facef8f21dcb4009626adbd0c5e6c4305c07253c7b" "checksum crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "09de9ee0fc255ace04c7fa0763c9395a945c37c8292bb554f8d48361d1dcf1b4" "checksum curl 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "aaf20bbe084f285f215eef2165feed70d6b75ba29cad24469badb853a4a287d0" "checksum curl-sys 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "71c63a540a9ee4e15e56c3ed9b11a2f121239b9f6d7b7fe30f616e048148df9a" @@ -3111,6 +3206,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum futf 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "51f93f3de6ba1794dcd5810b3546d004600a59a98266487c8407bc4b24e398f3" "checksum futures 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "0c5a3176836efa0b37f0e321b86672dfada1564aeb516fbed67b7c24050a0263" +"checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb" "checksum getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "b900c08c1939860ce8b54dc6a89e26e00c04c380fd0e09796799bd7f12861e05" "checksum git2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f41c0035c37ec11ed3f1e1946a76070b0c740393687e9a9c7612f6a709036b3" "checksum git2-curl 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b502f6b1b467957403d168f0039e0c46fa6a1220efa2adaef25d5b267b5fe024" @@ -3216,7 +3312,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11fb43a206a04116ffd7cfcf9bcb941f8eb6cc7ff667272246b0a1c74259a3cb" "checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8" "checksum rustc-rayon 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1aa5cd8c3a706edb19b6ec6aa7b056bdc635b6e99c5cf7014f9af9d92f15e99" +"checksum rustc-rayon 0.9.0 (git+https://github.com/Zoxc/rayon.git?branch=fiber)" = "" "checksum rustc-rayon-core 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d69983f8613a9c3ba1a3bbf5e8bdf2fd5c42317b1d8dd8623ca8030173bf8a6b" +"checksum rustc-rayon-core 1.3.0 (git+https://github.com/Zoxc/rayon.git?branch=fiber)" = "" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a54aa04a10c68c1c4eacb4337fd883b435997ede17a9385784b990777686b09a" "checksum rustfix 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9da3cf9b79dc889a2c9879643f26d7a53e37e9361c7566b7d2787d5ace0d8396"