diff --git a/llvm/include/llvm/Analysis/Lint.h b/llvm/include/llvm/Analysis/Lint.h index 8dffa1ecb5f38..b0bc0ff4e1d89 100644 --- a/llvm/include/llvm/Analysis/Lint.h +++ b/llvm/include/llvm/Analysis/Lint.h @@ -29,14 +29,20 @@ class Function; /// /// This should only be used for debugging, because it plays games with /// PassManagers and stuff. -void lintModule(const Module &M); +void lintModule(const Module &M, bool AbortOnError = false); // Lint a function. -void lintFunction(const Function &F); +void lintFunction(const Function &F, bool AbortOnError = false); class LintPass : public PassInfoMixin { + const bool AbortOnError; + public: + LintPass(bool AbortOnError) : AbortOnError(AbortOnError) {} PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); + + void printPipeline(raw_ostream &OS, + function_ref MapClassName2PassName); }; } // namespace llvm diff --git a/llvm/lib/Analysis/Lint.cpp b/llvm/lib/Analysis/Lint.cpp index a01672844e0ec..f05e36e2025d4 100644 --- a/llvm/lib/Analysis/Lint.cpp +++ b/llvm/lib/Analysis/Lint.cpp @@ -78,11 +78,6 @@ using namespace llvm; -static const char LintAbortOnErrorArgName[] = "lint-abort-on-error"; -static cl::opt - LintAbortOnError(LintAbortOnErrorArgName, cl::init(false), - cl::desc("In the Lint pass, abort on errors.")); - namespace { namespace MemRef { static const unsigned Read = 1; @@ -747,20 +742,26 @@ PreservedAnalyses LintPass::run(Function &F, FunctionAnalysisManager &AM) { Lint L(Mod, DL, AA, AC, DT, TLI); L.visit(F); dbgs() << L.MessagesStr.str(); - if (LintAbortOnError && !L.MessagesStr.str().empty()) - report_fatal_error(Twine("Linter found errors, aborting. (enabled by --") + - LintAbortOnErrorArgName + ")", - false); + if (AbortOnError && !L.MessagesStr.str().empty()) + report_fatal_error( + "linter found errors, aborting. (enabled by abort-on-error)", false); return PreservedAnalyses::all(); } +void LintPass::printPipeline( + raw_ostream &OS, function_ref MapClassName2PassName) { + PassInfoMixin::printPipeline(OS, MapClassName2PassName); + if (AbortOnError) + OS << ""; +} + //===----------------------------------------------------------------------===// // Implement the public interfaces to this file... //===----------------------------------------------------------------------===// /// lintFunction - Check a function for errors, printing messages on stderr. /// -void llvm::lintFunction(const Function &f) { +void llvm::lintFunction(const Function &f, bool AbortOnError) { Function &F = const_cast(f); assert(!F.isDeclaration() && "Cannot lint external functions"); @@ -775,14 +776,14 @@ void llvm::lintFunction(const Function &f) { AA.registerFunctionAnalysis(); return AA; }); - LintPass().run(F, FAM); + LintPass(AbortOnError).run(F, FAM); } /// lintModule - Check a module for errors, printing messages on stderr. /// -void llvm::lintModule(const Module &M) { +void llvm::lintModule(const Module &M, bool AbortOnError) { for (const Function &F : M) { if (!F.isDeclaration()) - lintFunction(F); + lintFunction(F, AbortOnError); } } diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index 1b37e4a4fe1a3..8646c1f49ac35 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -681,6 +681,12 @@ Expected parseHardwareLoopOptions(StringRef Params) { return HardwareLoopOpts; } +/// Parser of parameters for Lint pass. +Expected parseLintOptions(StringRef Params) { + return PassBuilder::parseSinglePassOption(Params, "abort-on-error", + "LintPass"); +} + /// Parser of parameters for LoopUnroll pass. Expected parseLoopUnrollOptions(StringRef Params) { LoopUnrollOptions UnrollOpts; diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def index 49135c5e1a658..a43be480d6194 100644 --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -397,7 +397,6 @@ FUNCTION_PASS("kcfi", KCFIPass()) FUNCTION_PASS("kernel-info", KernelInfoPrinter(TM)) FUNCTION_PASS("lcssa", LCSSAPass()) FUNCTION_PASS("libcalls-shrinkwrap", LibCallsShrinkWrapPass()) -FUNCTION_PASS("lint", LintPass()) FUNCTION_PASS("load-store-vectorizer", LoadStoreVectorizerPass()) FUNCTION_PASS("loop-data-prefetch", LoopDataPrefetchPass()) FUNCTION_PASS("loop-distribute", LoopDistributePass()) @@ -543,6 +542,11 @@ FUNCTION_PASS_WITH_PARAMS( parseInstCombineOptions, "no-use-loop-info;use-loop-info;no-verify-fixpoint;verify-fixpoint;" "max-iterations=N") +FUNCTION_PASS_WITH_PARAMS( + "lint", "LintPass", + [](bool AbortOnError) { return LintPass(AbortOnError); }, + parseLintOptions, + "abort-on-error") FUNCTION_PASS_WITH_PARAMS( "loop-unroll", "LoopUnrollPass", [](LoopUnrollOptions Opts) { return LoopUnrollPass(Opts); }, diff --git a/llvm/test/Analysis/Lint/abort-on-error.ll b/llvm/test/Analysis/Lint/abort-on-error.ll index 3efc38aea887c..0bbbcfa9d7418 100644 --- a/llvm/test/Analysis/Lint/abort-on-error.ll +++ b/llvm/test/Analysis/Lint/abort-on-error.ll @@ -1,8 +1,8 @@ -; RUN: not opt -passes=lint -disable-output --lint-abort-on-error %s 2>&1 | FileCheck %s +; RUN: not opt -passes='lint' -disable-output %s 2>&1 | FileCheck %s ; CHECK: Undefined behavior: Division by zero ; CHECK-NEXT: %b = sdiv i32 %a, 0 -; CHECK-NEXT: LLVM ERROR: Linter found errors, aborting. (enabled by --lint-abort-on-error) +; CHECK-NEXT: LLVM ERROR: linter found errors, aborting. (enabled by abort-on-error) define i32 @sdiv_by_zero(i32 %a) { %b = sdiv i32 %a, 0 diff --git a/llvm/test/Analysis/Lint/const-store.ll b/llvm/test/Analysis/Lint/const-store.ll index 030a0be3aecc2..748f752b2975f 100644 --- a/llvm/test/Analysis/Lint/const-store.ll +++ b/llvm/test/Analysis/Lint/const-store.ll @@ -1,6 +1,6 @@ -; RUN: not opt --mtriple=amdgcn --passes=lint --lint-abort-on-error %s -disable-output 2>&1 | FileCheck %s +; RUN: not opt --mtriple=amdgcn --passes='lint' %s -disable-output 2>&1 | FileCheck %s ; RUN: opt --mtriple=amdgcn --mcpu=gfx1030 --passes=lint %s -disable-output 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK0 -; RUN: opt --mtriple=x86_64 --passes=lint --lint-abort-on-error %s -disable-output 2>&1 | FileCheck %s --allow-empty --check-prefix=NOERR +; RUN: opt --mtriple=x86_64 --passes='lint' %s -disable-output 2>&1 | FileCheck %s --allow-empty --check-prefix=NOERR ; NOERR: {{^$}} define amdgpu_kernel void @store_const(ptr addrspace(4) %out, i32 %a, i32 %b) {