Skip to content

Commit 8ba69d0

Browse files
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`
2 parents ff1636b + 332ae3b commit 8ba69d0

File tree

4 files changed

+50
-4
lines changed

4 files changed

+50
-4
lines changed

compiler/rustc_errors/src/json.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ impl Emitter for JsonEmitter {
129129
};
130130
let name = match record.section {
131131
TimingSection::Linking => "link",
132+
TimingSection::Codegen => "codegen",
132133
};
133134
let data = SectionTimestamp { name, event, timestamp: record.timestamp };
134135
let result = self.emit(EmitTyped::SectionTiming(data));

compiler/rustc_errors/src/timings.rs

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
use std::time::Instant;
22

3+
use rustc_data_structures::fx::FxHashSet;
4+
use rustc_data_structures::sync::Lock;
5+
36
use crate::DiagCtxtHandle;
47

58
/// A high-level section of the compilation process.
6-
#[derive(Copy, Clone, Debug)]
9+
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
710
pub enum TimingSection {
11+
/// Time spent doing codegen.
12+
Codegen,
813
/// Time spent linking.
914
Linking,
1015
}
@@ -36,23 +41,59 @@ pub struct TimingSectionHandler {
3641
/// Time when the compilation session started.
3742
/// If `None`, timing is disabled.
3843
origin: Option<Instant>,
44+
/// Sanity check to ensure that we open and close sections correctly.
45+
opened_sections: Lock<FxHashSet<TimingSection>>,
3946
}
4047

4148
impl TimingSectionHandler {
4249
pub fn new(enabled: bool) -> Self {
4350
let origin = if enabled { Some(Instant::now()) } else { None };
44-
Self { origin }
51+
Self { origin, opened_sections: Lock::new(FxHashSet::default()) }
4552
}
4653

4754
/// Returns a RAII guard that will immediately emit a start the provided section, and then emit
4855
/// its end when it is dropped.
49-
pub fn start_section<'a>(
56+
pub fn section_guard<'a>(
5057
&self,
5158
diag_ctxt: DiagCtxtHandle<'a>,
5259
section: TimingSection,
5360
) -> TimingSectionGuard<'a> {
61+
if self.is_enabled() && self.opened_sections.borrow().contains(&section) {
62+
diag_ctxt
63+
.bug(format!("Section `{section:?}` was started again before it was finished"));
64+
}
65+
5466
TimingSectionGuard::create(diag_ctxt, section, self.origin)
5567
}
68+
69+
/// Start the provided section.
70+
pub fn start_section(&self, diag_ctxt: DiagCtxtHandle<'_>, section: TimingSection) {
71+
if let Some(origin) = self.origin {
72+
let mut opened = self.opened_sections.borrow_mut();
73+
if !opened.insert(section) {
74+
diag_ctxt
75+
.bug(format!("Section `{section:?}` was started again before it was finished"));
76+
}
77+
78+
diag_ctxt.emit_timing_section_start(TimingRecord::from_origin(origin, section));
79+
}
80+
}
81+
82+
/// End the provided section.
83+
pub fn end_section(&self, diag_ctxt: DiagCtxtHandle<'_>, section: TimingSection) {
84+
if let Some(origin) = self.origin {
85+
let mut opened = self.opened_sections.borrow_mut();
86+
if !opened.remove(&section) {
87+
diag_ctxt.bug(format!("Section `{section:?}` was ended before being started"));
88+
}
89+
90+
diag_ctxt.emit_timing_section_end(TimingRecord::from_origin(origin, section));
91+
}
92+
}
93+
94+
fn is_enabled(&self) -> bool {
95+
self.origin.is_some()
96+
}
5697
}
5798

5899
/// RAII wrapper for starting and ending section timings.

compiler/rustc_interface/src/passes.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use rustc_data_structures::jobserver::Proxy;
1111
use rustc_data_structures::steal::Steal;
1212
use rustc_data_structures::sync::{AppendOnlyIndexVec, FreezeLock, WorkerLocal};
1313
use rustc_data_structures::{parallel, thousands};
14+
use rustc_errors::timings::TimingSection;
1415
use rustc_expand::base::{ExtCtxt, LintStoreExpand};
1516
use rustc_feature::Features;
1617
use rustc_fs_util::try_canonicalize;
@@ -1176,6 +1177,8 @@ pub(crate) fn start_codegen<'tcx>(
11761177
codegen_backend: &dyn CodegenBackend,
11771178
tcx: TyCtxt<'tcx>,
11781179
) -> (Box<dyn Any>, EncodedMetadata) {
1180+
tcx.sess.timings.start_section(tcx.sess.dcx(), TimingSection::Codegen);
1181+
11791182
// Hook for tests.
11801183
if let Some((def_id, _)) = tcx.entry_fn(())
11811184
&& tcx.has_attr(def_id, sym::rustc_delayed_bug_from_inside_query)

compiler/rustc_interface/src/queries.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ impl Linker {
4848
let (codegen_results, work_products) = sess.time("finish_ongoing_codegen", || {
4949
codegen_backend.join_codegen(self.ongoing_codegen, sess, &self.output_filenames)
5050
});
51+
sess.timings.end_section(sess.dcx(), TimingSection::Codegen);
5152

5253
sess.dcx().abort_if_errors();
5354

@@ -89,7 +90,7 @@ impl Linker {
8990
}
9091

9192
let _timer = sess.prof.verbose_generic_activity("link_crate");
92-
let _timing = sess.timings.start_section(sess.dcx(), TimingSection::Linking);
93+
let _timing = sess.timings.section_guard(sess.dcx(), TimingSection::Linking);
9394
codegen_backend.link(sess, codegen_results, self.metadata, &self.output_filenames)
9495
}
9596
}

0 commit comments

Comments
 (0)