From 8e9bbc899c7a1913ff04d9af516efee900aeffd1 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 31 Oct 2024 14:23:38 +0000 Subject: [PATCH] Move some code from Compiler::enter to GlobalCtxt::finish --- compiler/rustc_incremental/src/lib.rs | 11 +++++-- compiler/rustc_incremental/src/persist/mod.rs | 3 +- .../rustc_incremental/src/persist/save.rs | 2 +- compiler/rustc_interface/src/passes.rs | 2 ++ compiler/rustc_interface/src/queries.rs | 30 ++++--------------- compiler/rustc_middle/messages.ftl | 3 ++ compiler/rustc_middle/src/error.rs | 11 +++++-- compiler/rustc_middle/src/hooks/mod.rs | 13 ++++++++ compiler/rustc_middle/src/ty/context.rs | 13 ++++++-- compiler/rustc_query_impl/src/lib.rs | 6 ++++ .../rustc_query_impl/src/profiling_support.rs | 2 ++ 11 files changed, 64 insertions(+), 32 deletions(-) diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs index e8735cba9bd..6dab6468870 100644 --- a/compiler/rustc_incremental/src/lib.rs +++ b/compiler/rustc_incremental/src/lib.rs @@ -16,8 +16,15 @@ mod persist; pub use persist::{ LoadResult, copy_cgu_workproduct_to_incr_comp_cache_dir, finalize_session_directory, - in_incr_comp_dir, in_incr_comp_dir_sess, load_query_result_cache, save_dep_graph, - save_work_product_index, setup_dep_graph, + in_incr_comp_dir, in_incr_comp_dir_sess, load_query_result_cache, save_work_product_index, + setup_dep_graph, }; +use rustc_middle::util::Providers; + +#[allow(missing_docs)] +pub fn provide(providers: &mut Providers) { + providers.hooks.save_dep_graph = + |tcx| tcx.sess.time("serialize_dep_graph", || persist::save_dep_graph(tcx.tcx)); +} rustc_fluent_macro::fluent_messages! { "../messages.ftl" } diff --git a/compiler/rustc_incremental/src/persist/mod.rs b/compiler/rustc_incremental/src/persist/mod.rs index 186db0a60a3..f5d5167e0e2 100644 --- a/compiler/rustc_incremental/src/persist/mod.rs +++ b/compiler/rustc_incremental/src/persist/mod.rs @@ -12,5 +12,6 @@ mod work_product; pub use fs::{finalize_session_directory, in_incr_comp_dir, in_incr_comp_dir_sess}; pub use load::{LoadResult, load_query_result_cache, setup_dep_graph}; -pub use save::{save_dep_graph, save_work_product_index}; +pub(crate) use save::save_dep_graph; +pub use save::save_work_product_index; pub use work_product::copy_cgu_workproduct_to_incr_comp_cache_dir; diff --git a/compiler/rustc_incremental/src/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs index 53726df4597..8fc50ca1b43 100644 --- a/compiler/rustc_incremental/src/persist/save.rs +++ b/compiler/rustc_incremental/src/persist/save.rs @@ -25,7 +25,7 @@ use crate::errors; /// /// This function should only run after all queries have completed. /// Trying to execute a query afterwards would attempt to read the result cache we just dropped. -pub fn save_dep_graph(tcx: TyCtxt<'_>) { +pub(crate) fn save_dep_graph(tcx: TyCtxt<'_>) { debug!("save_dep_graph()"); tcx.dep_graph.with_ignore(|| { let sess = tcx.sess; diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index fd850d2f39a..3d3f1d23a60 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -704,10 +704,12 @@ pub static DEFAULT_QUERY_PROVIDERS: LazyLock = LazyLock::new(|| { rustc_const_eval::provide(providers); rustc_middle::hir::provide(providers); rustc_borrowck::provide(providers); + rustc_incremental::provide(providers); rustc_mir_build::provide(providers); rustc_mir_transform::provide(providers); rustc_monomorphize::provide(providers); rustc_privacy::provide(providers); + rustc_query_impl::provide(providers); rustc_resolve::provide(providers); rustc_hir_analysis::provide(providers); rustc_hir_typeck::provide(providers); diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index ff8cf790ef8..cd3a2fb7049 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -12,13 +12,12 @@ use rustc_hir::def_id::LOCAL_CRATE; use rustc_middle::arena::Arena; use rustc_middle::dep_graph::DepGraph; use rustc_middle::ty::{GlobalCtxt, TyCtxt}; -use rustc_serialize::opaque::FileEncodeResult; use rustc_session::Session; use rustc_session::config::{self, OutputFilenames, OutputType}; use crate::errors::FailedWritingFile; use crate::interface::{Compiler, Result}; -use crate::{errors, passes}; +use crate::passes; /// Represent the result of a query. /// @@ -90,8 +89,10 @@ impl<'tcx> Queries<'tcx> { } } - pub fn finish(&self) -> FileEncodeResult { - if let Some(gcx) = self.gcx_cell.get() { gcx.finish() } else { Ok(0) } + pub fn finish(&'tcx self) { + if let Some(gcx) = self.gcx_cell.get() { + gcx.finish(); + } } pub fn parse(&self) -> Result> { @@ -209,29 +210,10 @@ impl Compiler { let queries = Queries::new(self); let ret = f(&queries); - // 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.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 "" in self-profiling data. - { - let _prof_timer = - queries.compiler.sess.prof.generic_activity("self_profile_alloc_query_strings"); - gcx.enter(rustc_query_impl::alloc_self_profile_query_strings); - } - - self.sess.time("serialize_dep_graph", || gcx.enter(rustc_incremental::save_dep_graph)); - - gcx.enter(rustc_query_impl::query_key_hash_verify_all); - } - // The timer's lifetime spans the dropping of `queries`, which contains // the global context. _timer = self.sess.timer("free_global_ctxt"); - if let Err((path, error)) = queries.finish() { - self.sess.dcx().emit_fatal(errors::FailedWritingFile { path: &path, error }); - } + queries.finish(); ret } diff --git a/compiler/rustc_middle/messages.ftl b/compiler/rustc_middle/messages.ftl index 52c3212ab80..5dd85978f00 100644 --- a/compiler/rustc_middle/messages.ftl +++ b/compiler/rustc_middle/messages.ftl @@ -73,6 +73,9 @@ middle_drop_check_overflow = middle_erroneous_constant = erroneous constant encountered +middle_failed_writing_file = + failed to write file {$path}: {$error}" + middle_layout_references_error = the type has an unknown layout diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs index 5c2aa0005d4..6300d856393 100644 --- a/compiler/rustc_middle/src/error.rs +++ b/compiler/rustc_middle/src/error.rs @@ -1,5 +1,5 @@ -use std::fmt; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; +use std::{fmt, io}; use rustc_errors::codes::*; use rustc_errors::{DiagArgName, DiagArgValue, DiagMessage}; @@ -18,6 +18,13 @@ pub struct DropCheckOverflow<'tcx> { pub overflow_ty: Ty<'tcx>, } +#[derive(Diagnostic)] +#[diag(middle_failed_writing_file)] +pub struct FailedWritingFile<'a> { + pub path: &'a Path, + pub error: io::Error, +} + #[derive(Diagnostic)] #[diag(middle_opaque_hidden_type_mismatch)] pub struct OpaqueHiddenTypeMismatch<'tcx> { diff --git a/compiler/rustc_middle/src/hooks/mod.rs b/compiler/rustc_middle/src/hooks/mod.rs index 742797fdeef..92fa64b0987 100644 --- a/compiler/rustc_middle/src/hooks/mod.rs +++ b/compiler/rustc_middle/src/hooks/mod.rs @@ -108,6 +108,19 @@ declare_hooks! { /// Returns `true` if we should codegen an instance in the local crate, or returns `false` if we /// can just link to the upstream crate and therefore don't need a mono item. hook should_codegen_locally(instance: crate::ty::Instance<'tcx>) -> bool; + + hook alloc_self_profile_query_strings() -> (); + + /// Saves and writes the DepGraph to the file system. + /// + /// This function saves both the dep-graph and the query result cache, + /// and drops the result cache. + /// + /// This function should only run after all queries have completed. + /// Trying to execute a query afterwards would attempt to read the result cache we just dropped. + hook save_dep_graph() -> (); + + hook query_key_hash_verify_all() -> (); } #[cold] diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index c55733da7b3..e1a360a1b1e 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1365,8 +1365,17 @@ impl<'tcx> GlobalCtxt<'tcx> { tls::enter_context(&icx, || f(icx.tcx)) } - pub fn finish(&self) -> FileEncodeResult { - self.dep_graph.finish_encoding() + pub fn finish(&'tcx self) { + // We assume that no queries are run past here. If there are new queries + // after this point, they'll show up as "" in self-profiling data. + self.enter(|tcx| tcx.alloc_self_profile_query_strings()); + + self.enter(|tcx| tcx.save_dep_graph()); + self.enter(|tcx| tcx.query_key_hash_verify_all()); + + if let Err((path, error)) = self.dep_graph.finish_encoding() { + self.sess.dcx().emit_fatal(crate::error::FailedWritingFile { path: &path, error }); + } } } diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index df898e0587f..a1917fed4d9 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -222,3 +222,9 @@ pub fn query_system<'tcx>( } rustc_middle::rustc_query_append! { define_queries! } + +pub fn provide(providers: &mut rustc_middle::util::Providers) { + providers.hooks.alloc_self_profile_query_strings = + |tcx| alloc_self_profile_query_strings(tcx.tcx); + providers.hooks.query_key_hash_verify_all = |tcx| query_key_hash_verify_all(tcx.tcx); +} diff --git a/compiler/rustc_query_impl/src/profiling_support.rs b/compiler/rustc_query_impl/src/profiling_support.rs index 5f989b264aa..7d80e54bf87 100644 --- a/compiler/rustc_query_impl/src/profiling_support.rs +++ b/compiler/rustc_query_impl/src/profiling_support.rs @@ -252,6 +252,8 @@ pub fn alloc_self_profile_query_strings(tcx: TyCtxt<'_>) { return; } + let _prof_timer = tcx.sess.prof.generic_activity("self_profile_alloc_query_strings"); + let mut string_cache = QueryKeyStringCache::new(); for alloc in super::ALLOC_SELF_PROFILE_QUERY_STRINGS.iter() {