Skip to content

Commit

Permalink
Auto merge of #70951 - cjgillot:anarchy, r=oli-obk
Browse files Browse the repository at this point in the history
Move the query engine out of rustc_middle

The handling of queries is moved to a trait `QueryEngine`.
It replaces `query::Queries` in the `TyCtxt`, allowing to move the query engine out of librustc_middle.

There are 2 modes to access the query engine: through `TyCtxt` and dynamic dispatch,
or through a `QueryCtxt`. The `QueryCtxt` is  required for everything touching the `OnDiskCache`.

For now, I put it in librustc_incremental, which is very small.
This may not be the best place.

A significant part of the codegen time for librustc_middle is moved to the recipient crate.

This PR may require a perf run.

cc #65031
r? `@Zoxc`
  • Loading branch information
bors committed Feb 20, 2021
2 parents e7c23ab + 9823c2c commit 83b30a6
Show file tree
Hide file tree
Showing 37 changed files with 1,362 additions and 1,175 deletions.
26 changes: 26 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3878,6 +3878,7 @@ version = "0.0.0"
dependencies = [
"libc",
"rustc-rayon",
"rustc-rayon-core",
"rustc_ast",
"rustc_ast_lowering",
"rustc_ast_passes",
Expand All @@ -3890,6 +3891,7 @@ dependencies = [
"rustc_expand",
"rustc_hir",
"rustc_incremental",
"rustc_index",
"rustc_lint",
"rustc_metadata",
"rustc_middle",
Expand All @@ -3899,6 +3901,7 @@ dependencies = [
"rustc_passes",
"rustc_plugin_impl",
"rustc_privacy",
"rustc_query_impl",
"rustc_resolve",
"rustc_serialize",
"rustc_session",
Expand Down Expand Up @@ -4165,6 +4168,29 @@ dependencies = [
"tracing",
]

[[package]]
name = "rustc_query_impl"
version = "0.0.0"
dependencies = [
"measureme",
"rustc-rayon-core",
"rustc_ast",
"rustc_attr",
"rustc_data_structures",
"rustc_errors",
"rustc_feature",
"rustc_hir",
"rustc_index",
"rustc_macros",
"rustc_middle",
"rustc_query_system",
"rustc_serialize",
"rustc_session",
"rustc_span",
"rustc_target",
"tracing",
]

[[package]]
name = "rustc_query_system"
version = "0.0.0"
Expand Down
6 changes: 1 addition & 5 deletions compiler/rustc_codegen_cranelift/src/driver/aot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -465,9 +465,5 @@ fn determine_cgu_reuse<'tcx>(tcx: TyCtxt<'tcx>, cgu: &CodegenUnit<'tcx>) -> CguR
cgu.name()
);

if tcx.dep_graph.try_mark_green(tcx, &dep_node).is_some() {
CguReuse::PreLto
} else {
CguReuse::No
}
if tcx.try_mark_green(&dep_node) { CguReuse::PreLto } else { CguReuse::No }
}
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -867,7 +867,7 @@ fn determine_cgu_reuse<'tcx>(tcx: TyCtxt<'tcx>, cgu: &CodegenUnit<'tcx>) -> CguR
cgu.name()
);

