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

Query refactoring #107831

Merged
merged 4 commits into from
Feb 10, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
26 changes: 5 additions & 21 deletions compiler/rustc_interface/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -738,30 +738,16 @@ pub static DEFAULT_EXTERN_QUERY_PROVIDERS: LazyLock<ExternProviders> = LazyLock:
extern_providers
});

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.gcx);
ty::tls::enter_context(&icx, || f(icx.tcx))
}
}

pub fn create_global_ctxt<'tcx>(
compiler: &'tcx Compiler,
lint_store: Lrc<LintStore>,
dep_graph: DepGraph,
untracked: Untracked,
queries: &'tcx OnceCell<TcxQueries<'tcx>>,
global_ctxt: &'tcx OnceCell<GlobalCtxt<'tcx>>,
gcx_cell: &'tcx OnceCell<GlobalCtxt<'tcx>>,
arena: &'tcx WorkerLocal<Arena<'tcx>>,
hir_arena: &'tcx WorkerLocal<rustc_hir::Arena<'tcx>>,
) -> QueryContext<'tcx> {
) -> &'tcx GlobalCtxt<'tcx> {
// We're constructing the HIR here; we don't care what we will
// read, since we haven't even constructed the *input* to
// incr. comp. yet.
Expand All @@ -785,8 +771,8 @@ pub fn create_global_ctxt<'tcx>(
TcxQueries::new(local_providers, extern_providers, query_result_on_disk_cache)
});

let gcx = sess.time("setup_global_ctxt", || {
global_ctxt.get_or_init(move || {
sess.time("setup_global_ctxt", || {
gcx_cell.get_or_init(move || {
TyCtxt::create_global_ctxt(
sess,
lint_store,
Expand All @@ -799,9 +785,7 @@ pub fn create_global_ctxt<'tcx>(
rustc_query_impl::query_callbacks(arena),
)
})
});

QueryContext { gcx }
})
}

/// Runs the resolution, type-checking, region checking and other
Expand Down
27 changes: 14 additions & 13 deletions compiler/rustc_interface/src/queries.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::errors::{FailedWritingFile, RustcErrorFatal, RustcErrorUnexpectedAnnotation};
use crate::interface::{Compiler, Result};
use crate::passes::{self, BoxedResolver, QueryContext};
use crate::passes::{self, BoxedResolver};

use rustc_ast as ast;
use rustc_codegen_ssa::traits::CodegenBackend;
Expand Down Expand Up @@ -64,7 +64,7 @@ impl<'a, T> std::ops::DerefMut for QueryResult<'a, T> {
}
}

