From 922fa2fce38b0bd97921b91ff1cdc57f18d3569c Mon Sep 17 00:00:00 2001 From: Arthur Eubanks Date: Wed, 27 May 2020 23:12:36 -0700 Subject: [PATCH] Run Coverage pass before other *San passes under new pass manager, round 2 Summary: This was attempted once before in https://reviews.llvm.org/D79698, but was reverted due to the coverage pass running in the wrong part of the pipeline. This commit puts it in the same place as the other sanitizers. This changes PassBuilder.OptimizerLastEPCallbacks to work on a ModulePassManager instead of a FunctionPassManager. That is because SanitizerCoverage cannot (easily) be split into a module pass and a function pass like some of the other sanitizers since in its current implementation it conditionally inserts module constructors based on whether or not it successfully modified functions. This fixes compiler-rt/test/msan/coverage-levels.cpp under the new pass manager (last check-msan test). Subscribers: hiraditya, cfe-commits, llvm-commits Tags: #clang, #llvm Differential Revision: https://reviews.llvm.org/D80692 --- clang/lib/CodeGen/BackendUtil.cpp | 50 +++++++++++++++++++++++----------- llvm/include/llvm/Passes/PassBuilder.h | 4 +-- llvm/lib/Passes/PassBuilder.cpp | 6 ++-- llvm/tools/opt/NewPMDriver.cpp | 2 +- 4 files changed, 40 insertions(+), 22 deletions(-) diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index e746aef1a62..dd501633392 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -32,6 +32,7 @@ #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" #include "llvm/IR/ModuleSummaryIndex.h" +#include "llvm/IR/PassManager.h" #include "llvm/IR/Verifier.h" #include "llvm/LTO/LTOBackend.h" #include "llvm/MC/MCAsmInfo.h" @@ -1001,6 +1002,15 @@ static void addSanitizersAtO0(ModulePassManager &MPM, const Triple &TargetTriple, const LangOptions &LangOpts, const CodeGenOptions &CodeGenOpts) { + if (CodeGenOpts.SanitizeCoverageType || + CodeGenOpts.SanitizeCoverageIndirectCalls || + CodeGenOpts.SanitizeCoverageTraceCmp) { + auto SancovOpts = getSancovOptsFromCGOpts(CodeGenOpts); + MPM.addPass(ModuleSanitizerCoveragePass( + SancovOpts, CodeGenOpts.SanitizeCoverageWhitelistFiles, + CodeGenOpts.SanitizeCoverageBlacklistFiles)); + } + auto ASanPass = [&](SanitizerMask Mask, bool CompileKernel) { MPM.addPass(RequireAnalysisPass()); bool Recover = CodeGenOpts.SanitizeRecover.has(Mask); @@ -1249,6 +1259,20 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager( [](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) { FPM.addPass(BoundsCheckingPass()); }); + + if (CodeGenOpts.SanitizeCoverageType || + CodeGenOpts.SanitizeCoverageIndirectCalls || + CodeGenOpts.SanitizeCoverageTraceCmp) { + PB.registerOptimizerLastEPCallback( + [this](ModulePassManager &MPM, + PassBuilder::OptimizationLevel Level) { + auto SancovOpts = getSancovOptsFromCGOpts(CodeGenOpts); + MPM.addPass(ModuleSanitizerCoveragePass( + SancovOpts, CodeGenOpts.SanitizeCoverageWhitelistFiles, + CodeGenOpts.SanitizeCoverageBlacklistFiles)); + }); + } + if (LangOpts.Sanitize.has(SanitizerKind::Memory)) { int TrackOrigins = CodeGenOpts.SanitizeMemoryTrackOrigins; bool Recover = CodeGenOpts.SanitizeRecover.has(SanitizerKind::Memory); @@ -1257,17 +1281,19 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager( MPM.addPass(MemorySanitizerPass({TrackOrigins, Recover, false})); }); PB.registerOptimizerLastEPCallback( - [TrackOrigins, Recover](FunctionPassManager &FPM, + [TrackOrigins, Recover](ModulePassManager &MPM, PassBuilder::OptimizationLevel Level) { - FPM.addPass(MemorySanitizerPass({TrackOrigins, Recover, false})); + MPM.addPass(createModuleToFunctionPassAdaptor( + MemorySanitizerPass({TrackOrigins, Recover, false}))); }); } if (LangOpts.Sanitize.has(SanitizerKind::Thread)) { PB.registerPipelineStartEPCallback( [](ModulePassManager &MPM) { MPM.addPass(ThreadSanitizerPass()); }); PB.registerOptimizerLastEPCallback( - [](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) { - FPM.addPass(ThreadSanitizerPass()); + [](ModulePassManager &MPM, PassBuilder::OptimizationLevel Level) { + MPM.addPass( + createModuleToFunctionPassAdaptor(ThreadSanitizerPass())); }); } if (LangOpts.Sanitize.has(SanitizerKind::Address)) { @@ -1278,10 +1304,11 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager( bool Recover = CodeGenOpts.SanitizeRecover.has(SanitizerKind::Address); bool UseAfterScope = CodeGenOpts.SanitizeAddressUseAfterScope; PB.registerOptimizerLastEPCallback( - [Recover, UseAfterScope](FunctionPassManager &FPM, + [Recover, UseAfterScope](ModulePassManager &MPM, PassBuilder::OptimizationLevel Level) { - FPM.addPass(AddressSanitizerPass( - /*CompileKernel=*/false, Recover, UseAfterScope)); + MPM.addPass( + createModuleToFunctionPassAdaptor(AddressSanitizerPass( + /*CompileKernel=*/false, Recover, UseAfterScope))); }); bool ModuleUseAfterScope = asanUseGlobalsGC(TargetTriple, CodeGenOpts); bool UseOdrIndicator = CodeGenOpts.SanitizeAddressUseOdrIndicator; @@ -1325,15 +1352,6 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager( } } - if (CodeGenOpts.SanitizeCoverageType || - CodeGenOpts.SanitizeCoverageIndirectCalls || - CodeGenOpts.SanitizeCoverageTraceCmp) { - auto SancovOpts = getSancovOptsFromCGOpts(CodeGenOpts); - MPM.addPass(ModuleSanitizerCoveragePass( - SancovOpts, CodeGenOpts.SanitizeCoverageWhitelistFiles, - CodeGenOpts.SanitizeCoverageBlacklistFiles)); - } - if (LangOpts.Sanitize.has(SanitizerKind::HWAddress)) { bool Recover = CodeGenOpts.SanitizeRecover.has(SanitizerKind::HWAddress); MPM.addPass(HWAddressSanitizerPass( diff --git a/llvm/include/llvm/Passes/PassBuilder.h b/llvm/include/llvm/Passes/PassBuilder.h index 391d144d5dc..d5a70c2ae13 100644 --- a/llvm/include/llvm/Passes/PassBuilder.h +++ b/llvm/include/llvm/Passes/PassBuilder.h @@ -600,7 +600,7 @@ public: /// is not triggered at O0. Extensions to the O0 pipeline should append their /// passes to the end of the overall pipeline. void registerOptimizerLastEPCallback( - const std::function &C) { + const std::function &C) { OptimizerLastEPCallbacks.push_back(C); } @@ -728,7 +728,7 @@ private: CGSCCOptimizerLateEPCallbacks; SmallVector, 2> VectorizerStartEPCallbacks; - SmallVector, 2> + SmallVector, 2> OptimizerLastEPCallbacks; // Module callbacks SmallVector, 2> diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index 0999f7872d1..1b1701cbe26 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -1073,12 +1073,12 @@ ModulePassManager PassBuilder::buildModuleOptimizationPipeline( if (PTO.Coroutines) OptimizePM.addPass(CoroCleanupPass()); - for (auto &C : OptimizerLastEPCallbacks) - C(OptimizePM, Level); - // Add the core optimizing pipeline. MPM.addPass(createModuleToFunctionPassAdaptor(std::move(OptimizePM))); + for (auto &C : OptimizerLastEPCallbacks) + C(MPM, Level); + if (PTO.CallGraphProfile) MPM.addPass(CGProfilePass()); diff --git a/llvm/tools/opt/NewPMDriver.cpp b/llvm/tools/opt/NewPMDriver.cpp index 2e84ca49b6e..c99ad2f7b4d 100644 --- a/llvm/tools/opt/NewPMDriver.cpp +++ b/llvm/tools/opt/NewPMDriver.cpp @@ -194,7 +194,7 @@ static void registerEPCallbacks(PassBuilder &PB, bool VerifyEachPass, }); if (tryParsePipelineText(PB, OptimizerLastEPPipeline)) PB.registerOptimizerLastEPCallback( - [&PB, VerifyEachPass, DebugLogging](FunctionPassManager &PM, + [&PB, VerifyEachPass, DebugLogging](ModulePassManager &PM, PassBuilder::OptimizationLevel) { ExitOnError Err("Unable to parse OptimizerLastEP pipeline: "); Err(PB.parsePassPipeline(PM, OptimizerLastEPPipeline, VerifyEachPass, -- 2.11.0