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
This commit is contained in:
Arthur Eubanks
2020-05-28 14:25:23 -07:00
parent 434d122e94
commit 922fa2fce3
4 changed files with 40 additions and 22 deletions
+34 -16
View File
@@ -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<ASanGlobalsMetadataAnalysis, Module>());
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(
+2 -2
View File
@@ -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<void(FunctionPassManager &, OptimizationLevel)> &C) {
const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
OptimizerLastEPCallbacks.push_back(C);
}
@@ -728,7 +728,7 @@ private:
CGSCCOptimizerLateEPCallbacks;
SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2>
VectorizerStartEPCallbacks;
SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2>
SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
OptimizerLastEPCallbacks;
// Module callbacks
SmallVector<std::function<void(ModulePassManager &)>, 2>
+3 -3
View File
@@ -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());
+1 -1
View File
@@ -194,7 +194,7 @@ static void registerEPCallbacks(PassBuilder &PB, bool VerifyEachPass,
});
if (tryParsePipelineText<FunctionPassManager>(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,