[llvm] c977139 - [NewPM][Lint] Port -lint to NewPM

Arthur Eubanks via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 3 13:06:10 PDT 2020


Author: Arthur Eubanks
Date: 2020-09-03T13:03:44-07:00
New Revision: c9771391ce05e5cba00e29017fd6c39157df3f3c

URL: https://github.com/llvm/llvm-project/commit/c9771391ce05e5cba00e29017fd6c39157df3f3c
DIFF: https://github.com/llvm/llvm-project/commit/c9771391ce05e5cba00e29017fd6c39157df3f3c.diff

LOG: [NewPM][Lint] Port -lint to NewPM

This also changes -lint from an analysis to a pass. It's similar to
-verify, and that is a normal pass, and lives in llvm/IR.

Reviewed By: ychen

Differential Revision: https://reviews.llvm.org/D87057

Added: 
    

Modified: 
    llvm/include/llvm/Analysis/Lint.h
    llvm/include/llvm/InitializePasses.h
    llvm/include/llvm/LinkAllPasses.h
    llvm/lib/Analysis/Analysis.cpp
    llvm/lib/Analysis/Lint.cpp
    llvm/lib/Passes/PassBuilder.cpp
    llvm/lib/Passes/PassRegistry.def
    llvm/test/Other/lint.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Analysis/Lint.h b/llvm/include/llvm/Analysis/Lint.h
index 0fea81e215c9..6eb637e72782 100644
--- a/llvm/include/llvm/Analysis/Lint.h
+++ b/llvm/include/llvm/Analysis/Lint.h
@@ -19,30 +19,30 @@
 #ifndef LLVM_ANALYSIS_LINT_H
 #define LLVM_ANALYSIS_LINT_H
 
+#include "llvm/IR/PassManager.h"
+
 namespace llvm {
 
 class FunctionPass;
 class Module;
 class Function;
 
-/// Create a lint pass.
-///
-/// Check a module or function.
-FunctionPass *createLintPass();
+FunctionPass *createLintLegacyPassPass();
 
-/// Check a module.
+/// Lint a module.
 ///
 /// This should only be used for debugging, because it plays games with
 /// PassManagers and stuff.
-void lintModule(
-  const Module &M    ///< The module to be checked
-);
+void lintModule(const Module &M);
+
+// 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<LintPass> {
+public:
+  PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
 
-} // End llvm namespace
+} // namespace llvm
 
-#endif
+#endif // LLVM_ANALYSIS_LINT_H

diff  --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h
index 7e512ba56c72..63ae19d8495d 100644
--- a/llvm/include/llvm/InitializePasses.h
+++ b/llvm/include/llvm/InitializePasses.h
@@ -218,7 +218,7 @@ void initializeLegalizerPass(PassRegistry&);
 void initializeGISelCSEAnalysisWrapperPassPass(PassRegistry &);
 void initializeGISelKnownBitsAnalysisPass(PassRegistry &);
 void initializeLibCallsShrinkWrapLegacyPassPass(PassRegistry&);
-void initializeLintPass(PassRegistry&);
+void initializeLintLegacyPassPass(PassRegistry &);
 void initializeLiveDebugValuesPass(PassRegistry&);
 void initializeLiveDebugVariablesPass(PassRegistry&);
 void initializeLiveIntervalsPass(PassRegistry&);

