Skip to content

Commit 83b30a6

Browse files
committed
Auto merge of #70951 - cjgillot:anarchy, r=oli-obk
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`
2 parents e7c23ab + 9823c2c commit 83b30a6

File tree

37 files changed

+1362
-1175
lines changed

37 files changed

+1362
-1175
lines changed

Cargo.lock

+26
Original file line numberDiff line numberDiff line change
@@ -3878,6 +3878,7 @@ version = "0.0.0"
38783878
dependencies = [
38793879
"libc",
38803880
"rustc-rayon",
3881+
"rustc-rayon-core",
38813882
"rustc_ast",
38823883
"rustc_ast_lowering",
38833884
"rustc_ast_passes",
@@ -3890,6 +3891,7 @@ dependencies = [
38903891
"rustc_expand",
38913892
"rustc_hir",
38923893
"rustc_incremental",
3894+
"rustc_index",
38933895
"rustc_lint",
38943896
"rustc_metadata",
38953897
"rustc_middle",
@@ -3899,6 +3901,7 @@ dependencies = [
38993901
"rustc_passes",
39003902
"rustc_plugin_impl",
39013903
"rustc_privacy",
3904+
"rustc_query_impl",
39023905
"rustc_resolve",
39033906
"rustc_serialize",
39043907
"rustc_session",
@@ -4165,6 +4168,29 @@ dependencies = [
41654168
"tracing",
41664169
]
41674170

4171+
[[package]]
4172+
name = "rustc_query_impl"
4173+
version = "0.0.0"
4174+
dependencies = [
4175+
"measureme",
4176+
"rustc-rayon-core",
4177+
"rustc_ast",
4178+
"rustc_attr",
4179+
"rustc_data_structures",
4180+
"rustc_errors",
4181+
"rustc_feature",
4182+
"rustc_hir",
4183+
"rustc_index",
4184+
"rustc_macros",
4185+
"rustc_middle",
4186+
"rustc_query_system",
4187+
"rustc_serialize",
4188+
"rustc_session",
4189+
"rustc_span",
4190+
"rustc_target",
4191+
"tracing",
4192+
]
4193+
41684194
[[package]]
41694195
name = "rustc_query_system"
41704196
version = "0.0.0"

compiler/rustc_codegen_cranelift/src/driver/aot.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -465,9 +465,5 @@ fn determine_cgu_reuse<'tcx>(tcx: TyCtxt<'tcx>, cgu: &CodegenUnit<'tcx>) -> CguR
465465
cgu.name()
466466
);
467467

468-
if tcx.dep_graph.try_mark_green(tcx, &dep_node).is_some() {
469-
CguReuse::PreLto
470-
} else {
471-
CguReuse::No
472-
}
468+
if tcx.try_mark_green(&dep_node) { CguReuse::PreLto } else { CguReuse::No }
473469
}

compiler/rustc_codegen_ssa/src/base.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -867,7 +867,7 @@ fn determine_cgu_reuse<'tcx>(tcx: TyCtxt<'tcx>, cgu: &CodegenUnit<'tcx>) -> CguR
867867
cgu.name()
868868
);
869869

870-
if tcx.dep_graph.try_mark_green(tcx, &dep_node).is_some() {
870+
if tcx.try_mark_green(&dep_node) {
871871
// We can re-use either the pre- or the post-thinlto state. If no LTO is
872872
// being performed then we can use post-LTO artifacts, otherwise we must
873873
// reuse pre-LTO artifacts

compiler/rustc_driver/src/lib.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ use rustc_interface::{interface, Queries};
2727
use rustc_lint::LintStore;
2828
use rustc_metadata::locator;
2929
use rustc_middle::middle::cstore::MetadataLoader;
30-
use rustc_middle::ty::TyCtxt;
3130
use rustc_save_analysis as save;
3231
use rustc_save_analysis::DumpHandler;
3332
use rustc_serialize::json::{self, ToJson};
@@ -1232,7 +1231,7 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {
12321231

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

1235-
TyCtxt::try_print_query_stack(&handler, num_frames);
1234+
interface::try_print_query_stack(&handler, num_frames);
12361235

12371236
#[cfg(windows)]
12381237
unsafe {

compiler/rustc_interface/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ doctest = false
1010
[dependencies]
1111
libc = "0.2"
1212
tracing = "0.1"
13+
rustc-rayon-core = "0.3.0"
1314
rayon = { version = "0.3.0", package = "rustc-rayon" }
1415
smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
1516
rustc_ast = { path = "../rustc_ast" }
@@ -30,6 +31,7 @@ rustc_codegen_ssa = { path = "../rustc_codegen_ssa" }
3031
rustc_symbol_mangling = { path = "../rustc_symbol_mangling" }
3132
rustc_codegen_llvm = { path = "../rustc_codegen_llvm", optional = true }
3233
rustc_hir = { path = "../rustc_hir" }
34+
rustc_index = { path = "../rustc_index" }
3335
rustc_metadata = { path = "../rustc_metadata" }
3436
rustc_mir = { path = "../rustc_mir" }
3537
rustc_mir_build = { path = "../rustc_mir_build" }
@@ -39,6 +41,7 @@ rustc_lint = { path = "../rustc_lint" }
3941
rustc_errors = { path = "../rustc_errors" }
4042
rustc_plugin_impl = { path = "../rustc_plugin_impl" }
4143
rustc_privacy = { path = "../rustc_privacy" }
44+
rustc_query_impl = { path = "../rustc_query_impl" }
4245
rustc_resolve = { path = "../rustc_resolve" }
4346
rustc_trait_selection = { path = "../rustc_trait_selection" }
4447
rustc_ty_utils = { path = "../rustc_ty_utils" }

compiler/rustc_interface/src/interface.rs

+22-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
88
use rustc_data_structures::sync::Lrc;
99
use rustc_data_structures::OnDrop;
1010
use rustc_errors::registry::Registry;
11-
use rustc_errors::ErrorReported;
11+
use rustc_errors::{ErrorReported, Handler};
1212
use rustc_lint::LintStore;
1313
use rustc_middle::ty;
1414
use rustc_parse::new_parser_from_source_str;
@@ -213,3 +213,24 @@ pub fn run_compiler<R: Send>(mut config: Config, f: impl FnOnce(&Compiler) -> R
213213
|| create_compiler_and_run(config, f),
214214
)
215215
}
216+
217+
pub fn try_print_query_stack(handler: &Handler, num_frames: Option<usize>) {
218+
eprintln!("query stack during panic:");
219+
220+
// Be careful relying on global state here: this code is called from
221+
// a panic hook, which means that the global `Handler` may be in a weird
222+
// state if it was responsible for triggering the panic.
223+
let i = ty::tls::with_context_opt(|icx| {
224+
if let Some(icx) = icx {
225+
icx.tcx.queries.try_print_query_stack(icx.tcx, icx.query, handler, num_frames)
226+
} else {
227+
0
228+
}
229+
});
230+
231+
if num_frames == None || num_frames >= Some(i) {
232+
eprintln!("end of query stack");
233+
} else {
234+
eprintln!("we're just showing a limited slice of the query stack");
235+
}
236+
}

compiler/rustc_interface/src/passes.rs

+17-9
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use rustc_expand::base::ExtCtxt;
1515
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
1616
use rustc_hir::definitions::Definitions;
1717
use rustc_hir::Crate;
18+
use rustc_index::vec::IndexVec;
1819
use rustc_lint::LintStore;
1920
use rustc_middle::arena::Arena;
2021
use rustc_middle::dep_graph::DepGraph;
@@ -27,6 +28,7 @@ use rustc_mir_build as mir_build;
2728
use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str};
2829
use rustc_passes::{self, hir_stats, layout_test};
2930
use rustc_plugin_impl as plugin;
31+
use rustc_query_impl::Queries as TcxQueries;
3032
use rustc_resolve::{Resolver, ResolverArenas};
3133
use rustc_session::config::{CrateType, Input, OutputFilenames, OutputType, PpMode, PpSourceMode};
3234
use rustc_session::lint;
@@ -738,20 +740,18 @@ pub static DEFAULT_EXTERN_QUERY_PROVIDERS: SyncLazy<Providers> = SyncLazy::new(|
738740
extern_providers
739741
});
740742

741-
pub struct QueryContext<'tcx>(&'tcx GlobalCtxt<'tcx>);
743+
pub struct QueryContext<'tcx> {
744+
gcx: &'tcx GlobalCtxt<'tcx>,
745+
}
742746

743747
impl<'tcx> QueryContext<'tcx> {
744748
pub fn enter<F, R>(&mut self, f: F) -> R
745749
where
746750
F: FnOnce(TyCtxt<'tcx>) -> R,
747751
{
748-
let icx = ty::tls::ImplicitCtxt::new(self.0);
752+
let icx = ty::tls::ImplicitCtxt::new(self.gcx);
749753
ty::tls::enter_context(&icx, |_| f(icx.tcx))
750754
}
751-
752-
pub fn print_stats(&mut self) {
753-
self.enter(ty::query::print_stats)
754-
}
755755
}
756756

757757
pub fn create_global_ctxt<'tcx>(
@@ -762,6 +762,7 @@ pub fn create_global_ctxt<'tcx>(
762762
mut resolver_outputs: ResolverOutputs,
763763
outputs: OutputFilenames,
764764
crate_name: &str,
765+
queries: &'tcx OnceCell<TcxQueries<'tcx>>,
765766
global_ctxt: &'tcx OnceCell<GlobalCtxt<'tcx>>,
766767
arena: &'tcx WorkerLocal<Arena<'tcx>>,
767768
) -> QueryContext<'tcx> {
@@ -785,26 +786,33 @@ pub fn create_global_ctxt<'tcx>(
785786
callback(sess, &mut local_providers, &mut extern_providers);
786787
}
787788

789+
let queries = {
790+
let crates = resolver_outputs.cstore.crates_untracked();
791+
let max_cnum = crates.iter().map(|c| c.as_usize()).max().unwrap_or(0);
792+
let mut providers = IndexVec::from_elem_n(extern_providers, max_cnum + 1);
793+
providers[LOCAL_CRATE] = local_providers;
794+
queries.get_or_init(|| TcxQueries::new(providers, extern_providers))
795+
};
796+
788797
let gcx = sess.time("setup_global_ctxt", || {
789798
global_ctxt.get_or_init(|| {
790799
TyCtxt::create_global_ctxt(
791800
sess,
792801
lint_store,
793-
local_providers,
794-
extern_providers,
795802
arena,
796803
resolver_outputs,
797804
krate,
798805
defs,
799806
dep_graph,
800807
query_result_on_disk_cache,
808+
queries.as_dyn(),
801809
&crate_name,
802810
&outputs,
803811
)
804812
})
805813
});
806814

807-
QueryContext(gcx)
815+
QueryContext { gcx }
808816
}
809817

810818
/// Runs the resolution, type-checking, region checking and other

compiler/rustc_interface/src/queries.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use rustc_lint::LintStore;
1414
use rustc_middle::arena::Arena;
1515
use rustc_middle::dep_graph::DepGraph;
1616
use rustc_middle::ty::{GlobalCtxt, ResolverOutputs, TyCtxt};
17+
use rustc_query_impl::Queries as TcxQueries;
1718
use rustc_serialize::json;
1819
use rustc_session::config::{self, OutputFilenames, OutputType};
1920
use rustc_session::{output::find_crate_name, Session};
@@ -71,6 +72,7 @@ impl<T> Default for Query<T> {
7172
pub struct Queries<'tcx> {
7273
compiler: &'tcx Compiler,
7374
gcx: OnceCell<GlobalCtxt<'tcx>>,
75+
queries: OnceCell<TcxQueries<'tcx>>,
7476

7577
arena: WorkerLocal<Arena<'tcx>>,
7678
hir_arena: WorkerLocal<rustc_ast_lowering::Arena<'tcx>>,
@@ -92,6 +94,7 @@ impl<'tcx> Queries<'tcx> {
9294
Queries {
9395
compiler,
9496
gcx: OnceCell::new(),
97+
queries: OnceCell::new(),
9598
arena: WorkerLocal::new(|_| Arena::default()),
9699
hir_arena: WorkerLocal::new(|_| rustc_ast_lowering::Arena::default()),
97100
dep_graph_future: Default::default(),
@@ -265,6 +268,7 @@ impl<'tcx> Queries<'tcx> {
265268
resolver_outputs.steal(),
266269
outputs,
267270
&crate_name,
271+
&self.queries,
268272
&self.gcx,
269273
&self.arena,
270274
))
@@ -425,11 +429,11 @@ impl Compiler {
425429
{
426430
let _prof_timer =
427431
queries.session().prof.generic_activity("self_profile_alloc_query_strings");
428-
gcx.enter(|tcx| tcx.alloc_self_profile_query_strings());
432+
gcx.enter(rustc_query_impl::alloc_self_profile_query_strings);
429433
}
430434

431435
if self.session().opts.debugging_opts.query_stats {
432-
gcx.print_stats();
436+
gcx.enter(rustc_query_impl::print_stats);
433437
}
434438
}
435439

compiler/rustc_interface/src/util.rs

+28-4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ use rustc_data_structures::stable_hasher::StableHasher;
1010
use rustc_data_structures::sync::Lrc;
1111
use rustc_errors::registry::Registry;
1212
use rustc_metadata::dynamic_lib::DynamicLibrary;
13+
#[cfg(parallel_compiler)]
14+
use rustc_middle::ty::tls;
1315
use rustc_resolve::{self, Resolver};
1416
use rustc_session as session;
1517
use rustc_session::config::{self, CrateType};
@@ -29,11 +31,12 @@ use std::io;
2931
use std::lazy::SyncOnceCell;
3032
use std::mem;
3133
use std::ops::DerefMut;
34+
#[cfg(not(parallel_compiler))]
35+
use std::panic;
3236
use std::path::{Path, PathBuf};
3337
use std::sync::atomic::{AtomicBool, Ordering};
3438
use std::sync::{Arc, Mutex, Once};
35-
#[cfg(not(parallel_compiler))]
36-
use std::{panic, thread};
39+
use std::thread;
3740
use tracing::info;
3841

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

162+
/// Creates a new thread and forwards information in thread locals to it.
163+
/// The new thread runs the deadlock handler.
164+
/// Must only be called when a deadlock is about to happen.
165+
#[cfg(parallel_compiler)]
166+
unsafe fn handle_deadlock() {
167+
let registry = rustc_rayon_core::Registry::current();
168+
169+
let context = tls::get_tlv();
170+
assert!(context != 0);
171+
rustc_data_structures::sync::assert_sync::<tls::ImplicitCtxt<'_, '_>>();
172+
let icx: &tls::ImplicitCtxt<'_, '_> = &*(context as *const tls::ImplicitCtxt<'_, '_>);
173+
174+
let session_globals = rustc_span::SESSION_GLOBALS.with(|sg| sg as *const _);
175+
let session_globals = &*session_globals;
176+
thread::spawn(move || {
177+
tls::enter_context(icx, |_| {
178+
rustc_span::SESSION_GLOBALS
179+
.set(session_globals, || tls::with(|tcx| tcx.queries.deadlock(tcx, &registry)))
180+
});
181+
});
182+
}
183+
159184
#[cfg(parallel_compiler)]
160185
pub fn setup_callbacks_and_run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
161186
edition: Edition,
162187
threads: usize,
163188
stderr: &Option<Arc<Mutex<Vec<u8>>>>,
164189
f: F,
165190
) -> R {
166-
use rustc_middle::ty;
167191
crate::callbacks::setup_callbacks();
168192

169193
let mut config = rayon::ThreadPoolBuilder::new()
170194
.thread_name(|_| "rustc".to_string())
171195
.acquire_thread_handler(jobserver::acquire_thread)
172196
.release_thread_handler(jobserver::release_thread)
173197
.num_threads(threads)
174-
.deadlock_handler(|| unsafe { ty::query::handle_deadlock() });
198+
.deadlock_handler(|| unsafe { handle_deadlock() });
175199

176200
if let Some(size) = get_stack_size() {
177201
config = config.stack_size(size);

0 commit comments

Comments
 (0)