if tcx.dep_graph.try_mark_green(tcx, &dep_node).is_some() {
if tcx.try_mark_green(&dep_node) {
// We can re-use either the pre- or the post-thinlto state. If no LTO is
// being performed then we can use post-LTO artifacts, otherwise we must
// reuse pre-LTO artifacts
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ use rustc_interface::{interface, Queries};
use rustc_lint::LintStore;
use rustc_metadata::locator;
use rustc_middle::middle::cstore::MetadataLoader;
use rustc_middle::ty::TyCtxt;
use rustc_save_analysis as save;
use rustc_save_analysis::DumpHandler;
use rustc_serialize::json::{self, ToJson};
Expand Down Expand Up @@ -1232,7 +1231,7 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {

let num_frames = if backtrace { None } else { Some(2) };

TyCtxt::try_print_query_stack(&handler, num_frames);
interface::try_print_query_stack(&handler, num_frames);

#[cfg(windows)]
unsafe {
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_interface/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ doctest = false
[dependencies]
libc = "0.2"
tracing = "0.1"
rustc-rayon-core = "0.3.0"
rayon = { version = "0.3.0", package = "rustc-rayon" }
smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
rustc_ast = { path = "../rustc_ast" }
Expand All @@ -30,6 +31,7 @@ rustc_codegen_ssa = { path = "../rustc_codegen_ssa" }
rustc_symbol_mangling = { path = "../rustc_symbol_mangling" }
rustc_codegen_llvm = { path = "../rustc_codegen_llvm", optional = true }
rustc_hir = { path = "../rustc_hir" }
rustc_index = { path = "../rustc_index" }
rustc_metadata = { path = "../rustc_metadata" }
rustc_mir = { path = "../rustc_mir" }
rustc_mir_build = { path = "../rustc_mir_build" }
Expand All @@ -39,6 +41,7 @@ rustc_lint = { path = "../rustc_lint" }
rustc_errors = { path = "../rustc_errors" }
rustc_plugin_impl = { path = "../rustc_plugin_impl" }
rustc_privacy = { path = "../rustc_privacy" }
rustc_query_impl = { path = "../rustc_query_impl" }
rustc_resolve = { path = "../rustc_resolve" }
rustc_trait_selection = { path = "../rustc_trait_selection" }
rustc_ty_utils = { path = "../rustc_ty_utils" }
Expand Down
23 changes: 22 additions & 1 deletion compiler/rustc_interface/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::sync::Lrc;
use rustc_data_structures::OnDrop;
use rustc_errors::registry::Registry;
use rustc_errors::ErrorReported;
use rustc_errors::{ErrorReported, Handler};
use rustc_lint::LintStore;
use rustc_middle::ty;
use rustc_parse::new_parser_from_source_str;
Expand Down Expand Up @@ -213,3 +213,24 @@ pub fn run_compiler<R: Send>(mut config: Config, f: impl FnOnce(&Compiler) -> R
|| create_compiler_and_run(config, f),
)
}

pub fn try_print_query_stack(handler: &Handler, num_frames: Option<usize>) {
eprintln!("query stack during panic:");

// Be careful relying on global state here: this code is called from
// a panic hook, which means that the global `Handler` may be in a weird
// state if it was responsible for triggering the panic.
let i = ty::tls::with_context_opt(|icx| {
if let Some(icx) = icx {
icx.tcx.queries.try_print_query_stack(icx.tcx, icx.query, handler, num_frames)
} else {
0
}
});

if num_frames == None || num_frames >= Some(i) {
eprintln!("end of query stack");
} else {
eprintln!("we're just showing a limited slice of the query stack");
}
}
26 changes: 17 additions & 9 deletions compiler/rustc_interface/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use rustc_expand::base::ExtCtxt;
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
use rustc_hir::definitions::Definitions;
use rustc_hir::Crate;
use rustc_index::vec::IndexVec;
use rustc_lint::LintStore;
use rustc_middle::arena::Arena;
use rustc_middle::dep_graph::DepGraph;
Expand All @@ -27,6 +28,7 @@ use rustc_mir_build as mir_build;
use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str};
use rustc_passes::{self, hir_stats, layout_test};
use rustc_plugin_impl as plugin;
use rustc_query_impl::Queries as TcxQueries;
use rustc_resolve::{Resolver, ResolverArenas};
use rustc_session::config::{CrateType, Input, OutputFilenames, OutputType, PpMode, PpSourceMode};
use rustc_session::lint;
Expand Down Expand Up @@ -738,20 +740,18 @@ pub static DEFAULT_EXTERN_QUERY_PROVIDERS: SyncLazy<Providers> = SyncLazy::new(|
extern_providers
});

pub struct QueryContext<'tcx>(&'tcx GlobalCtxt<'tcx>);
pub struct QueryContext<'tcx> {
gcx: &'tcx GlobalCtxt<'tcx>,
}

impl<'tcx> QueryContext<'tcx> {
pub fn enter<F, R>(&mut self, f: F) -> R
where
F: FnOnce(TyCtxt<'tcx>) -> R,
{
let icx = ty::tls::ImplicitCtxt::new(self.0);
let icx = ty::tls::ImplicitCtxt::new(self.gcx);
ty::tls::enter_context(&icx, |_| f(icx.tcx))
}

pub fn print_stats(&mut self) {
self.enter(ty::query::print_stats)
}
}

pub fn create_global_ctxt<'tcx>(
Expand All @@ -762,6 +762,7 @@ pub fn create_global_ctxt<'tcx>(
mut resolver_outputs: ResolverOutputs,
outputs: OutputFilenames,
crate_name: &str,
queries: &'tcx OnceCell<TcxQueries<'tcx>>,
global_ctxt: &'tcx OnceCell<GlobalCtxt<'tcx>>,
arena: &'tcx WorkerLocal<Arena<'tcx>>,
) -> QueryContext<'tcx> {
Expand All @@ -785,26 +786,33 @@ pub fn create_global_ctxt<'tcx>(
callback(sess, &mut local_providers, &mut extern_providers);
}

let queries = {
let crates = resolver_outputs.cstore.crates_untracked();
let max_cnum = crates.iter().map(|c| c.as_usize()).max().unwrap_or(0);
let mut providers = IndexVec::from_elem_n(extern_providers, max_cnum + 1);
providers[LOCAL_CRATE] = local_providers;
queries.get_or_init(|| TcxQueries::new(providers, extern_providers))
};

let gcx = sess.time("setup_global_ctxt", || {
global_ctxt.get_or_init(|| {
TyCtxt::create_global_ctxt(
sess,
lint_store,
local_providers,
extern_providers,
arena,
resolver_outputs,
krate,
defs,
dep_graph,
query_result_on_disk_cache,
queries.as_dyn(),
&crate_name,
&outputs,
)
})
});

QueryContext(gcx)
QueryContext { gcx }
}

