Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move the query engine out of rustc_middle #70951

Merged
merged 23 commits into from
Feb 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
7794fbb
Group logic about the Providers struct.
cjgillot Apr 9, 2020
211b05a
Don't require a QueryContext to access the DepGraph.
cjgillot Oct 11, 2020
6f04883
Remove QueryAccessors::to_dep_node.
cjgillot Oct 18, 2020
49c1b07
Decouple QueryContext from DepContext.
cjgillot Oct 18, 2020
dab9b89
Decouple the on-disk cache from the query engine.
cjgillot Jan 4, 2021
2db2776
Wrap TyCtxt inside a QueryCtxt for queries.
cjgillot Apr 8, 2020
3f868b1
Opacify query invocation.
cjgillot Jan 17, 2021
5d71b99
Make QueryEngine opaque to TyCtxt.
cjgillot Oct 11, 2020
0e9cac4
Make alloc_self_profile_query_strings a standalone function.
cjgillot Jan 17, 2021
4dbf83a
Move try_print_query_stack to rustc_interface.
cjgillot Apr 8, 2020
ea3d465
Move try_load_from_on_disk_cache to the QueryContext.
cjgillot Jan 5, 2021
a4b1158
Move handle_deadlock where it is used.
cjgillot Nov 18, 2020
6e4af4a
Move definition of callbacks to parent module.
cjgillot Jan 18, 2021
3bd14c7
Select caching strategy per query.
cjgillot Nov 18, 2020
b27266f
Use a QueryContext for try_mark_green.
cjgillot Jan 18, 2021
1ac21e4
Use QueryCtxt in DepKindStruct.
cjgillot Jan 19, 2021
cdc0b19
Split DepKindStruct in two.
cjgillot Jan 19, 2021
8e5d613
Wrap QueryDescription into a macro.
cjgillot Jan 19, 2021
24dbb61
Move query names and Providers to parent module.
cjgillot Jan 19, 2021
23f9d10
Make encode_query_results more generic.
cjgillot Jan 19, 2021
71f749a
Introduce a QueryEngine trait object.
cjgillot Jan 18, 2021
4581d16
Move the query system to rustc_query_impl.
cjgillot Jan 19, 2021
9823c2c
Workaround rustdoc not honouring cfg(parallel_compiler).
cjgillot Feb 19, 2021
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
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