From 93c636211ca4b0b7745d6d4ca82587a27ddc59a8 Mon Sep 17 00:00:00 2001 From: Alan Egerton Date: Fri, 14 May 2021 11:07:06 +0100 Subject: [PATCH 1/2] Provide option for specifying the profiler runtime Currently, if `-Zinstrument-coverage` is enabled, the target is linked against the `library/profiler_builtins` crate (which pulls in LLVM's compiler-rt runtime). This option enables backends to specify an alternative runtime crate for handling injected instrumentation calls. --- compiler/rustc_interface/src/tests.rs | 2 +- compiler/rustc_metadata/src/creader.rs | 38 ++++++++++++++------------ compiler/rustc_metadata/src/locator.rs | 4 ++- compiler/rustc_session/src/options.rs | 4 +-- 4 files changed, 27 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index bea7d0fb81f95..17496c35a4ba8 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -713,7 +713,6 @@ fn test_debugging_options_tracking_hash() { tracked!(no_codegen, true); tracked!(no_generate_arange_section, true); tracked!(no_link, true); - tracked!(no_profiler_runtime, true); tracked!(osx_rpath_install_name, true); tracked!(panic_abort_tests, true); tracked!(plt, Some(true)); @@ -722,6 +721,7 @@ fn test_debugging_options_tracking_hash() { tracked!(print_fuel, Some("abc".to_string())); tracked!(profile, true); tracked!(profile_emit, Some(PathBuf::from("abc"))); + tracked!(profiler_runtime, None); tracked!(relax_elf_relocations, Some(true)); tracked!(relro_level, Some(RelroLevel::Full)); tracked!(simulate_remapped_rust_src_base, Some(PathBuf::from("/rustc/abc"))); diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index e9ae22f8cedbc..8108470e3d3cc 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -769,27 +769,31 @@ impl<'a> CrateLoader<'a> { } fn inject_profiler_runtime(&mut self, krate: &ast::Crate) { - if (self.sess.instrument_coverage() + if self.sess.instrument_coverage() || self.sess.opts.debugging_opts.profile - || self.sess.opts.cg.profile_generate.enabled()) - && !self.sess.opts.debugging_opts.no_profiler_runtime + || self.sess.opts.cg.profile_generate.enabled() { - info!("loading profiler"); - - if self.sess.contains_name(&krate.attrs, sym::no_core) { - self.sess.err( - "`profiler_builtins` crate (required by compiler options) \ - is not compatible with crate attribute `#![no_core]`", - ); - } + if let Some(name) = + self.sess.opts.debugging_opts.profiler_runtime.as_deref().map(Symbol::intern) + { + info!("loading profiler"); + + if name == sym::profiler_builtins + && self.sess.contains_name(&krate.attrs, sym::no_core) + { + self.sess.err( + "`profiler_builtins` crate (required by compiler options) \ + is not compatible with crate attribute `#![no_core]`", + ); + } - let name = sym::profiler_builtins; - let cnum = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit, None); - let data = self.cstore.get_crate_data(cnum); + let cnum = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit, None); + let data = self.cstore.get_crate_data(cnum); - // Sanity check the loaded crate to ensure it is indeed a profiler runtime - if !data.is_profiler_runtime() { - self.sess.err("the crate `profiler_builtins` is not a profiler runtime"); + // Sanity check the loaded crate to ensure it is indeed a profiler runtime + if !data.is_profiler_runtime() { + self.sess.err(&format!("the crate `{}` is not a profiler runtime", name)); + } } } } diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs index 6e7360950908e..8570bf30f8078 100644 --- a/compiler/rustc_metadata/src/locator.rs +++ b/compiler/rustc_metadata/src/locator.rs @@ -1100,7 +1100,9 @@ impl CrateError { if sess.is_nightly_build() && std::env::var("CARGO").is_ok() { err.help("consider building the standard library from source with `cargo build -Zbuild-std`"); } - } else if crate_name == sym::profiler_builtins { + } else if Some(crate_name) + == sess.opts.debugging_opts.profiler_runtime.as_deref().map(Symbol::intern) + { err.note(&"the compiler may have been built without the profiler runtime"); } err.span_label(span, "can't find crate"); diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index c9f95ed1224d0..d41f474ab0177 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1148,8 +1148,6 @@ options! { "compile without linking"), no_parallel_llvm: bool = (false, parse_no_flag, [UNTRACKED], "run LLVM in non-parallel mode (while keeping codegen-units and ThinLTO)"), - no_profiler_runtime: bool = (false, parse_no_flag, [TRACKED], - "prevent automatic injection of the profiler_builtins crate"), normalize_docs: bool = (false, parse_bool, [TRACKED], "normalize associated items in rustdoc when generating documentation"), osx_rpath_install_name: bool = (false, parse_bool, [TRACKED], @@ -1193,6 +1191,8 @@ options! { profile_emit: Option = (None, parse_opt_pathbuf, [TRACKED], "file path to emit profiling data at runtime when using 'profile' \ (default based on relative source path)"), + profiler_runtime: Option = (Some(String::from("profiler_builtins")), parse_opt_string, [TRACKED], + "name of the profiler runtime crate to automatically inject, or None to disable"), query_dep_graph: bool = (false, parse_bool, [UNTRACKED], "enable queries of the dependency graph for regression testing (default: no)"), query_stats: bool = (false, parse_bool, [UNTRACKED], From 872839eb494e2ed6b2e7c9ba28ec3450c399d935 Mon Sep 17 00:00:00 2001 From: Alan Egerton Date: Thu, 17 Jun 2021 12:11:40 +0100 Subject: [PATCH 2/2] Early return from `inject_profiler_runtime` --- compiler/rustc_metadata/src/creader.rs | 46 +++++++++++++------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 8108470e3d3cc..dbf36c5d397ea 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -769,32 +769,32 @@ impl<'a> CrateLoader<'a> { } fn inject_profiler_runtime(&mut self, krate: &ast::Crate) { - if self.sess.instrument_coverage() - || self.sess.opts.debugging_opts.profile - || self.sess.opts.cg.profile_generate.enabled() + let profiler_runtime = &self.sess.opts.debugging_opts.profiler_runtime; + + if !(profiler_runtime.is_some() + && (self.sess.instrument_coverage() + || self.sess.opts.debugging_opts.profile + || self.sess.opts.cg.profile_generate.enabled())) { - if let Some(name) = - self.sess.opts.debugging_opts.profiler_runtime.as_deref().map(Symbol::intern) - { - info!("loading profiler"); - - if name == sym::profiler_builtins - && self.sess.contains_name(&krate.attrs, sym::no_core) - { - self.sess.err( - "`profiler_builtins` crate (required by compiler options) \ - is not compatible with crate attribute `#![no_core]`", - ); - } + return; + } - let cnum = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit, None); - let data = self.cstore.get_crate_data(cnum); + info!("loading profiler"); - // Sanity check the loaded crate to ensure it is indeed a profiler runtime - if !data.is_profiler_runtime() { - self.sess.err(&format!("the crate `{}` is not a profiler runtime", name)); - } - } + let name = Symbol::intern(profiler_runtime.as_ref().unwrap()); + if name == sym::profiler_builtins && self.sess.contains_name(&krate.attrs, sym::no_core) { + self.sess.err( + "`profiler_builtins` crate (required by compiler options) \ + is not compatible with crate attribute `#![no_core]`", + ); + } + + let cnum = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit, None); + let data = self.cstore.get_crate_data(cnum); + + // Sanity check the loaded crate to ensure it is indeed a profiler runtime + if !data.is_profiler_runtime() { + self.sess.err(&format!("the crate `{}` is not a profiler runtime", name)); } }