diff --git a/include/llvm/IR/Lint.h b/include/llvm/Analysis/Lint.h similarity index 70% rename from include/llvm/IR/Lint.h rename to include/llvm/Analysis/Lint.h index cd3f69c64df..0fea81e215c 100644 --- a/include/llvm/IR/Lint.h +++ b/include/llvm/Analysis/Lint.h @@ -1,4 +1,4 @@ -//===-- llvm/IR/Lint.h - LLVM IR Lint ---------------------------*- C++ -*-===// +//===-- llvm/Analysis/Lint.h - LLVM IR Lint ---------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -16,10 +16,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_IR_LINT_H -#define LLVM_IR_LINT_H - -#include "llvm/IR/PassManager.h" +#ifndef LLVM_ANALYSIS_LINT_H +#define LLVM_ANALYSIS_LINT_H namespace llvm { @@ -32,20 +30,19 @@ class Function; /// Check a module or function. FunctionPass *createLintPass(); -/// Lint a module. +/// Check a module. /// /// 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 ///< The module to be checked +); -// Lint a function. -void lintFunction(const Function &F); +// lintFunction - Check a function. +void lintFunction( + const Function &F ///< The function to be checked +); -class LintPass : public PassInfoMixin { -public: - PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); -}; +} // End llvm namespace -} // namespace llvm - -#endif // LLVM_IR_LINT_H +#endif diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index 63ae19d8495..7e512ba56c7 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -218,7 +218,7 @@ void initializeLegalizerPass(PassRegistry&); void initializeGISelCSEAnalysisWrapperPassPass(PassRegistry &); void initializeGISelKnownBitsAnalysisPass(PassRegistry &); void initializeLibCallsShrinkWrapLegacyPassPass(PassRegistry&); -void initializeLintLegacyPassPass(PassRegistry &); +void initializeLintPass(PassRegistry&); void initializeLiveDebugValuesPass(PassRegistry&); void initializeLiveDebugVariablesPass(PassRegistry&); void initializeLiveIntervalsPass(PassRegistry&); diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h index c4bbbd513b2..dfd0e9c8da7 100644 --- a/include/llvm/LinkAllPasses.h +++ b/include/llvm/LinkAllPasses.h @@ -24,6 +24,7 @@ #include "llvm/Analysis/DomPrinter.h" #include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/IntervalPartition.h" +#include "llvm/Analysis/Lint.h" #include "llvm/Analysis/Passes.h" #include "llvm/Analysis/PostDominators.h" #include "llvm/Analysis/RegionPass.h" @@ -36,7 +37,6 @@ #include "llvm/CodeGen/Passes.h" #include "llvm/IR/Function.h" #include "llvm/IR/IRPrintingPasses.h" -#include "llvm/IR/Lint.h" #include "llvm/Support/Valgrind.h" #include "llvm/Transforms/AggressiveInstCombine/AggressiveInstCombine.h" #include "llvm/Transforms/IPO.h" diff --git a/lib/Analysis/Analysis.cpp b/lib/Analysis/Analysis.cpp index e0a4b9dd10a..a9ece42df85 100644 --- a/lib/Analysis/Analysis.cpp +++ b/lib/Analysis/Analysis.cpp @@ -57,6 +57,7 @@ void llvm::initializeAnalysis(PassRegistry &Registry) { initializeLazyValueInfoWrapperPassPass(Registry); initializeLazyValueInfoPrinterPass(Registry); initializeLegacyDivergenceAnalysisPass(Registry); + initializeLintPass(Registry); initializeLoopInfoWrapperPassPass(Registry); initializeMemDepPrinterPass(Registry); initializeMemDerefPrinterPass(Registry); diff --git a/lib/Analysis/CMakeLists.txt b/lib/Analysis/CMakeLists.txt index 06cc2ac900b..f50439bc876 100644 --- a/lib/Analysis/CMakeLists.txt +++ b/lib/Analysis/CMakeLists.txt @@ -69,6 +69,7 @@ add_llvm_component_library(LLVMAnalysis LazyCallGraph.cpp LazyValueInfo.cpp LegacyDivergenceAnalysis.cpp + Lint.cpp Loads.cpp LoopAccessAnalysis.cpp LoopAnalysisManager.cpp diff --git a/lib/IR/Lint.cpp b/lib/Analysis/Lint.cpp similarity index 81% rename from lib/IR/Lint.cpp rename to lib/Analysis/Lint.cpp index 4db508a01f0..4a159d6035f 100644 --- a/lib/IR/Lint.cpp +++ b/lib/Analysis/Lint.cpp @@ -33,7 +33,7 @@ // //===----------------------------------------------------------------------===// -#include "llvm/IR/Lint.h" +#include "llvm/Analysis/Lint.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallPtrSet.h" @@ -63,7 +63,6 @@ #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" -#include "llvm/IR/PassManager.h" #include "llvm/IR/Type.h" #include "llvm/IR/Value.h" #include "llvm/InitializePasses.h" @@ -81,102 +80,134 @@ using namespace llvm; namespace { -namespace MemRef { -static const unsigned Read = 1; -static const unsigned Write = 2; -static const unsigned Callee = 4; -static const unsigned Branchee = 8; -} // end namespace MemRef + namespace MemRef { + static const unsigned Read = 1; + static const unsigned Write = 2; + static const unsigned Callee = 4; + static const unsigned Branchee = 8; + } // end namespace MemRef -class Lint : public InstVisitor { - friend class InstVisitor; + class Lint : public FunctionPass, public InstVisitor { + friend class InstVisitor; - void visitFunction(Function &F); + void visitFunction(Function &F); - void visitCallBase(CallBase &CB); - void visitMemoryReference(Instruction &I, Value *Ptr, uint64_t Size, - MaybeAlign Alignment, Type *Ty, unsigned Flags); - void visitEHBeginCatch(IntrinsicInst *II); - void visitEHEndCatch(IntrinsicInst *II); + void visitCallBase(CallBase &CB); + void visitMemoryReference(Instruction &I, Value *Ptr, uint64_t Size, + MaybeAlign Alignment, Type *Ty, unsigned Flags); + void visitEHBeginCatch(IntrinsicInst *II); + void visitEHEndCatch(IntrinsicInst *II); - void visitReturnInst(ReturnInst &I); - void visitLoadInst(LoadInst &I); - void visitStoreInst(StoreInst &I); - void visitXor(BinaryOperator &I); - void visitSub(BinaryOperator &I); - void visitLShr(BinaryOperator &I); - void visitAShr(BinaryOperator &I); - void visitShl(BinaryOperator &I); - void visitSDiv(BinaryOperator &I); - void visitUDiv(BinaryOperator &I); - void visitSRem(BinaryOperator &I); - void visitURem(BinaryOperator &I); - void visitAllocaInst(AllocaInst &I); - void visitVAArgInst(VAArgInst &I); - void visitIndirectBrInst(IndirectBrInst &I); - void visitExtractElementInst(ExtractElementInst &I); - void visitInsertElementInst(InsertElementInst &I); - void visitUnreachableInst(UnreachableInst &I); + void visitReturnInst(ReturnInst &I); + void visitLoadInst(LoadInst &I); + void visitStoreInst(StoreInst &I); + void visitXor(BinaryOperator &I); + void visitSub(BinaryOperator &I); + void visitLShr(BinaryOperator &I); + void visitAShr(BinaryOperator &I); + void visitShl(BinaryOperator &I); + void visitSDiv(BinaryOperator &I); + void visitUDiv(BinaryOperator &I); + void visitSRem(BinaryOperator &I); + void visitURem(BinaryOperator &I); + void visitAllocaInst(AllocaInst &I); + void visitVAArgInst(VAArgInst &I); + void visitIndirectBrInst(IndirectBrInst &I); + void visitExtractElementInst(ExtractElementInst &I); + void visitInsertElementInst(InsertElementInst &I); + void visitUnreachableInst(UnreachableInst &I); - Value *findValue(Value *V, bool OffsetOk) const; - Value *findValueImpl(Value *V, bool OffsetOk, - SmallPtrSetImpl &Visited) const; + Value *findValue(Value *V, bool OffsetOk) const; + Value *findValueImpl(Value *V, bool OffsetOk, + SmallPtrSetImpl &Visited) const; -public: - Module *Mod; - const DataLayout *DL; - AliasAnalysis *AA; - AssumptionCache *AC; - DominatorTree *DT; - TargetLibraryInfo *TLI; + public: + Module *Mod; + const DataLayout *DL; + AliasAnalysis *AA; + AssumptionCache *AC; + DominatorTree *DT; + TargetLibraryInfo *TLI; - std::string Messages; - raw_string_ostream MessagesStr; + std::string Messages; + raw_string_ostream MessagesStr; - Lint(Module *Mod, const DataLayout *DL, AliasAnalysis *AA, - AssumptionCache *AC, DominatorTree *DT, TargetLibraryInfo *TLI) - : Mod(Mod), DL(DL), AA(AA), AC(AC), DT(DT), TLI(TLI), - MessagesStr(Messages) {} + static char ID; // Pass identification, replacement for typeid + Lint() : FunctionPass(ID), MessagesStr(Messages) { + initializeLintPass(*PassRegistry::getPassRegistry()); + } - void WriteValues(ArrayRef Vs) { - for (const Value *V : Vs) { - if (!V) - continue; - if (isa(V)) { - MessagesStr << *V << '\n'; - } else { - V->printAsOperand(MessagesStr, true, Mod); - MessagesStr << '\n'; + bool runOnFunction(Function &F) override; + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + AU.addRequired(); + AU.addRequired(); + AU.addRequired(); + AU.addRequired(); + } + void print(raw_ostream &O, const Module *M) const override {} + + void WriteValues(ArrayRef Vs) { + for (const Value *V : Vs) { + if (!V) + continue; + if (isa(V)) { + MessagesStr << *V << '\n'; + } else { + V->printAsOperand(MessagesStr, true, Mod); + MessagesStr << '\n'; + } } } - } - /// A check failed, so printout out the condition and the message. - /// - /// This provides a nice place to put a breakpoint if you want to see why - /// something is not correct. - void CheckFailed(const Twine &Message) { MessagesStr << Message << '\n'; } + /// A check failed, so printout out the condition and the message. + /// + /// This provides a nice place to put a breakpoint if you want to see why + /// something is not correct. + void CheckFailed(const Twine &Message) { MessagesStr << Message << '\n'; } - /// A check failed (with values to print). - /// - /// This calls the Message-only version so that the above is easier to set - /// a breakpoint on. - template - void CheckFailed(const Twine &Message, const T1 &V1, const Ts &... Vs) { - CheckFailed(Message); - WriteValues({V1, Vs...}); - } -}; + /// A check failed (with values to print). + /// + /// This calls the Message-only version so that the above is easier to set + /// a breakpoint on. + template + void CheckFailed(const Twine &Message, const T1 &V1, const Ts &...Vs) { + CheckFailed(Message); + WriteValues({V1, Vs...}); + } + }; } // end anonymous namespace +char Lint::ID = 0; +INITIALIZE_PASS_BEGIN(Lint, "lint", "Statically lint-checks LLVM IR", + false, true) +INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) +INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) +INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) +INITIALIZE_PASS_END(Lint, "lint", "Statically lint-checks LLVM IR", + false, true) + // Assert - We know that cond should be true, if not print an error message. -#define Assert(C, ...) \ - do { \ - if (!(C)) { \ - CheckFailed(__VA_ARGS__); \ - return; \ - } \ - } while (false) +#define Assert(C, ...) \ + do { if (!(C)) { CheckFailed(__VA_ARGS__); return; } } while (false) + +// Lint::run - This is the main Analysis entry point for a +// function. +// +bool Lint::runOnFunction(Function &F) { + Mod = F.getParent(); + DL = &F.getParent()->getDataLayout(); + AA = &getAnalysis().getAAResults(); + AC = &getAnalysis().getAssumptionCache(F); + DT = &getAnalysis().getDomTree(); + TLI = &getAnalysis().getTLI(F); + visit(F); + dbgs() << MessagesStr.str(); + Messages.clear(); + return false; +} void Lint::visitFunction(Function &F) { // This isn't undefined behavior, it's just a little unusual, and it's a @@ -250,7 +281,8 @@ void Lint::visitCallBase(CallBase &I) { // Check that an sret argument points to valid memory. if (Formal->hasStructRetAttr() && Actual->getType()->isPointerTy()) { - Type *Ty = cast(Formal->getType())->getElementType(); + Type *Ty = + cast(Formal->getType())->getElementType(); visitMemoryReference(I, Actual, DL->getTypeStoreSize(Ty), DL->getABITypeAlign(Ty), Ty, MemRef::Read | MemRef::Write); @@ -277,12 +309,12 @@ void Lint::visitCallBase(CallBase &I) { } } + if (IntrinsicInst *II = dyn_cast(&I)) switch (II->getIntrinsicID()) { - default: - break; + default: break; - // TODO: Check more intrinsics + // TODO: Check more intrinsics case Intrinsic::memcpy: { MemCpyInst *MCI = cast(&I); @@ -521,8 +553,7 @@ static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, VectorType *VecTy = dyn_cast(V->getType()); if (!VecTy) { - KnownBits Known = - computeKnownBits(V, DL, 0, AC, dyn_cast(V), DT); + KnownBits Known = computeKnownBits(V, DL, 0, AC, dyn_cast(V), DT); return Known.isZero(); } @@ -651,13 +682,11 @@ Value *Lint::findValueImpl(Value *V, bool OffsetOk, if (!VisitedBlocks.insert(BB).second) break; if (Value *U = - FindAvailableLoadedValue(L, BB, BBI, DefMaxInstsToScan, AA)) + FindAvailableLoadedValue(L, BB, BBI, DefMaxInstsToScan, AA)) return findValueImpl(U, OffsetOk, Visited); - if (BBI != BB->begin()) - break; + if (BBI != BB->begin()) break; BB = BB->getUniquePredecessor(); - if (!BB) - break; + if (!BB) break; BBI = BB->end(); } } else if (PHINode *PN = dyn_cast(V)) { @@ -667,8 +696,8 @@ Value *Lint::findValueImpl(Value *V, bool OffsetOk, if (CI->isNoopCast(*DL)) return findValueImpl(CI->getOperand(0), OffsetOk, Visited); } else if (ExtractValueInst *Ex = dyn_cast(V)) { - if (Value *W = - FindInsertedValue(Ex->getAggregateOperand(), Ex->getIndices())) + if (Value *W = FindInsertedValue(Ex->getAggregateOperand(), + Ex->getIndices())) if (W != V) return findValueImpl(W, OffsetOk, Visited); } else if (ConstantExpr *CE = dyn_cast(V)) { @@ -699,75 +728,22 @@ Value *Lint::findValueImpl(Value *V, bool OffsetOk, return V; } -PreservedAnalyses LintPass::run(Function &F, FunctionAnalysisManager &AM) { - auto *Mod = F.getParent(); - auto *DL = &F.getParent()->getDataLayout(); - auto *AA = &AM.getResult(F); - auto *AC = &AM.getResult(F); - auto *DT = &AM.getResult(F); - auto *TLI = &AM.getResult(F); - Lint L(Mod, DL, AA, AC, DT, TLI); - L.visit(F); - dbgs() << L.MessagesStr.str(); - return PreservedAnalyses::all(); -} - -class LintLegacyPass : public FunctionPass { -public: - static char ID; // Pass identification, replacement for typeid - LintLegacyPass() : FunctionPass(ID) { - initializeLintLegacyPassPass(*PassRegistry::getPassRegistry()); - } - - bool runOnFunction(Function &F) override; - - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.setPreservesAll(); - AU.addRequired(); - AU.addRequired(); - AU.addRequired(); - AU.addRequired(); - } - void print(raw_ostream &O, const Module *M) const override {} -}; - -char LintLegacyPass::ID = 0; -INITIALIZE_PASS_BEGIN(LintLegacyPass, "lint", "Statically lint-checks LLVM IR", - false, true) -INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) -INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) -INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) -INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) -INITIALIZE_PASS_END(LintLegacyPass, "lint", "Statically lint-checks LLVM IR", - false, true) - -bool LintLegacyPass::runOnFunction(Function &F) { - auto *Mod = F.getParent(); - auto *DL = &F.getParent()->getDataLayout(); - auto *AA = &getAnalysis().getAAResults(); - auto *AC = &getAnalysis().getAssumptionCache(F); - auto *DT = &getAnalysis().getDomTree(); - auto *TLI = &getAnalysis().getTLI(F); - Lint L(Mod, DL, AA, AC, DT, TLI); - L.visit(F); - dbgs() << L.MessagesStr.str(); - return false; -} - //===----------------------------------------------------------------------===// // Implement the public interfaces to this file... //===----------------------------------------------------------------------===// -FunctionPass *llvm::createLintPass() { return new LintLegacyPass(); } +FunctionPass *llvm::createLintPass() { + return new Lint(); +} /// lintFunction - Check a function for errors, printing messages on stderr. /// void llvm::lintFunction(const Function &f) { - Function &F = const_cast(f); + Function &F = const_cast(f); assert(!F.isDeclaration() && "Cannot lint external functions"); legacy::FunctionPassManager FPM(F.getParent()); - auto *V = new LintLegacyPass(); + Lint *V = new Lint(); FPM.add(V); FPM.run(F); } @@ -776,7 +752,7 @@ void llvm::lintFunction(const Function &f) { /// void llvm::lintModule(const Module &M) { legacy::PassManager PM; - auto *V = new LintLegacyPass(); + Lint *V = new Lint(); PM.add(V); - PM.run(const_cast(M)); + PM.run(const_cast(M)); } diff --git a/lib/IR/CMakeLists.txt b/lib/IR/CMakeLists.txt index 3dd49a60870..49805d5b8c2 100644 --- a/lib/IR/CMakeLists.txt +++ b/lib/IR/CMakeLists.txt @@ -32,7 +32,6 @@ add_llvm_component_library(LLVMCore LLVMContextImpl.cpp LLVMRemarkStreamer.cpp LegacyPassManager.cpp - Lint.cpp MDBuilder.cpp Mangler.cpp Metadata.cpp diff --git a/lib/IR/Core.cpp b/lib/IR/Core.cpp index 9403f9159cf..8598acc8280 100644 --- a/lib/IR/Core.cpp +++ b/lib/IR/Core.cpp @@ -26,7 +26,6 @@ #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/LegacyPassManager.h" -#include "llvm/IR/Lint.h" #include "llvm/IR/Module.h" #include "llvm/InitializePasses.h" #include "llvm/Support/Debug.h" @@ -47,7 +46,6 @@ using namespace llvm; void llvm::initializeCore(PassRegistry &Registry) { initializeDominatorTreeWrapperPassPass(Registry); - initializeLintLegacyPassPass(Registry); initializePrintModulePassWrapperPass(Registry); initializePrintFunctionPassWrapperPass(Registry); initializeSafepointIRVerifierPass(Registry); diff --git a/lib/Passes/PassBuilder.cpp b/lib/Passes/PassBuilder.cpp index 59632765829..3a6b736dae3 100644 --- a/lib/Passes/PassBuilder.cpp +++ b/lib/Passes/PassBuilder.cpp @@ -61,7 +61,6 @@ #include "llvm/Analysis/TypeBasedAliasAnalysis.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/IRPrintingPasses.h" -#include "llvm/IR/Lint.h" #include "llvm/IR/PassManager.h" #include "llvm/IR/SafepointIRVerifier.h" #include "llvm/IR/Verifier.h" diff --git a/lib/Passes/PassRegistry.def b/lib/Passes/PassRegistry.def index b0d1d2a63a8..12e04ad9112 100644 --- a/lib/Passes/PassRegistry.def +++ b/lib/Passes/PassRegistry.def @@ -205,7 +205,6 @@ FUNCTION_PASS("irce", IRCEPass()) FUNCTION_PASS("float2int", Float2IntPass()) FUNCTION_PASS("no-op-function", NoOpFunctionPass()) FUNCTION_PASS("libcalls-shrinkwrap", LibCallsShrinkWrapPass()) -FUNCTION_PASS("lint", LintPass()) FUNCTION_PASS("inject-tli-mappings", InjectTLIMappings()) FUNCTION_PASS("loweratomic", LowerAtomicPass()) FUNCTION_PASS("lower-expect", LowerExpectIntrinsicPass()) diff --git a/test/Other/lint.ll b/test/Other/lint.ll index a156301c1c2..45c8bd55fa0 100644 --- a/test/Other/lint.ll +++ b/test/Other/lint.ll @@ -1,5 +1,4 @@ ; RUN: opt -basic-aa -lint -disable-output < %s 2>&1 | FileCheck %s -; RUN: opt -aa-pipeline=basic-aa -passes=lint -disable-output < %s 2>&1 | FileCheck %s target datalayout = "e-p:64:64:64" declare fastcc void @bar() diff --git a/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn b/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn index 3ec2f15abd4..1c6d22dd672 100644 --- a/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn +++ b/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn @@ -67,6 +67,7 @@ static_library("Analysis") { "LazyCallGraph.cpp", "LazyValueInfo.cpp", "LegacyDivergenceAnalysis.cpp", + "Lint.cpp", "Loads.cpp", "LoopAccessAnalysis.cpp", "LoopAnalysisManager.cpp", diff --git a/utils/gn/secondary/llvm/lib/IR/BUILD.gn b/utils/gn/secondary/llvm/lib/IR/BUILD.gn index c9344805125..aa2631a9d22 100644 --- a/utils/gn/secondary/llvm/lib/IR/BUILD.gn +++ b/utils/gn/secondary/llvm/lib/IR/BUILD.gn @@ -47,7 +47,6 @@ static_library("IR") { "LLVMContextImpl.cpp", "LLVMRemarkStreamer.cpp", "LegacyPassManager.cpp", - "Lint.cpp", "MDBuilder.cpp", "Mangler.cpp", "Metadata.cpp",