From f742d8832601080df1ae56c6469da18a917e1f60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sun, 10 Sep 2023 13:15:46 +0200 Subject: [PATCH 1/3] Remove `verbose_generic_activity_with_arg` --- .../rustc_codegen_cranelift/src/driver/aot.rs | 41 +++++++------------ compiler/rustc_codegen_llvm/src/back/lto.rs | 2 +- .../rustc_data_structures/src/profiling.rs | 19 --------- .../rustc_mir_transform/src/pass_manager.rs | 5 ++- compiler/rustc_query_impl/src/plumbing.rs | 3 +- 5 files changed, 21 insertions(+), 49 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs index d143bcc96ef93..3e93830951c5c 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs @@ -269,7 +269,7 @@ fn module_codegen( ), ) -> OngoingModuleCodegen { let (cgu_name, mut cx, mut module, codegened_functions) = - tcx.prof.verbose_generic_activity_with_arg("codegen cgu", cgu_name.as_str()).run(|| { + tcx.prof.generic_activity_with_arg("codegen cgu", cgu_name.as_str()).run(|| { let cgu = tcx.codegen_unit(cgu_name); let mono_items = cgu.items_in_deterministic_order(tcx); @@ -322,35 +322,24 @@ fn module_codegen( }); OngoingModuleCodegen::Async(std::thread::spawn(move || { - cx.profiler.clone().verbose_generic_activity_with_arg("compile functions", &*cgu_name).run( - || { - cranelift_codegen::timing::set_thread_profiler(Box::new(super::MeasuremeProfiler( - cx.profiler.clone(), - ))); - - let mut cached_context = Context::new(); - for codegened_func in codegened_functions { - crate::base::compile_fn( - &mut cx, - &mut cached_context, - &mut module, - codegened_func, - ); - } - }, - ); + cx.profiler.clone().generic_activity_with_arg("compile functions", &*cgu_name).run(|| { + cranelift_codegen::timing::set_thread_profiler(Box::new(super::MeasuremeProfiler( + cx.profiler.clone(), + ))); + + let mut cached_context = Context::new(); + for codegened_func in codegened_functions { + crate::base::compile_fn(&mut cx, &mut cached_context, &mut module, codegened_func); + } + }); - let global_asm_object_file = cx - .profiler - .verbose_generic_activity_with_arg("compile assembly", &*cgu_name) - .run(|| { + let global_asm_object_file = + cx.profiler.generic_activity_with_arg("compile assembly", &*cgu_name).run(|| { crate::global_asm::compile_global_asm(&global_asm_config, &cgu_name, &cx.global_asm) })?; - let codegen_result = cx - .profiler - .verbose_generic_activity_with_arg("write object file", &*cgu_name) - .run(|| { + let codegen_result = + cx.profiler.generic_activity_with_arg("write object file", &*cgu_name).run(|| { emit_cgu( &global_asm_config.output_filenames, &cx.profiler, diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index 5cf83b1accb16..ba263296bb454 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -605,7 +605,7 @@ pub(crate) fn run_pass_manager( module: &mut ModuleCodegen, thin: bool, ) -> Result<(), FatalError> { - let _timer = cgcx.prof.verbose_generic_activity_with_arg("LLVM_lto_optimize", &*module.name); + let _timer = cgcx.prof.generic_activity_with_arg("LLVM_lto_optimize", &*module.name); let config = cgcx.config(module.kind); // Now we have one massive module inside of llmod. Time to run the diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs index 3c76c2b79911a..321812fa93aec 100644 --- a/compiler/rustc_data_structures/src/profiling.rs +++ b/compiler/rustc_data_structures/src/profiling.rs @@ -223,25 +223,6 @@ impl SelfProfilerRef { VerboseTimingGuard::start(message_and_format, self.generic_activity(event_label)) } - /// Like `verbose_generic_activity`, but with an extra arg. - pub fn verbose_generic_activity_with_arg( - &self, - event_label: &'static str, - event_arg: A, - ) -> VerboseTimingGuard<'_> - where - A: Borrow + Into, - { - let message_and_format = self - .print_verbose_generic_activities - .map(|format| (format!("{}({})", event_label, event_arg.borrow()), format)); - - VerboseTimingGuard::start( - message_and_format, - self.generic_activity_with_arg(event_label, event_arg), - ) - } - /// Start profiling a generic activity. Profiling continues until the /// TimingGuard returned from this call is dropped. #[inline(always)] diff --git a/compiler/rustc_mir_transform/src/pass_manager.rs b/compiler/rustc_mir_transform/src/pass_manager.rs index 057f5fe82931b..0aba1bc968539 100644 --- a/compiler/rustc_mir_transform/src/pass_manager.rs +++ b/compiler/rustc_mir_transform/src/pass_manager.rs @@ -121,7 +121,10 @@ fn run_passes_inner<'tcx>( validate_body(tcx, body, format!("before pass {name}")); } - tcx.sess.time(name, || pass.run_pass(tcx, body)); + tcx.sess + .prof + .generic_activity_with_arg("mir_pass", name) + .run(|| pass.run_pass(tcx, body)); if dump_enabled { dump_mir_for_pass(tcx, body, &name, true); diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index a30ea7c1ddcaf..f2fdf066d15c9 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -348,8 +348,7 @@ pub(crate) fn encode_query_results<'a, 'tcx, Q>( Q: super::QueryConfigRestored<'tcx>, Q::RestoredValue: Encodable>, { - let _timer = - qcx.profiler().verbose_generic_activity_with_arg("encode_query_results_for", query.name()); + let _timer = qcx.profiler().generic_activity_with_arg("encode_query_results_for", query.name()); assert!(query.query_state(qcx).all_inactive()); let cache = query.query_cache(qcx); From 9624c30965d768527efd3ca5f52904fb5e763587 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 13 Sep 2023 13:05:15 +0200 Subject: [PATCH 2/3] Generate MIR pass names for profiling on the fly and pass the body DefId as argument --- compiler/rustc_middle/src/mir/mod.rs | 37 +++++++++++++++++++ .../rustc_mir_transform/src/pass_manager.rs | 14 +++++-- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index c78b1e0e2f44a..68163c6392d1d 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -25,6 +25,7 @@ use rustc_target::abi::{FieldIdx, Size, VariantIdx}; use polonius_engine::Atom; pub use rustc_ast::Mutability; +use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::graph::dominators::Dominators; use rustc_index::{Idx, IndexSlice, IndexVec}; @@ -35,6 +36,8 @@ use rustc_span::{Span, DUMMY_SP}; use either::Either; use std::borrow::Cow; +use std::cell::RefCell; +use std::collections::hash_map::Entry; use std::fmt::{self, Debug, Display, Formatter, Write}; use std::ops::{Index, IndexMut}; use std::{iter, mem}; @@ -97,6 +100,36 @@ impl<'tcx> HasLocalDecls<'tcx> for Body<'tcx> { } } +thread_local! { + static PASS_NAMES: RefCell> = { + RefCell::new(FxHashMap::default()) + }; +} + +/// Converts a MIR pass name into a snake case form to match the profiling naming style. +fn to_profiler_name(type_name: &'static str) -> &'static str { + PASS_NAMES.with(|names| match names.borrow_mut().entry(type_name) { + Entry::Occupied(e) => *e.get(), + Entry::Vacant(e) => { + let snake_case: String = type_name + .chars() + .flat_map(|c| { + if c.is_ascii_uppercase() { + vec!['_', c.to_ascii_lowercase()] + } else if c == '-' { + vec!['_'] + } else { + vec![c] + } + }) + .collect(); + let result = &*String::leak(format!("mir_pass{}", snake_case)); + e.insert(result); + result + } + }) +} + /// A streamlined trait that you can implement to create a pass; the /// pass will be named after the type, and it will consist of a main /// loop that goes over each available MIR and applies `run_pass`. @@ -106,6 +139,10 @@ pub trait MirPass<'tcx> { if let Some((_, tail)) = name.rsplit_once(':') { tail } else { name } } + fn profiler_name(&self) -> &'static str { + to_profiler_name(self.name()) + } + /// Returns `true` if this pass is enabled with the current combination of compiler flags. fn is_enabled(&self, _sess: &Session) -> bool { true diff --git a/compiler/rustc_mir_transform/src/pass_manager.rs b/compiler/rustc_mir_transform/src/pass_manager.rs index 0aba1bc968539..5abb2f3d0412a 100644 --- a/compiler/rustc_mir_transform/src/pass_manager.rs +++ b/compiler/rustc_mir_transform/src/pass_manager.rs @@ -94,6 +94,8 @@ fn run_passes_inner<'tcx>( let overridden_passes = &tcx.sess.opts.unstable_opts.mir_enable_passes; trace!(?overridden_passes); + let prof_arg = tcx.sess.prof.enabled().then(|| format!("{:?}", body.source.def_id())); + if !body.should_skip() { for pass in passes { let name = pass.name(); @@ -121,10 +123,14 @@ fn run_passes_inner<'tcx>( validate_body(tcx, body, format!("before pass {name}")); } - tcx.sess - .prof - .generic_activity_with_arg("mir_pass", name) - .run(|| pass.run_pass(tcx, body)); + if let Some(prof_arg) = &prof_arg { + tcx.sess + .prof + .generic_activity_with_arg(pass.profiler_name(), &**prof_arg) + .run(|| pass.run_pass(tcx, body)); + } else { + pass.run_pass(tcx, body); + } if dump_enabled { dump_mir_for_pass(tcx, body, &name, true); From c64e15e817abbe4a2be0143a10c7c4334fa3bdd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 13 Sep 2023 13:12:51 +0200 Subject: [PATCH 3/3] Bring back `verbose_generic_activity_with_arg` --- .../rustc_data_structures/src/profiling.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs index 321812fa93aec..3c76c2b79911a 100644 --- a/compiler/rustc_data_structures/src/profiling.rs +++ b/compiler/rustc_data_structures/src/profiling.rs @@ -223,6 +223,25 @@ impl SelfProfilerRef { VerboseTimingGuard::start(message_and_format, self.generic_activity(event_label)) } + /// Like `verbose_generic_activity`, but with an extra arg. + pub fn verbose_generic_activity_with_arg( + &self, + event_label: &'static str, + event_arg: A, + ) -> VerboseTimingGuard<'_> + where + A: Borrow + Into, + { + let message_and_format = self + .print_verbose_generic_activities + .map(|format| (format!("{}({})", event_label, event_arg.borrow()), format)); + + VerboseTimingGuard::start( + message_and_format, + self.generic_activity_with_arg(event_label, event_arg), + ) + } + /// Start profiling a generic activity. Profiling continues until the /// TimingGuard returned from this call is dropped. #[inline(always)]