diff options
| author | Jubilee <workingjubilee@gmail.com> | 2025-06-23 12:48:20 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-23 12:48:20 -0700 |
| commit | 8ba69d0f95fa75763fde16fce6cb6388326edf9d (patch) | |
| tree | ab2f501c5b660d8681245c5153c673814bb6c4bf | |
| parent | ff1636b6e3fb685f43b17be8a12905203c8717da (diff) | |
| parent | 332ae3b7e632eb23c39b9844f44e2f9e7409e622 (diff) | |
| download | rust-8ba69d0f95fa75763fde16fce6cb6388326edf9d.tar.gz rust-8ba69d0f95fa75763fde16fce6cb6388326edf9d.zip | |
Rollup merge of #142784 - Kobzol:timings-codegen, r=nnethercote
Add codegen timing section And since we now start and end the sections also using separate functions, also add some light checking if we're generating the sections correctly. I'm integrating `--timings` into Cargo, and I realized that the codegen timings would be quite useful for that. Frontend can be computed simply as `[start of compilation, start of codegen]` for now. r? `@nnethercote`
| -rw-r--r-- | compiler/rustc_errors/src/json.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/timings.rs | 47 | ||||
| -rw-r--r-- | compiler/rustc_interface/src/passes.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_interface/src/queries.rs | 3 |
4 files changed, 50 insertions, 4 deletions
diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index 6d600f896a0..4348610be0a 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -129,6 +129,7 @@ impl Emitter for JsonEmitter { }; let name = match record.section { TimingSection::Linking => "link", + TimingSection::Codegen => "codegen", }; let data = SectionTimestamp { name, event, timestamp: record.timestamp }; let result = self.emit(EmitTyped::SectionTiming(data)); diff --git a/compiler/rustc_errors/src/timings.rs b/compiler/rustc_errors/src/timings.rs index 27fc9df8d79..0d82f3e8db8 100644 --- a/compiler/rustc_errors/src/timings.rs +++ b/compiler/rustc_errors/src/timings.rs @@ -1,10 +1,15 @@ use std::time::Instant; +use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::sync::Lock; + use crate::DiagCtxtHandle; /// A high-level section of the compilation process. -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub enum TimingSection { + /// Time spent doing codegen. + Codegen, /// Time spent linking. Linking, } @@ -36,23 +41,59 @@ pub struct TimingSectionHandler { /// Time when the compilation session started. /// If `None`, timing is disabled. origin: Option<Instant>, + /// Sanity check to ensure that we open and close sections correctly. + opened_sections: Lock<FxHashSet<TimingSection>>, } impl TimingSectionHandler { pub fn new(enabled: bool) -> Self { let origin = if enabled { Some(Instant::now()) } else { None }; - Self { origin } + Self { origin, opened_sections: Lock::new(FxHashSet::default()) } } /// Returns a RAII guard that will immediately emit a start the provided section, and then emit /// its end when it is dropped. - pub fn start_section<'a>( + pub fn section_guard<'a>( &self, diag_ctxt: DiagCtxtHandle<'a>, section: TimingSection, ) -> TimingSectionGuard<'a> { + if self.is_enabled() && self.opened_sections.borrow().contains(§ion) { + diag_ctxt + .bug(format!("Section `{section:?}` was started again before it was finished")); + } + TimingSectionGuard::create(diag_ctxt, section, self.origin) } + + /// Start the provided section. + pub fn start_section(&self, diag_ctxt: DiagCtxtHandle<'_>, section: TimingSection) { + if let Some(origin) = self.origin { + let mut opened = self.opened_sections.borrow_mut(); + if !opened.insert(section) { + diag_ctxt + .bug(format!("Section `{section:?}` was started again before it was finished")); + } + + diag_ctxt.emit_timing_section_start(TimingRecord::from_origin(origin, section)); + } + } + + /// End the provided section. + pub fn end_section(&self, diag_ctxt: DiagCtxtHandle<'_>, section: TimingSection) { + if let Some(origin) = self.origin { + let mut opened = self.opened_sections.borrow_mut(); + if !opened.remove(§ion) { + diag_ctxt.bug(format!("Section `{section:?}` was ended before being started")); + } + + diag_ctxt.emit_timing_section_end(TimingRecord::from_origin(origin, section)); + } + } + + fn is_enabled(&self) -> bool { + self.origin.is_some() + } } /// RAII wrapper for starting and ending section timings. diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 201b7e2b940..0b9facfc7af 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -11,6 +11,7 @@ use rustc_data_structures::jobserver::Proxy; use rustc_data_structures::steal::Steal; use rustc_data_structures::sync::{AppendOnlyIndexVec, FreezeLock, WorkerLocal}; use rustc_data_structures::{parallel, thousands}; +use rustc_errors::timings::TimingSection; use rustc_expand::base::{ExtCtxt, LintStoreExpand}; use rustc_feature::Features; use rustc_fs_util::try_canonicalize; @@ -1176,6 +1177,8 @@ pub(crate) fn start_codegen<'tcx>( codegen_backend: &dyn CodegenBackend, tcx: TyCtxt<'tcx>, ) -> (Box<dyn Any>, EncodedMetadata) { + tcx.sess.timings.start_section(tcx.sess.dcx(), TimingSection::Codegen); + // Hook for tests. if let Some((def_id, _)) = tcx.entry_fn(()) && tcx.has_attr(def_id, sym::rustc_delayed_bug_from_inside_query) diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 877440ec7d2..2bc30fa7cb0 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -48,6 +48,7 @@ impl Linker { let (codegen_results, work_products) = sess.time("finish_ongoing_codegen", || { codegen_backend.join_codegen(self.ongoing_codegen, sess, &self.output_filenames) }); + sess.timings.end_section(sess.dcx(), TimingSection::Codegen); sess.dcx().abort_if_errors(); @@ -89,7 +90,7 @@ impl Linker { } let _timer = sess.prof.verbose_generic_activity("link_crate"); - let _timing = sess.timings.start_section(sess.dcx(), TimingSection::Linking); + let _timing = sess.timings.section_guard(sess.dcx(), TimingSection::Linking); codegen_backend.link(sess, codegen_results, self.metadata, &self.output_filenames) } } |