diff  --git a/llvm/include/llvm/LinkAllPasses.h b/llvm/include/llvm/LinkAllPasses.h
index dfd0e9c8da70..59284eecfbc7 100644
--- a/llvm/include/llvm/LinkAllPasses.h
+++ b/llvm/include/llvm/LinkAllPasses.h
@@ -203,7 +203,7 @@ namespace {
       (void) llvm::createPrintFunctionPass(os);
       (void) llvm::createModuleDebugInfoPrinterPass();
       (void) llvm::createPartialInliningPass();
-      (void) llvm::createLintPass();
+      (void) llvm::createLintLegacyPassPass();
       (void) llvm::createSinkingPass();
       (void) llvm::createLowerAtomicPass();
       (void) llvm::createCorrelatedValuePropagationPass();

diff  --git a/llvm/lib/Analysis/Analysis.cpp b/llvm/lib/Analysis/Analysis.cpp
index a9ece42df856..0496e23195d5 100644
--- a/llvm/lib/Analysis/Analysis.cpp
+++ b/llvm/lib/Analysis/Analysis.cpp
@@ -57,7 +57,7 @@ void llvm::initializeAnalysis(PassRegistry &Registry) {
   initializeLazyValueInfoWrapperPassPass(Registry);
   initializeLazyValueInfoPrinterPass(Registry);
   initializeLegacyDivergenceAnalysisPass(Registry);
-  initializeLintPass(Registry);
+  initializeLintLegacyPassPass(Registry);
   initializeLoopInfoWrapperPassPass(Registry);
   initializeMemDepPrinterPass(Registry);
   initializeMemDerefPrinterPass(Registry);

diff  --git a/llvm/lib/Analysis/Lint.cpp b/llvm/lib/Analysis/Lint.cpp
index 4a159d6035f0..04e04a8053e8 100644
--- a/llvm/lib/Analysis/Lint.cpp
+++ b/llvm/lib/Analysis/Lint.cpp
@@ -63,6 +63,7 @@
 #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"
@@ -80,134 +81,102 @@
 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
-
-  class Lint : public FunctionPass, public InstVisitor<Lint> {
-    friend class InstVisitor<Lint>;
-
-    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 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<Value *> &Visited) const;
-
-  public:
-    Module *Mod;
-    const DataLayout *DL;
-    AliasAnalysis *AA;
-    AssumptionCache *AC;
-    DominatorTree *DT;
-    TargetLibraryInfo *TLI;
-
-    std::string Messages;
-    raw_string_ostream MessagesStr;
-
-    static char ID; // Pass identification, replacement for typeid
-    Lint() : FunctionPass(ID), MessagesStr(Messages) {
-      initializeLintPass(*PassRegistry::getPassRegistry());
-    }
-
-    bool runOnFunction(Function &F) override;
-
-    void getAnalysisUsage(AnalysisUsage &AU) const override {
-      AU.setPreservesAll();
-      AU.addRequired<AAResultsWrapperPass>();
-      AU.addRequired<AssumptionCacheTracker>();
-      AU.addRequired<TargetLibraryInfoWrapperPass>();
-      AU.addRequired<DominatorTreeWrapperPass>();
-    }
-    void print(raw_ostream &O, const Module *M) const override {}
-
-    void WriteValues(ArrayRef<const Value *> Vs) {
-      for (const Value *V : Vs) {
-        if (!V)
-          continue;
-        if (isa<Instruction>(V)) {
-          MessagesStr << *V << '\n';
-        } else {
-          V->printAsOperand(MessagesStr, true, Mod);
-          MessagesStr << '\n';
-        }
+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<Lint> {
+  friend class InstVisitor<Lint>;
+
+  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 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<Value *> &Visited) const;
+
+public:
+  Module *Mod;
+  const DataLayout *DL;
+  AliasAnalysis *AA;
+  AssumptionCache *AC;
+  DominatorTree *DT;
+  TargetLibraryInfo *TLI;
+
+  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) {}
+
+  void WriteValues(ArrayRef<const Value *> Vs) {
+    for (const Value *V : Vs) {
+      if (!V)
+        continue;
+      if (isa<Instruction>(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 (with values to print).
-    ///
-    /// This calls the Message-only version so that the above is easier to set
-    /// a breakpoint on.
-    template <typename T1, typename... Ts>
-    void CheckFailed(const Twine &Message, const T1 &V1, const Ts &...Vs) {
-      CheckFailed(Message);
-      WriteValues({V1, Vs...});
-    }
-  };
+  /// 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 <typename T1, typename... Ts>
+  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)
-
-// 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<AAResultsWrapperPass>().getAAResults();
-  AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
-  DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
-  TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
-  visit(F);
-  dbgs() << MessagesStr.str();
-  Messages.clear();
-  return false;
-}
+#define Assert(C, ...)                                                         \
+  do {                                                                         \
+    if (!(C)) {                                                                \
+      CheckFailed(__VA_ARGS__);                                                \
+      return;                                                                  \
+    }                                                                          \
+  } while (false)
 
 void Lint::visitFunction(Function &F) {
   // This isn't undefined behavior, it's just a little unusual, and it's a
@@ -281,8 +250,7 @@ void Lint::visitCallBase(CallBase &I) {
 
         // Check that an sret argument points to valid memory.
         if (Formal->hasStructRetAttr() && Actual->getType()->isPointerTy()) {
-          Type *Ty =
-            cast<PointerType>(Formal->getType())->getElementType();
+          Type *Ty = cast<PointerType>(Formal->getType())->getElementType();
           visitMemoryReference(I, Actual, DL->getTypeStoreSize(Ty),
                                DL->getABITypeAlign(Ty), Ty,
                                MemRef::Read | MemRef::Write);
@@ -309,12 +277,12 @@ void Lint::visitCallBase(CallBase &I) {
     }
   }
 
-
   if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(&I))
     switch (II->getIntrinsicID()) {
-    default: break;
+    default:
+      break;
 
-    // TODO: Check more intrinsics
+      // TODO: Check more intrinsics
 
     case Intrinsic::memcpy: {
       MemCpyInst *MCI = cast<MemCpyInst>(&I);
@@ -553,7 +521,8 @@ static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT,
 
   VectorType *VecTy = dyn_cast<VectorType>(V->getType());
   if (!VecTy) {
-    KnownBits Known = computeKnownBits(V, DL, 0, AC, dyn_cast<Instruction>(V), DT);
+    KnownBits Known =
+        computeKnownBits(V, DL, 0, AC, dyn_cast<Instruction>(V), DT);
     return Known.isZero();
   }
 
@@ -682,11 +651,13 @@ 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<PHINode>(V)) {
@@ -696,8 +667,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<ExtractValueInst>(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<ConstantExpr>(V)) {
@@ -728,22 +699,75 @@ 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<AAManager>(F);
+  auto *AC = &AM.getResult<AssumptionAnalysis>(F);
+  auto *DT = &AM.getResult<DominatorTreeAnalysis>(F);
+  auto *TLI = &AM.getResult<TargetLibraryAnalysis>(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<AAResultsWrapperPass>();
+    AU.addRequired<AssumptionCacheTracker>();
+    AU.addRequired<TargetLibraryInfoWrapperPass>();
+    AU.addRequired<DominatorTreeWrapperPass>();
+  }
+  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<AAResultsWrapperPass>().getAAResults();
+  auto *AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
+  auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+  auto *TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().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 Lint();
-}
+FunctionPass *llvm::createLintLegacyPassPass() { return new LintLegacyPass(); }
 
 /// lintFunction - Check a function for errors, printing messages on stderr.
 ///
 void llvm::lintFunction(const Function &f) {
-  Function &F = const_cast<Function&>(f);
+  Function &F = const_cast<Function &>(f);
   assert(!F.isDeclaration() && "Cannot lint external functions");
 
   legacy::FunctionPassManager FPM(F.getParent());
-  Lint *V = new Lint();
+  auto *V = new LintLegacyPass();
   FPM.add(V);
   FPM.run(F);
 }
@@ -752,7 +776,7 @@ void llvm::lintFunction(const Function &f) {
 ///
 void llvm::lintModule(const Module &M) {
   legacy::PassManager PM;
-  Lint *V = new Lint();
+  auto *V = new LintLegacyPass();
   PM.add(V);
-  PM.run(const_cast<Module&>(M));
+  PM.run(const_cast<Module &>(M));
 }

diff  --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index 3a6b736dae3c..9df6a985789e 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -39,6 +39,7 @@
 #include "llvm/Analysis/InstCount.h"
 #include "llvm/Analysis/LazyCallGraph.h"
 #include "llvm/Analysis/LazyValueInfo.h"
+#include "llvm/Analysis/Lint.h"
 #include "llvm/Analysis/LoopAccessAnalysis.h"
 #include "llvm/Analysis/LoopCacheAnalysis.h"
 #include "llvm/Analysis/LoopInfo.h"

diff  --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index 12e04ad91128..b0d1d2a63a83 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -205,6 +205,7 @@ 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/llvm/test/Other/lint.ll b/llvm/test/Other/lint.ll
index 45c8bd55fa01..a156301c1c26 100644
--- a/llvm/test/Other/lint.ll
+++ b/llvm/test/Other/lint.ll
@@ -1,4 +1,5 @@
 ; 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()


        


More information about the llvm-commits mailing list