Skip to content

Add codegen timing section #142784

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
1 change: 1 addition & 0 deletions compiler/rustc_errors/src/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,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));
Expand Down
49 changes: 46 additions & 3 deletions compiler/rustc_errors/src/timings.rs
Original file line number Diff line number Diff line change
@@ -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,
}
Expand Down Expand Up @@ -36,23 +41,61 @@ 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(&section) {
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.contains(&section) {
diag_ctxt
.bug(format!("Section `{section:?}` was started again before it was finished"));
} else {
opened.insert(section);
}

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(&section) {
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.
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_interface/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_interface/src/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -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)
}
}
Loading