Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions compiler/rustc_data_structures/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ pub use self::mode::{
FromDyn, check_dyn_thread_safe, is_dyn_thread_safe, set_dyn_thread_safe_mode,
};
pub use self::parallel::{
broadcast, par_fns, par_for_each_in, par_for_each_slice, par_join, par_map, parallel_guard,
spawn, try_par_for_each_in,
broadcast, par_fns, par_for_each_in, par_for_each_slice, par_join, par_map, par_range,
parallel_guard, spawn, try_par_for_each_in,
};
pub use self::vec::{AppendOnlyIndexVec, AppendOnlyVec};
pub use self::worker_local::{Registry, WorkerLocal};
Expand Down
39 changes: 38 additions & 1 deletion compiler/rustc_data_structures/src/sync/parallel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//! one way for the serial compiler, and another way the parallel compiler.

use std::any::Any;
use std::ops::Range;
use std::panic::{AssertUnwindSafe, catch_unwind, resume_unwind};

use parking_lot::Mutex;
Expand Down Expand Up @@ -123,6 +124,8 @@ where
}
}

const MAX_GROUP_COUNT: usize = 128;

fn par_slice<I: DynSend>(
items: &mut [I],
guard: &ParallelGuard,
Expand All @@ -143,7 +146,6 @@ fn par_slice<I: DynSend>(
rustc_thread_pool::scope(|s| {
let proof = items.derive(());

const MAX_GROUP_COUNT: usize = 128;
let group_size = items.len().div_ceil(MAX_GROUP_COUNT);
let mut groups = items.chunks_mut(group_size);

Expand All @@ -169,6 +171,41 @@ fn par_slice<I: DynSend>(
});
}

pub fn par_range(range: Range<usize>, op: impl Fn(usize) + DynSync + DynSend) {
parallel_guard(|guard| {
if let Some(proof) = mode::check_dyn_thread_safe() {
let op = proof.derive(op);

rustc_thread_pool::scope(|s| {
let len = range.end - range.start;
let group_size = len.div_ceil(MAX_GROUP_COUNT);
let mut current = range.start + group_size;

while current < range.end {
let mut c_range = current..(current + group_size);
c_range.end = range.end.min(c_range.end);

s.spawn(|_| {
for idx in c_range {
guard.run(|| op(idx));
}
});

current += group_size;
}

for idx in range.start..range.end.min(range.start + group_size) {
guard.run(|| op(idx));
}
});
} else {
for idx in range {
guard.run(|| op(idx));
}
}
});
}

pub fn par_for_each_in<I: DynSend, T: IntoIterator<Item = I>>(
t: T,
for_each: impl Fn(&I) + DynSync + DynSend,
Expand Down
30 changes: 27 additions & 3 deletions compiler/rustc_interface/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@ use rustc_crate_store::Untracked;
use rustc_data_structures::indexmap::IndexMap;
use rustc_data_structures::steal::Steal;
use rustc_data_structures::sync::{
AppendOnlyIndexVec, DynSend, DynSync, FreezeLock, WorkerLocal, par_fns,
AppendOnlyIndexVec, DynSend, DynSync, FreezeLock, WorkerLocal, is_dyn_thread_safe, par_fns,
par_range,
};
use rustc_data_structures::thousands;
use rustc_errors::timings::TimingSection;
use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, Level};
use rustc_expand::base::{ExtCtxt, LintStoreExpand};
use rustc_feature::Features;
use rustc_fs_util::try_canonicalize;
use rustc_hir::def_id::{LOCAL_CRATE, StableCrateId, StableCrateIdMap};
use rustc_hir::OwnerId;
use rustc_hir::def_id::{DefIndex, LOCAL_CRATE, LocalDefId, StableCrateId, StableCrateIdMap};
use rustc_hir::definitions::Definitions;
use rustc_incremental::setup_dep_graph;
use rustc_lint::{BufferedEarlyLint, EarlyCheckNode, LintStore, unerased_lint_store};
Expand Down Expand Up @@ -1091,9 +1093,29 @@ pub fn emit_delayed_lints(tcx: TyCtxt<'_>) {
/// Runs all analyses that we guarantee to run, even if errors were reported in earlier analyses.
/// This function never fails.
fn run_required_analyses(tcx: TyCtxt<'_>) {
let is_parallel = is_dyn_thread_safe();

// There is no point in prefectching hir owners when parallel compiler is
// deisabled, `print_hir_stats`, `check_crate` or `hir_crate_items` below will do it.
if is_parallel {
tcx.untracked().definitions.write().commit_end_of_determinism();
tcx.ensure_done().resolve_type_relative_delegations(());

let index = tcx.index_ast(());

par_range(0..index.len(), |idx| {
let id = LocalDefId { local_def_index: DefIndex::from_usize(idx) };
if index[id].is_some() {
tcx.ensure_done().hir_owner(id);
tcx.ensure_done().hir_attr_map(OwnerId { def_id: id });
}
});
}

if tcx.sess.opts.unstable_opts.input_stats {
rustc_passes::input_stats::print_hir_stats(tcx);
}

// When using rustdoc's "jump to def" feature, it enters this code and `check_crate`
// is not defined. So we need to cfg it out.
#[cfg(all(not(doc), debug_assertions))]
Expand All @@ -1104,7 +1126,9 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
// to use `hir_crate_items`.
tcx.ensure_done().hir_crate_items(());

tcx.untracked().definitions.write().commit_end_of_determinism();
if !is_parallel {
tcx.untracked().definitions.write().commit_end_of_determinism();
}

rustc_passes::delegation::check_glob_and_list_delegations_target_expr(tcx);

Expand Down
Loading