From f60d2eb6c19751154a2c752d1c916420c0bb60e6 Mon Sep 17 00:00:00 2001 From: John Kåre Alsaker Date: Mon, 6 Feb 2023 06:32:34 +0100 Subject: Add `-Z time-passes-format` to allow specifying a JSON output for `-Z time-passes` --- .../rustc_data_structures/src/graph/scc/tests.rs | 6 +- .../src/graph/vec_graph/tests.rs | 6 +- compiler/rustc_data_structures/src/profiling.rs | 72 ++++++++++++++++++---- 3 files changed, 65 insertions(+), 19 deletions(-) (limited to 'compiler/rustc_data_structures/src') diff --git a/compiler/rustc_data_structures/src/graph/scc/tests.rs b/compiler/rustc_data_structures/src/graph/scc/tests.rs index 820a70fc8e4..513df666d0d 100644 --- a/compiler/rustc_data_structures/src/graph/scc/tests.rs +++ b/compiler/rustc_data_structures/src/graph/scc/tests.rs @@ -56,7 +56,7 @@ fn test_three_sccs() { assert_eq!(sccs.scc(1), 0); assert_eq!(sccs.scc(2), 0); assert_eq!(sccs.scc(3), 2); - assert_eq!(sccs.successors(0), &[]); + assert_eq!(sccs.successors(0), &[] as &[usize]); assert_eq!(sccs.successors(1), &[0]); assert_eq!(sccs.successors(2), &[0]); } @@ -113,7 +113,7 @@ fn test_find_state_2() { assert_eq!(sccs.scc(2), 0); assert_eq!(sccs.scc(3), 0); assert_eq!(sccs.scc(4), 0); - assert_eq!(sccs.successors(0), &[]); + assert_eq!(sccs.successors(0), &[] as &[usize]); } #[test] @@ -138,7 +138,7 @@ fn test_find_state_3() { assert_eq!(sccs.scc(3), 0); assert_eq!(sccs.scc(4), 0); assert_eq!(sccs.scc(5), 1); - assert_eq!(sccs.successors(0), &[]); + assert_eq!(sccs.successors(0), &[] as &[usize]); assert_eq!(sccs.successors(1), &[0]); } diff --git a/compiler/rustc_data_structures/src/graph/vec_graph/tests.rs b/compiler/rustc_data_structures/src/graph/vec_graph/tests.rs index c8f97926717..7c866da6009 100644 --- a/compiler/rustc_data_structures/src/graph/vec_graph/tests.rs +++ b/compiler/rustc_data_structures/src/graph/vec_graph/tests.rs @@ -27,11 +27,11 @@ fn successors() { let graph = create_graph(); assert_eq!(graph.successors(0), &[1]); assert_eq!(graph.successors(1), &[2, 3]); - assert_eq!(graph.successors(2), &[]); + assert_eq!(graph.successors(2), &[] as &[usize]); assert_eq!(graph.successors(3), &[4]); - assert_eq!(graph.successors(4), &[]); + assert_eq!(graph.successors(4), &[] as &[usize]); assert_eq!(graph.successors(5), &[1]); - assert_eq!(graph.successors(6), &[]); + assert_eq!(graph.successors(6), &[] as &[usize]); } #[test] diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs index 3d9c7f6eae2..87b74903d51 100644 --- a/compiler/rustc_data_structures/src/profiling.rs +++ b/compiler/rustc_data_structures/src/profiling.rs @@ -97,6 +97,7 @@ use std::time::{Duration, Instant}; pub use measureme::EventId; use measureme::{EventIdBuilder, Profiler, SerializableString, StringId}; use parking_lot::RwLock; +use serde_json::json; use smallvec::SmallVec; bitflags::bitflags! { @@ -145,6 +146,15 @@ const EVENT_FILTERS_BY_NAME: &[(&str, EventFilter)] = &[ /// Something that uniquely identifies a query invocation. pub struct QueryInvocationId(pub u32); +/// Which format to use for `-Z time-passes` +#[derive(Clone, Copy, PartialEq, Hash, Debug)] +pub enum TimePassesFormat { + /// Emit human readable text + Text, + /// Emit structured JSON + Json, +} + /// A reference to the SelfProfiler. It can be cloned and sent across thread /// boundaries at will. #[derive(Clone)] @@ -158,14 +168,14 @@ pub struct SelfProfilerRef { // actually enabled. event_filter_mask: EventFilter, - // Print verbose generic activities to stderr? - print_verbose_generic_activities: bool, + // Print verbose generic activities to stderr. + print_verbose_generic_activities: Option, } impl SelfProfilerRef { pub fn new( profiler: Option>, - print_verbose_generic_activities: bool, + print_verbose_generic_activities: Option, ) -> SelfProfilerRef { // If there is no SelfProfiler then the filter mask is set to NONE, // ensuring that nothing ever tries to actually access it. @@ -207,9 +217,10 @@ impl SelfProfilerRef { /// a measureme event, "verbose" generic activities also print a timing entry to /// stderr if the compiler is invoked with -Ztime-passes. pub fn verbose_generic_activity(&self, event_label: &'static str) -> VerboseTimingGuard<'_> { - let message = self.print_verbose_generic_activities.then(|| event_label.to_owned()); + let message_and_format = + self.print_verbose_generic_activities.map(|format| (event_label.to_owned(), format)); - VerboseTimingGuard::start(message, self.generic_activity(event_label)) + VerboseTimingGuard::start(message_and_format, self.generic_activity(event_label), false) } /// Like `verbose_generic_activity`, but with an extra arg. @@ -221,11 +232,26 @@ impl SelfProfilerRef { where A: Borrow + Into, { - let message = self + let message_and_format = self .print_verbose_generic_activities - .then(|| format!("{}({})", event_label, event_arg.borrow())); + .map(|format| (format!("{}({})", event_label, event_arg.borrow()), format)); - VerboseTimingGuard::start(message, self.generic_activity_with_arg(event_label, event_arg)) + VerboseTimingGuard::start( + message_and_format, + self.generic_activity_with_arg(event_label, event_arg), + false, + ) + } + + /// Like `verbose_generic_activity`, but `event_label` must be unique for a rustc session. + pub fn unique_verbose_generic_activity( + &self, + event_label: &'static str, + ) -> VerboseTimingGuard<'_> { + let message_and_format = + self.print_verbose_generic_activities.map(|format| (event_label.to_owned(), format)); + + VerboseTimingGuard::start(message_and_format, self.generic_activity(event_label), true) } /// Start profiling a generic activity. Profiling continues until the @@ -705,15 +731,21 @@ impl<'a> TimingGuard<'a> { #[must_use] pub struct VerboseTimingGuard<'a> { - start_and_message: Option<(Instant, Option, String)>, + start_and_message: Option<(Instant, Option, String, TimePassesFormat, bool)>, _guard: TimingGuard<'a>, } impl<'a> VerboseTimingGuard<'a> { - pub fn start(message: Option, _guard: TimingGuard<'a>) -> Self { + pub fn start( + message_and_format: Option<(String, TimePassesFormat)>, + _guard: TimingGuard<'a>, + unique: bool, + ) -> Self { VerboseTimingGuard { _guard, - start_and_message: message.map(|msg| (Instant::now(), get_resident_set_size(), msg)), + start_and_message: message_and_format.map(|(msg, format)| { + (Instant::now(), get_resident_set_size(), msg, format, unique) + }), } } @@ -726,10 +758,10 @@ impl<'a> VerboseTimingGuard<'a> { impl Drop for VerboseTimingGuard<'_> { fn drop(&mut self) { - if let Some((start_time, start_rss, ref message)) = self.start_and_message { + if let Some((start_time, start_rss, ref message, format, unique)) = self.start_and_message { let end_rss = get_resident_set_size(); let dur = start_time.elapsed(); - print_time_passes_entry(message, dur, start_rss, end_rss); + print_time_passes_entry(message, dur, start_rss, end_rss, format, unique); } } } @@ -739,7 +771,21 @@ pub fn print_time_passes_entry( dur: Duration, start_rss: Option, end_rss: Option, + format: TimePassesFormat, + unique: bool, ) { + if format == TimePassesFormat::Json { + let json = json!({ + "pass": what, + "time": dur.as_secs_f64(), + "rss_start": start_rss, + "rss_end": end_rss, + "unique": unique, + }); + eprintln!("time: {}", json.to_string()); + return; + } + // Print the pass if its duration is greater than 5 ms, or it changed the // measured RSS. let is_notable = || { -- cgit 1.4.1-3-g733a5 From 6c57dda44d2c9c12fdaab359c28767e4ccdb671b Mon Sep 17 00:00:00 2001 From: John Kåre Alsaker Date: Tue, 21 Mar 2023 18:41:45 +0100 Subject: Remove `unique` and move `VerboseTimingGuard` fields into a new struct --- compiler/rustc_codegen_ssa/src/base.rs | 1 - compiler/rustc_data_structures/src/profiling.rs | 60 ++++++++++++------------- compiler/rustc_driver_impl/src/lib.rs | 2 +- compiler/rustc_session/src/utils.rs | 4 +- 4 files changed, 32 insertions(+), 35 deletions(-) (limited to 'compiler/rustc_data_structures/src') diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index a109633520a..24a83ac546f 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -787,7 +787,6 @@ pub fn codegen_crate( start_rss.unwrap(), end_rss, tcx.sess.opts.unstable_opts.time_passes_format, - true, ); } diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs index 87b74903d51..58a0609e296 100644 --- a/compiler/rustc_data_structures/src/profiling.rs +++ b/compiler/rustc_data_structures/src/profiling.rs @@ -220,7 +220,7 @@ impl SelfProfilerRef { let message_and_format = self.print_verbose_generic_activities.map(|format| (event_label.to_owned(), format)); - VerboseTimingGuard::start(message_and_format, self.generic_activity(event_label), false) + VerboseTimingGuard::start(message_and_format, self.generic_activity(event_label)) } /// Like `verbose_generic_activity`, but with an extra arg. @@ -239,21 +239,9 @@ impl SelfProfilerRef { VerboseTimingGuard::start( message_and_format, self.generic_activity_with_arg(event_label, event_arg), - false, ) } - /// Like `verbose_generic_activity`, but `event_label` must be unique for a rustc session. - pub fn unique_verbose_generic_activity( - &self, - event_label: &'static str, - ) -> VerboseTimingGuard<'_> { - let message_and_format = - self.print_verbose_generic_activities.map(|format| (event_label.to_owned(), format)); - - VerboseTimingGuard::start(message_and_format, self.generic_activity(event_label), true) - } - /// Start profiling a generic activity. Profiling continues until the /// TimingGuard returned from this call is dropped. #[inline(always)] @@ -729,9 +717,16 @@ impl<'a> TimingGuard<'a> { } } +struct VerboseInfo { + start_time: Instant, + start_rss: Option, + message: String, + format: TimePassesFormat, +} + #[must_use] pub struct VerboseTimingGuard<'a> { - start_and_message: Option<(Instant, Option, String, TimePassesFormat, bool)>, + info: Option, _guard: TimingGuard<'a>, } @@ -739,12 +734,14 @@ impl<'a> VerboseTimingGuard<'a> { pub fn start( message_and_format: Option<(String, TimePassesFormat)>, _guard: TimingGuard<'a>, - unique: bool, ) -> Self { VerboseTimingGuard { _guard, - start_and_message: message_and_format.map(|(msg, format)| { - (Instant::now(), get_resident_set_size(), msg, format, unique) + info: message_and_format.map(|(message, format)| VerboseInfo { + start_time: Instant::now(), + start_rss: get_resident_set_size(), + message, + format, }), } } @@ -758,10 +755,10 @@ impl<'a> VerboseTimingGuard<'a> { impl Drop for VerboseTimingGuard<'_> { fn drop(&mut self) { - if let Some((start_time, start_rss, ref message, format, unique)) = self.start_and_message { + if let Some(info) = &self.info { let end_rss = get_resident_set_size(); - let dur = start_time.elapsed(); - print_time_passes_entry(message, dur, start_rss, end_rss, format, unique); + let dur = info.start_time.elapsed(); + print_time_passes_entry(&info.message, dur, info.start_rss, end_rss, info.format); } } } @@ -772,18 +769,19 @@ pub fn print_time_passes_entry( start_rss: Option, end_rss: Option, format: TimePassesFormat, - unique: bool, ) { - if format == TimePassesFormat::Json { - let json = json!({ - "pass": what, - "time": dur.as_secs_f64(), - "rss_start": start_rss, - "rss_end": end_rss, - "unique": unique, - }); - eprintln!("time: {}", json.to_string()); - return; + match format { + TimePassesFormat::Json => { + let json = json!({ + "pass": what, + "time": dur.as_secs_f64(), + "rss_start": start_rss, + "rss_end": end_rss, + }); + eprintln!("time: {}", json.to_string()); + return; + } + TimePassesFormat::Text => (), } // Print the pass if its duration is greater than 5 ms, or it changed the diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index d44bd7fdb18..ad2c2b13fed 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -1359,7 +1359,7 @@ pub fn main() -> ! { if let Some(format) = callbacks.time_passes { let end_rss = get_resident_set_size(); - print_time_passes_entry("total", start_time.elapsed(), start_rss, end_rss, format, true); + print_time_passes_entry("total", start_time.elapsed(), start_rss, end_rss, format); } process::exit(exit_code) diff --git a/compiler/rustc_session/src/utils.rs b/compiler/rustc_session/src/utils.rs index a7feb2794c4..3b3d4ca5d6b 100644 --- a/compiler/rustc_session/src/utils.rs +++ b/compiler/rustc_session/src/utils.rs @@ -4,10 +4,10 @@ use std::path::{Path, PathBuf}; impl Session { pub fn timer(&self, what: &'static str) -> VerboseTimingGuard<'_> { - self.prof.unique_verbose_generic_activity(what) + self.prof.verbose_generic_activity(what) } pub fn time(&self, what: &'static str, f: impl FnOnce() -> R) -> R { - self.prof.unique_verbose_generic_activity(what).run(f) + self.prof.verbose_generic_activity(what).run(f) } } -- cgit 1.4.1-3-g733a5