IR: Use a single ModuleSlotTracker in the Verifier
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>
Wed, 20 Apr 2016 17:27:44 +0000 (17:27 +0000)
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>
Wed, 20 Apr 2016 17:27:44 +0000 (17:27 +0000)
Speed up Verifier output by sharing a single ModuleSlotTracker for the
duration.  There should be no functionality change here except for much
faster output when there's more than one statement.

Now the Verifier won't be traversing the full Metadata graph every time
it prints an error.  The TypePrinter is still not shared, but that would
take some extra plumbing.

llvm-svn: 266889

llvm/include/llvm/IR/Metadata.h
llvm/lib/IR/AsmWriter.cpp
llvm/lib/IR/Verifier.cpp

index c2558d0..064ec46 100644 (file)
@@ -1269,6 +1269,8 @@ public:
   void setOperand(unsigned I, MDNode *New);
   StringRef getName() const;
   void print(raw_ostream &ROS, bool IsForDebug = false) const;
+  void print(raw_ostream &ROS, ModuleSlotTracker &MST,
+             bool IsForDebug = false) const;
   void dump() const;
 
   // ---------------------------------------------------------------------------
index ee805bf..916f90f 100644 (file)
@@ -3269,6 +3269,22 @@ void NamedMDNode::print(raw_ostream &ROS, bool IsForDebug) const {
   W.printNamedMDNode(this);
 }
 
+void NamedMDNode::print(raw_ostream &ROS, ModuleSlotTracker &MST,
+                        bool IsForDebug) const {
+  Optional<SlotTracker> LocalST;
+  SlotTracker *SlotTable;
+  if (auto *ST = MST.getMachine())
+    SlotTable = ST;
+  else {
+    LocalST.emplace(getParent());
+    SlotTable = &*LocalST;
+  }
+
+  formatted_raw_ostream OS(ROS);
+  AssemblyWriter W(OS, *SlotTable, getParent(), nullptr, IsForDebug);
+  W.printNamedMDNode(this);
+}
+
 void Comdat::print(raw_ostream &ROS, bool /*IsForDebug*/) const {
   PrintLLVMName(ROS, getName(), ComdatPrefix);
   ROS << " = comdat ";
index 655032e..f010fd3 100644 (file)
@@ -67,6 +67,7 @@
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Metadata.h"
 #include "llvm/IR/Module.h"
+#include "llvm/IR/ModuleSlotTracker.h"
 #include "llvm/IR/PassManager.h"
 #include "llvm/IR/Statepoint.h"
 #include "llvm/Pass.h"
@@ -84,6 +85,7 @@ namespace {
 struct VerifierSupport {
   raw_ostream *OS;
   const Module *M = nullptr;
+  Optional<ModuleSlotTracker> MST;
 
   /// Track the brokenness of the module while recursively visiting.
   bool Broken = false;
@@ -105,9 +107,10 @@ private:
     if (!V)
       return;
     if (isa<Instruction>(V)) {
-      *OS << *V << '\n';
+      V->print(*OS, *MST);
+      *OS << '\n';
     } else {
-      V->printAsOperand(*OS, true, M);
+      V->printAsOperand(*OS, true, *MST);
       *OS << '\n';
     }
   }
@@ -118,7 +121,7 @@ private:
   void Write(const Metadata *MD) {
     if (!MD)
       return;
-    MD->print(*OS, M);
+    MD->print(*OS, *MST, M);
     *OS << '\n';
   }
 
@@ -129,7 +132,7 @@ private:
   void Write(const NamedMDNode *NMD) {
     if (!NMD)
       return;
-    NMD->print(*OS);
+    NMD->print(*OS, *MST);
     *OS << '\n';
   }
 
@@ -229,13 +232,21 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
 
   void checkAtomicMemAccessSize(const Module *M, Type *Ty,
                                 const Instruction *I);
+
+  void updateModule(const Module *NewM) {
+    if (M == NewM)
+      return;
+    MST.emplace(NewM);
+    M = NewM;
+  }
+
 public:
   explicit Verifier(raw_ostream *OS)
       : VerifierSupport(OS), Context(nullptr), LandingPadResultTy(nullptr),
         SawFrameEscape(false) {}
 
   bool verify(const Function &F) {
-    M = F.getParent();
+    updateModule(F.getParent());
     Context = &M->getContext();
 
     // First ensure the function is well-enough formed to compute dominance
@@ -278,7 +289,7 @@ public:
   }
 
   bool verify(const Module &M) {
-    this->M = &M;
+    updateModule(&M);
     Context = &M.getContext();
     Broken = false;