impl<'a, 'tcx> QueryResult<'a, QueryContext<'tcx>> {
impl<'a, 'tcx> QueryResult<'a, &'tcx GlobalCtxt<'tcx>> {
pub fn enter<T>(&mut self, f: impl FnOnce(TyCtxt<'tcx>) -> T) -> T {
(*self.0).get_mut().enter(f)
}
Expand All @@ -78,7 +78,7 @@ impl<T> Default for Query<T> {

pub struct Queries<'tcx> {
compiler: &'tcx Compiler,
gcx: OnceCell<GlobalCtxt<'tcx>>,
gcx_cell: OnceCell<GlobalCtxt<'tcx>>,
queries: OnceCell<TcxQueries<'tcx>>,

arena: WorkerLocal<Arena<'tcx>>,
Expand All @@ -90,15 +90,16 @@ pub struct Queries<'tcx> {
register_plugins: Query<(ast::Crate, Lrc<LintStore>)>,
expansion: Query<(Lrc<ast::Crate>, Rc<RefCell<BoxedResolver>>, Lrc<LintStore>)>,
dep_graph: Query<DepGraph>,
global_ctxt: Query<QueryContext<'tcx>>,
// This just points to what's in `gcx_cell`.
gcx: Query<&'tcx GlobalCtxt<'tcx>>,
ongoing_codegen: Query<Box<dyn Any>>,
}

impl<'tcx> Queries<'tcx> {
pub fn new(compiler: &'tcx Compiler) -> Queries<'tcx> {
Queries {
compiler,
gcx: OnceCell::new(),
gcx_cell: OnceCell::new(),
queries: OnceCell::new(),
arena: WorkerLocal::new(|_| Arena::default()),
hir_arena: WorkerLocal::new(|_| rustc_hir::Arena::default()),
Expand All @@ -108,7 +109,7 @@ impl<'tcx> Queries<'tcx> {
register_plugins: Default::default(),
expansion: Default::default(),
dep_graph: Default::default(),
global_ctxt: Default::default(),
gcx: Default::default(),
ongoing_codegen: Default::default(),
}
}
Expand Down Expand Up @@ -207,8 +208,8 @@ impl<'tcx> Queries<'tcx> {
})
}

pub fn global_ctxt(&'tcx self) -> Result<QueryResult<'_, QueryContext<'tcx>>> {
self.global_ctxt.compute(|| {
pub fn global_ctxt(&'tcx self) -> Result<QueryResult<'_, &'tcx GlobalCtxt<'tcx>>> {
self.gcx.compute(|| {
let crate_name = *self.crate_name()?.borrow();
let (krate, resolver, lint_store) = self.expansion()?.steal();

Expand All @@ -218,18 +219,18 @@ impl<'tcx> Queries<'tcx> {
ast_lowering: untracked_resolver_for_lowering,
} = BoxedResolver::to_resolver_outputs(resolver);

let mut qcx = passes::create_global_ctxt(
let gcx = passes::create_global_ctxt(
self.compiler,
lint_store,
self.dep_graph()?.steal(),
untracked,
&self.queries,
&self.gcx,
&self.gcx_cell,
&self.arena,
&self.hir_arena,
);

qcx.enter(|tcx| {
gcx.enter(|tcx| {
let feed = tcx.feed_unit_query();
feed.resolver_for_lowering(
tcx.arena.alloc(Steal::new((untracked_resolver_for_lowering, krate))),
Expand All @@ -239,7 +240,7 @@ impl<'tcx> Queries<'tcx> {
let feed = tcx.feed_local_crate();
feed.crate_name(crate_name);
});
Ok(qcx)
Ok(gcx)
})
}

Expand Down Expand Up @@ -387,7 +388,7 @@ impl Compiler {

// NOTE: intentionally does not compute the global context if it hasn't been built yet,
// since that likely means there was a parse error.
if let Some(Ok(gcx)) = &mut *queries.global_ctxt.result.borrow_mut() {
if let Some(Ok(gcx)) = &mut *queries.gcx.result.borrow_mut() {
let gcx = gcx.get_mut();
// We assume that no queries are run past here. If there are new queries
// after this point, they'll show up as "<unknown>" in self-profiling data.
Expand Down
12 changes: 12 additions & 0 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,18 @@ pub struct GlobalCtxt<'tcx> {
pub(crate) alloc_map: Lock<interpret::AllocMap<'tcx>>,
}

impl<'tcx> GlobalCtxt<'tcx> {
/// Installs `self` in a `TyCtxt` and `ImplicitCtxt` for the duration of
/// `f`.
pub fn enter<'a: 'tcx, F, R>(&'a self, f: F) -> R
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't be available outside rustc_interface as it cannot be accidentally called.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even before this PR, it's used in several other places: rustdoc, miri, etc. This grep output gives an idea:

compiler/rustc_driver_impl/src/lib.rs:                    queries.global_ctxt()?.enter(|tcx| {
compiler/rustc_driver_impl/src/lib.rs:            queries.global_ctxt()?.enter(|tcx| tcx.output_filenames(()));
compiler/rustc_driver_impl/src/lib.rs:            queries.global_ctxt()?.enter(|tcx| {
compiler/rustc_interface/src/queries.rs:            self.global_ctxt()?.enter(|tcx| {
compiler/rustc_interface/src/queries.rs:        let (crate_hash, prepare_outputs, dep_graph) = self.global_ctxt()?.enter(|tcx| {
src/librustdoc/doctest.rs:                let collector = queries.global_ctxt()?.enter(|tcx| {
src/tools/miri/src/bin/miri.rs:        queries.global_ctxt().unwrap().enter(|tcx| {
tests/run-make-fulldeps/obtain-borrowck/driver.rs:        queries.global_ctxt().unwrap().enter(|tcx| {
compiler/rustc_interface/src/queries.rs:            gcx.enter(|tcx| {
compiler/rustc_interface/src/queries.rs:                gcx.enter(rustc_query_impl::alloc_self_profile_query_strings);
compiler/rustc_interface/src/queries.rs:                .time("serialize_dep_graph", || gcx.enter(rustc_incremental::save_dep_graph));
src/librustdoc/lib.rs:            gcx.enter(|tcx| {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant to say the upstream compiler crates cannot call it. The downstream crates however must call it to initialize the GlobalCtxt pointer in the TLS state, before getting access to TyCtxt. The QueryContext structure ensures they do so.

where
F: FnOnce(TyCtxt<'tcx>) -> R,
{
let icx = tls::ImplicitCtxt::new(self);
tls::enter_context(&icx, || f(icx.tcx))
}
}

impl<'tcx> TyCtxt<'tcx> {
/// Expects a body and returns its codegen attributes.
///
Expand Down
4 changes: 2 additions & 2 deletions src/librustdoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -814,9 +814,9 @@ fn main_args(at_args: &[String]) -> MainResult {
sess.fatal("Compilation failed, aborting rustdoc");
}

let mut global_ctxt = abort_on_err(queries.global_ctxt(), sess);
let mut gcx = abort_on_err(queries.global_ctxt(), sess);

global_ctxt.enter(|tcx| {
gcx.enter(|tcx| {
let (krate, render_opts, mut cache) = sess.time("run_global_ctxt", || {
core::run_global_ctxt(
tcx,
Expand Down