[llvm] 36d5138 - [NewPM] Make some sanitizer passes parameterized in the PassRegistry
Bjorn Pettersson via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 19 03:44:20 PDT 2021
Author: Bjorn Pettersson
Date: 2021-08-19T12:43:37+02:00
New Revision: 36d51386195e3d606e0d40495f1135ab180bd6ae
URL: https://github.com/llvm/llvm-project/commit/36d51386195e3d606e0d40495f1135ab180bd6ae
DIFF: https://github.com/llvm/llvm-project/commit/36d51386195e3d606e0d40495f1135ab180bd6ae.diff
LOG: [NewPM] Make some sanitizer passes parameterized in the PassRegistry
Refactored implementation of AddressSanitizerPass and
HWAddressSanitizerPass to use pass options similar to passes like
MemorySanitizerPass. This makes sure that there is a single mapping
from class name to pass name (needed by D108298), and options like
-debug-only and -print-after makes a bit more sense when (despite
that it is the unparameterized pass name that should be used in those
options).
A result of the above is that some pass names are removed in favor
of the parameterized versions:
- "khwasan" is now "hwasan<kernel;recover>"
- "kasan" is now "asan<kernel>"
- "kmsan" is now "msan<kernel>"
Differential Revision: https://reviews.llvm.org/D105007
Added:
Modified:
clang/lib/CodeGen/BackendUtil.cpp
llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h
llvm/include/llvm/Transforms/Instrumentation/HWAddressSanitizer.h
llvm/lib/Passes/PassBuilder.cpp
llvm/lib/Passes/PassRegistry.def
llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
llvm/tools/opt/NewPMDriver.cpp
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 404d2680fac3..991620766b55 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -1161,7 +1161,7 @@ static void addSanitizers(const Triple &TargetTriple,
CompileKernel, Recover, ModuleUseAfterScope, UseOdrIndicator,
DestructorKind));
MPM.addPass(createModuleToFunctionPassAdaptor(AddressSanitizerPass(
- CompileKernel, Recover, UseAfterScope, UseAfterReturn)));
+ {CompileKernel, Recover, UseAfterScope, UseAfterReturn})));
}
};
ASanPass(SanitizerKind::Address, false);
@@ -1171,8 +1171,8 @@ static void addSanitizers(const Triple &TargetTriple,
if (LangOpts.Sanitize.has(Mask)) {
bool Recover = CodeGenOpts.SanitizeRecover.has(Mask);
MPM.addPass(HWAddressSanitizerPass(
- CompileKernel, Recover,
- /*DisableOptimization=*/CodeGenOpts.OptimizationLevel == 0));
+ {CompileKernel, Recover,
+ /*DisableOptimization=*/CodeGenOpts.OptimizationLevel == 0}));
}
};
HWASanPass(SanitizerKind::HWAddress, false);
diff --git a/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h b/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h
index de0871bc9921..9e8b97c0b94f 100644
--- a/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h
+++ b/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h
@@ -89,6 +89,20 @@ class ASanGlobalsMetadataAnalysis
static AnalysisKey Key;
};
+struct AddressSanitizerOptions {
+ AddressSanitizerOptions()
+ : AddressSanitizerOptions(false, false, false,
+ AsanDetectStackUseAfterReturnMode::Runtime){};
+ AddressSanitizerOptions(bool CompileKernel, bool Recover, bool UseAfterScope,
+ AsanDetectStackUseAfterReturnMode UseAfterReturn)
+ : CompileKernel(CompileKernel), Recover(Recover),
+ UseAfterScope(UseAfterScope), UseAfterReturn(UseAfterReturn){};
+ bool CompileKernel;
+ bool Recover;
+ bool UseAfterScope;
+ AsanDetectStackUseAfterReturnMode UseAfterReturn;
+};
+
/// Public interface to the address sanitizer pass for instrumenting code to
/// check for various memory errors at runtime.
///
@@ -98,19 +112,13 @@ class ASanGlobalsMetadataAnalysis
/// surrounding requested memory to be checked for invalid accesses.
class AddressSanitizerPass : public PassInfoMixin<AddressSanitizerPass> {
public:
- explicit AddressSanitizerPass(
- bool CompileKernel = false, bool Recover = false,
- bool UseAfterScope = false,
- AsanDetectStackUseAfterReturnMode UseAfterReturn =
- AsanDetectStackUseAfterReturnMode::Runtime);
+ explicit AddressSanitizerPass(AddressSanitizerOptions Options)
+ : Options(Options){};
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
static bool isRequired() { return true; }
private:
- bool CompileKernel;
- bool Recover;
- bool UseAfterScope;
- AsanDetectStackUseAfterReturnMode UseAfterReturn;
+ AddressSanitizerOptions Options;
};
/// Public interface to the address sanitizer module pass for instrumenting code
diff --git a/llvm/include/llvm/Transforms/Instrumentation/HWAddressSanitizer.h b/llvm/include/llvm/Transforms/Instrumentation/HWAddressSanitizer.h
index 7942417d2bfa..07248baaa8b6 100644
--- a/llvm/include/llvm/Transforms/Instrumentation/HWAddressSanitizer.h
+++ b/llvm/include/llvm/Transforms/Instrumentation/HWAddressSanitizer.h
@@ -18,21 +18,30 @@
namespace llvm {
+struct HWAddressSanitizerOptions {
+ HWAddressSanitizerOptions()
+ : HWAddressSanitizerOptions(false, false, false){};
+ HWAddressSanitizerOptions(bool CompileKernel, bool Recover,
+ bool DisableOptimization)
+ : CompileKernel(CompileKernel), Recover(Recover),
+ DisableOptimization(DisableOptimization){};
+ bool CompileKernel;
+ bool Recover;
+ bool DisableOptimization;
+};
+
/// This is a public interface to the hardware address sanitizer pass for
/// instrumenting code to check for various memory errors at runtime, similar to
/// AddressSanitizer but based on partial hardware assistance.
class HWAddressSanitizerPass : public PassInfoMixin<HWAddressSanitizerPass> {
public:
- explicit HWAddressSanitizerPass(bool CompileKernel = false,
- bool Recover = false,
- bool DisableOptimization = false);
+ explicit HWAddressSanitizerPass(HWAddressSanitizerOptions Options)
+ : Options(Options){};
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
static bool isRequired() { return true; }
private:
- bool CompileKernel;
- bool Recover;
- bool DisableOptimization;
+ HWAddressSanitizerOptions Options;
};
FunctionPass *
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index c8dee32d0b01..81d83191986b 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -453,6 +453,8 @@ PassBuilder::PassBuilder(TargetMachine *TM, PipelineTuningOptions PTO,
if (PIC && shouldPopulateClassToPassNames()) {
#define MODULE_PASS(NAME, CREATE_PASS) \
PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
+#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
+ PIC->addClassToPassName(CLASS, NAME);
#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
#define FUNCTION_PASS(NAME, CREATE_PASS) \
@@ -2137,6 +2139,44 @@ Expected<LoopUnrollOptions> parseLoopUnrollOptions(StringRef Params) {
return UnrollOpts;
}
+Expected<AddressSanitizerOptions> parseASanPassOptions(StringRef Params) {
+ AddressSanitizerOptions Result;
+ while (!Params.empty()) {
+ StringRef ParamName;
+ std::tie(ParamName, Params) = Params.split(';');
+
+ if (ParamName == "kernel") {
+ Result.CompileKernel = true;
+ } else {
+ return make_error<StringError>(
+ formatv("invalid AddressSanitizer pass parameter '{0}' ", ParamName)
+ .str(),
+ inconvertibleErrorCode());
+ }
+ }
+ return Result;
+}
+
+Expected<HWAddressSanitizerOptions> parseHWASanPassOptions(StringRef Params) {
+ HWAddressSanitizerOptions Result;
+ while (!Params.empty()) {
+ StringRef ParamName;
+ std::tie(ParamName, Params) = Params.split(';');
+
+ if (ParamName == "recover") {
+ Result.Recover = true;
+ } else if (ParamName == "kernel") {
+ Result.CompileKernel = true;
+ } else {
+ return make_error<StringError>(
+ formatv("invalid HWAddressSanitizer pass parameter '{0}' ", ParamName)
+ .str(),
+ inconvertibleErrorCode());
+ }
+ }
+ return Result;
+}
+
Expected<MemorySanitizerOptions> parseMSanPassOptions(StringRef Params) {
MemorySanitizerOptions Result;
while (!Params.empty()) {
@@ -2356,6 +2396,9 @@ static bool isModulePassName(StringRef Name, CallbacksT &Callbacks) {
#define MODULE_PASS(NAME, CREATE_PASS) \
if (Name == NAME) \
return true;
+#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
+ if (checkParametrizedPassName(Name, NAME)) \
+ return true;
#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
return true;
@@ -2600,6 +2643,14 @@ Error PassBuilder::parseModulePass(ModulePassManager &MPM,
MPM.addPass(CREATE_PASS); \
return Error::success(); \
}
+#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
+ if (checkParametrizedPassName(Name, NAME)) { \
+ auto Params = parsePassParameters(PARSER, Name, NAME); \
+ if (!Params) \
+ return Params.takeError(); \
+ MPM.addPass(CREATE_PASS(Params.get())); \
+ return Error::success(); \
+ }
#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
if (Name == "require<" NAME ">") { \
MPM.addPass( \
@@ -3176,6 +3227,11 @@ void PassBuilder::printPassNames(raw_ostream &OS) {
#define MODULE_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
#include "PassRegistry.def"
+ OS << "Module passes with params:\n";
+#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
+ printPassName(NAME, PARAMS, OS);
+#include "PassRegistry.def"
+
OS << "Module analyses:\n";
#define MODULE_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
#include "PassRegistry.def"
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index 7525d59f94a5..1679129bb936 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -60,8 +60,6 @@ MODULE_PASS("globaldce", GlobalDCEPass())
MODULE_PASS("globalopt", GlobalOptPass())
MODULE_PASS("globalsplit", GlobalSplitPass())
MODULE_PASS("hotcoldsplit", HotColdSplittingPass())
-MODULE_PASS("hwasan", HWAddressSanitizerPass(false, false))
-MODULE_PASS("khwasan", HWAddressSanitizerPass(true, true))
MODULE_PASS("inferattrs", InferFunctionAttrsPass())
MODULE_PASS("inliner-wrapper", ModuleInlinerWrapperPass())
MODULE_PASS("inliner-wrapper-no-mandatory-first", ModuleInlinerWrapperPass(
@@ -123,6 +121,18 @@ MODULE_PASS("poison-checking", PoisonCheckingPass())
MODULE_PASS("pseudo-probe-update", PseudoProbeUpdatePass())
#undef MODULE_PASS
+#ifndef MODULE_PASS_WITH_PARAMS
+#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS)
+#endif
+MODULE_PASS_WITH_PARAMS("hwasan",
+ "HWAddressSanitizerPass",
+ [](HWAddressSanitizerOptions Opts) {
+ return HWAddressSanitizerPass(Opts);
+ },
+ parseHWASanPassOptions,
+ "kernel;recover")
+#undef MODULE_PASS_WITH_PARAMS
+
#ifndef CGSCC_ANALYSIS
#define CGSCC_ANALYSIS(NAME, CREATE_PASS)
#endif
@@ -322,10 +332,7 @@ FUNCTION_PASS("verify<scalar-evolution>", ScalarEvolutionVerifierPass())
FUNCTION_PASS("view-cfg", CFGViewerPass())
FUNCTION_PASS("view-cfg-only", CFGOnlyViewerPass())
FUNCTION_PASS("transform-warning", WarnMissedTransformationsPass())
-FUNCTION_PASS("asan", AddressSanitizerPass(false, false, false))
-FUNCTION_PASS("kasan", AddressSanitizerPass(true, false, false))
FUNCTION_PASS("msan", MemorySanitizerPass({}))
-FUNCTION_PASS("kmsan", MemorySanitizerPass({0, false, /*Kernel=*/true}))
FUNCTION_PASS("tsan", ThreadSanitizerPass())
FUNCTION_PASS("memprof", MemProfilerPass())
#undef FUNCTION_PASS
@@ -345,6 +352,13 @@ FUNCTION_PASS_WITH_PARAMS("loop-unroll",
"no-profile-peeling;profile-peeling;"
"no-runtime;runtime;"
"no-upperbound;upperbound")
+FUNCTION_PASS_WITH_PARAMS("asan",
+ "AddressSanitizerPass",
+ [](AddressSanitizerOptions Opts) {
+ return AddressSanitizerPass(Opts);
+ },
+ parseASanPassOptions,
+ "kernel")
FUNCTION_PASS_WITH_PARAMS("msan",
"MemorySanitizerPass",
[](MemorySanitizerOptions Opts) {
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index c02955bad0f6..2b8f5b71acb8 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -1212,20 +1212,14 @@ GlobalsMetadata ASanGlobalsMetadataAnalysis::run(Module &M,
return GlobalsMetadata(M);
}
-AddressSanitizerPass::AddressSanitizerPass(
- bool CompileKernel, bool Recover, bool UseAfterScope,
- AsanDetectStackUseAfterReturnMode UseAfterReturn)
- : CompileKernel(CompileKernel), Recover(Recover),
- UseAfterScope(UseAfterScope), UseAfterReturn(UseAfterReturn) {}
-
PreservedAnalyses AddressSanitizerPass::run(Function &F,
AnalysisManager<Function> &AM) {
auto &MAMProxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
Module &M = *F.getParent();
if (auto *R = MAMProxy.getCachedResult<ASanGlobalsMetadataAnalysis>(M)) {
const TargetLibraryInfo *TLI = &AM.getResult<TargetLibraryAnalysis>(F);
- AddressSanitizer Sanitizer(M, R, CompileKernel, Recover, UseAfterScope,
- UseAfterReturn);
+ AddressSanitizer Sanitizer(M, R, Options.CompileKernel, Options.Recover,
+ Options.UseAfterScope, Options.UseAfterReturn);
if (Sanitizer.instrumentFunction(F, TLI))
return PreservedAnalyses::none();
return PreservedAnalyses::all();
diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
index d7cff904ca15..9834d09bebcd 100644
--- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -471,19 +471,14 @@ llvm::createHWAddressSanitizerLegacyPassPass(bool CompileKernel, bool Recover,
DisableOptimization);
}
-HWAddressSanitizerPass::HWAddressSanitizerPass(bool CompileKernel, bool Recover,
- bool DisableOptimization)
- : CompileKernel(CompileKernel), Recover(Recover),
- DisableOptimization(DisableOptimization) {}
-
PreservedAnalyses HWAddressSanitizerPass::run(Module &M,
ModuleAnalysisManager &MAM) {
const StackSafetyGlobalInfo *SSI = nullptr;
auto TargetTriple = llvm::Triple(M.getTargetTriple());
- if (shouldUseStackSafetyAnalysis(TargetTriple, DisableOptimization))
+ if (shouldUseStackSafetyAnalysis(TargetTriple, Options.DisableOptimization))
SSI = &MAM.getResult<StackSafetyGlobalAnalysis>(M);
- HWAddressSanitizer HWASan(M, CompileKernel, Recover, SSI);
+ HWAddressSanitizer HWASan(M, Options.CompileKernel, Options.Recover, SSI);
bool Modified = false;
auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
for (Function &F : M) {
diff --git a/llvm/tools/opt/NewPMDriver.cpp b/llvm/tools/opt/NewPMDriver.cpp
index 6c11da564835..0dab83cc22f5 100644
--- a/llvm/tools/opt/NewPMDriver.cpp
+++ b/llvm/tools/opt/NewPMDriver.cpp
@@ -339,18 +339,19 @@ bool llvm::runPassPipeline(StringRef Arg0, Module &M, TargetMachine *TM,
PB.registerPipelineParsingCallback(
[](StringRef Name, ModulePassManager &MPM,
ArrayRef<PassBuilder::PipelineElement>) {
+ AddressSanitizerOptions Opts;
if (Name == "asan-pipeline") {
MPM.addPass(
RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>());
MPM.addPass(
- createModuleToFunctionPassAdaptor(AddressSanitizerPass()));
+ createModuleToFunctionPassAdaptor(AddressSanitizerPass(Opts)));
MPM.addPass(ModuleAddressSanitizerPass());
return true;
} else if (Name == "asan-function-pipeline") {
MPM.addPass(
RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>());
MPM.addPass(
- createModuleToFunctionPassAdaptor(AddressSanitizerPass()));
+ createModuleToFunctionPassAdaptor(AddressSanitizerPass(Opts)));
return true;
}
return false;
More information about the llvm-commits
mailing list