/// Runs the resolution, type-checking, region checking and other
Expand Down
8 changes: 6 additions & 2 deletions compiler/rustc_interface/src/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use rustc_lint::LintStore;
use rustc_middle::arena::Arena;
use rustc_middle::dep_graph::DepGraph;
use rustc_middle::ty::{GlobalCtxt, ResolverOutputs, TyCtxt};
use rustc_query_impl::Queries as TcxQueries;
use rustc_serialize::json;
use rustc_session::config::{self, OutputFilenames, OutputType};
use rustc_session::{output::find_crate_name, Session};
Expand Down Expand Up @@ -71,6 +72,7 @@ impl<T> Default for Query<T> {
pub struct Queries<'tcx> {
compiler: &'tcx Compiler,
gcx: OnceCell<GlobalCtxt<'tcx>>,
queries: OnceCell<TcxQueries<'tcx>>,

arena: WorkerLocal<Arena<'tcx>>,
hir_arena: WorkerLocal<rustc_ast_lowering::Arena<'tcx>>,
Expand All @@ -92,6 +94,7 @@ impl<'tcx> Queries<'tcx> {
Queries {
compiler,
gcx: OnceCell::new(),
queries: OnceCell::new(),
arena: WorkerLocal::new(|_| Arena::default()),
hir_arena: WorkerLocal::new(|_| rustc_ast_lowering::Arena::default()),
dep_graph_future: Default::default(),
Expand Down Expand Up @@ -265,6 +268,7 @@ impl<'tcx> Queries<'tcx> {
resolver_outputs.steal(),
outputs,
&crate_name,
&self.queries,
&self.gcx,
&self.arena,
))
Expand Down Expand Up @@ -425,11 +429,11 @@ impl Compiler {
{
let _prof_timer =
queries.session().prof.generic_activity("self_profile_alloc_query_strings");
gcx.enter(|tcx| tcx.alloc_self_profile_query_strings());
gcx.enter(rustc_query_impl::alloc_self_profile_query_strings);
}

if self.session().opts.debugging_opts.query_stats {
gcx.print_stats();
gcx.enter(rustc_query_impl::print_stats);
}
}

Expand Down
32 changes: 28 additions & 4 deletions compiler/rustc_interface/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ use rustc_data_structures::stable_hasher::StableHasher;
use rustc_data_structures::sync::Lrc;
use rustc_errors::registry::Registry;
use rustc_metadata::dynamic_lib::DynamicLibrary;
#[cfg(parallel_compiler)]
use rustc_middle::ty::tls;
use rustc_resolve::{self, Resolver};
use rustc_session as session;
use rustc_session::config::{self, CrateType};
Expand All @@ -29,11 +31,12 @@ use std::io;
use std::lazy::SyncOnceCell;
use std::mem;
use std::ops::DerefMut;
#[cfg(not(parallel_compiler))]
use std::panic;
use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex, Once};
#[cfg(not(parallel_compiler))]
use std::{panic, thread};
use std::thread;
use tracing::info;

/// Adds `target_feature = "..."` cfgs for a variety of platform
Expand Down Expand Up @@ -156,22 +159,43 @@ pub fn setup_callbacks_and_run_in_thread_pool_with_globals<F: FnOnce() -> R + Se
scoped_thread(cfg, main_handler)
}

/// Creates a new thread and forwards information in thread locals to it.
/// The new thread runs the deadlock handler.
/// Must only be called when a deadlock is about to happen.
#[cfg(parallel_compiler)]
unsafe fn handle_deadlock() {
let registry = rustc_rayon_core::Registry::current();

let context = tls::get_tlv();
assert!(context != 0);
rustc_data_structures::sync::assert_sync::<tls::ImplicitCtxt<'_, '_>>();
let icx: &tls::ImplicitCtxt<'_, '_> = &*(context as *const tls::ImplicitCtxt<'_, '_>);

let session_globals = rustc_span::SESSION_GLOBALS.with(|sg| sg as *const _);
let session_globals = &*session_globals;
thread::spawn(move || {
tls::enter_context(icx, |_| {
rustc_span::SESSION_GLOBALS
.set(session_globals, || tls::with(|tcx| tcx.queries.deadlock(tcx, &registry)))
});
});
}

#[cfg(parallel_compiler)]
pub fn setup_callbacks_and_run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
edition: Edition,
threads: usize,
stderr: &Option<Arc<Mutex<Vec<u8>>>>,
f: F,
) -> R {
use rustc_middle::ty;
crate::callbacks::setup_callbacks();

let mut config = rayon::ThreadPoolBuilder::new()
.thread_name(|_| "rustc".to_string())
.acquire_thread_handler(jobserver::acquire_thread)
.release_thread_handler(jobserver::release_thread)
.num_threads(threads)
.deadlock_handler(|| unsafe { ty::query::handle_deadlock() });
.deadlock_handler(|| unsafe { handle_deadlock() });

if let Some(size) = get_stack_size() {
config = config.stack_size(size);
Expand Down
Loading

0 comments on commit 83b30a6

Please sign in to comment.