From 5ecbe7fcf8bceb91d43a21be872aaef44c01073a Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 5 Apr 2021 10:45:04 +0200 Subject: [PATCH] Explicitly register instrprof pass Don't use "passes" for this purpose, explicitly insert it into the correct place in the pipeline instead. --- compiler/rustc_codegen_llvm/src/back/write.rs | 7 ++++++- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 1 + compiler/rustc_codegen_ssa/src/back/write.rs | 8 ++------ compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp | 12 +++++++++++- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 673f5c3c3623..96d24e4f298c 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -472,6 +472,7 @@ pub(crate) unsafe fn optimize_with_new_llvm_pass_manager( sanitizer_options.as_ref(), pgo_gen_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()), pgo_use_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()), + config.instrument_coverage, llvm_selfprofiler, selfprofile_before_pass_callback, selfprofile_after_pass_callback, @@ -545,7 +546,7 @@ pub(crate) unsafe fn optimize( llvm::LLVMRustAddPass(fpm, find_pass("lint").unwrap()); continue; } - if pass_name == "insert-gcov-profiling" || pass_name == "instrprof" { + if pass_name == "insert-gcov-profiling" { // Instrumentation must be inserted before optimization, // otherwise LLVM may optimize some functions away which // breaks llvm-cov. @@ -566,6 +567,10 @@ pub(crate) unsafe fn optimize( } } + if config.instrument_coverage { + llvm::LLVMRustAddPass(mpm, find_pass("instrprof").unwrap()); + } + add_sanitizer_passes(config, &mut extra_passes); // Some options cause LLVM bitcode to be emitted, which uses ThinLTOBuffers, so we need diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 32b1526f6e44..9a7be0319446 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2203,6 +2203,7 @@ extern "C" { SanitizerOptions: Option<&SanitizerOptions>, PGOGenPath: *const c_char, PGOUsePath: *const c_char, + InstrumentCoverage: bool, llvm_selfprofiler: *mut c_void, begin_callback: SelfProfileBeforePassCallback, end_callback: SelfProfileAfterPassCallback, diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index dce8ab6f0267..dd50a2988594 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -84,6 +84,7 @@ pub struct ModuleConfig { pub pgo_gen: SwitchWithOptPath, pub pgo_use: Option, + pub instrument_coverage: bool, pub sanitizer: SanitizerSet, pub sanitizer_recover: SanitizerSet, @@ -174,12 +175,6 @@ impl ModuleConfig { if sess.opts.debugging_opts.profile && !is_compiler_builtins { passes.push("insert-gcov-profiling".to_owned()); } - - // The rustc option `-Zinstrument_coverage` injects intrinsic calls to - // `llvm.instrprof.increment()`, which requires the LLVM `instrprof` pass. - if sess.instrument_coverage() { - passes.push("instrprof".to_owned()); - } passes }, vec![] @@ -193,6 +188,7 @@ impl ModuleConfig { SwitchWithOptPath::Disabled ), pgo_use: if_regular!(sess.opts.cg.profile_use.clone(), None), + instrument_coverage: if_regular!(sess.instrument_coverage(), false), sanitizer: if_regular!(sess.opts.debugging_opts.sanitizer, SanitizerSet::empty()), sanitizer_recover: if_regular!( diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 65a988629c3b..7191e9a779c6 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -32,6 +32,7 @@ #include "llvm/Transforms/Instrumentation.h" #include "llvm/Transforms/Instrumentation/AddressSanitizer.h" #include "llvm/Support/TimeProfiler.h" +#include "llvm/Transforms/Instrumentation/InstrProfiling.h" #include "llvm/Transforms/Instrumentation/ThreadSanitizer.h" #include "llvm/Transforms/Instrumentation/MemorySanitizer.h" #include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h" @@ -744,7 +745,7 @@ LLVMRustOptimizeWithNewPassManager( bool MergeFunctions, bool UnrollLoops, bool SLPVectorize, bool LoopVectorize, bool DisableSimplifyLibCalls, bool EmitLifetimeMarkers, LLVMRustSanitizerOptions *SanitizerOptions, - const char *PGOGenPath, const char *PGOUsePath, + const char *PGOGenPath, const char *PGOUsePath, bool InstrumentCoverage, void* LlvmSelfProfiler, LLVMRustSelfProfileBeforePassCallback BeforePassCallback, LLVMRustSelfProfileAfterPassCallback AfterPassCallback) { @@ -834,6 +835,15 @@ LLVMRustOptimizeWithNewPassManager( ); } + if (InstrumentCoverage) { + PipelineStartEPCallbacks.push_back( + [](ModulePassManager &MPM, PassBuilder::OptimizationLevel Level) { + InstrProfOptions Options; + MPM.addPass(InstrProfiling(Options, false)); + } + ); + } + if (SanitizerOptions) { if (SanitizerOptions->SanitizeMemory) { MemorySanitizerOptions Options(