[llvm] r199646 - [PM] Wire up the Verifier for the new pass manager and connect it to the

Chandler Carruth chandlerc at gmail.com
Mon Jan 20 03:34:09 PST 2014


Author: chandlerc
Date: Mon Jan 20 05:34:08 2014
New Revision: 199646

URL: http://llvm.org/viewvc/llvm-project?rev=199646&view=rev
Log:
[PM] Wire up the Verifier for the new pass manager and connect it to the
various opt verifier commandline options.

Mostly mechanical wiring of the verifier to the new pass manager.
Exercises one of the more unusual aspects of it -- a pass can be either
a module or function pass interchangably. If this is ever problematic,
we can make things more constrained, but for things like the verifier
where there is an "obvious" applicability at both levels, it seems
convenient.

This is the next-to-last piece of basic functionality left to make the
opt commandline driving of the new pass manager minimally functional for
testing and further development. There is still a lot to be done there
(notably the factoring into .def files to kill the current boilerplate
code) but it is relatively uninteresting. The only interesting bit left
for minimal functionality is supporting the registration of analyses.
I'm planning on doing that on top of the .def file switch mostly because
the boilerplate for the analyses would be significantly worse.

Modified:
    llvm/trunk/include/llvm/IR/Verifier.h
    llvm/trunk/include/llvm/InitializePasses.h
    llvm/trunk/lib/IR/Core.cpp
    llvm/trunk/lib/IR/Verifier.cpp
    llvm/trunk/test/Other/new-pass-manager.ll
    llvm/trunk/tools/opt/NewPMDriver.cpp
    llvm/trunk/tools/opt/NewPMDriver.h
    llvm/trunk/tools/opt/Passes.cpp
    llvm/trunk/tools/opt/Passes.h
    llvm/trunk/tools/opt/opt.cpp

Modified: llvm/trunk/include/llvm/IR/Verifier.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Verifier.h?rev=199646&r1=199645&r2=199646&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Verifier.h (original)
+++ llvm/trunk/include/llvm/IR/Verifier.h Mon Jan 20 05:34:08 2014
@@ -21,13 +21,15 @@
 #ifndef LLVM_IR_VERIFIER_H
 #define LLVM_IR_VERIFIER_H
 
+#include "llvm/ADT/StringRef.h"
 #include <string>
 
 namespace llvm {
 
+class Function;
 class FunctionPass;
 class Module;
-class Function;
+class PreservedAnalyses;
 class raw_ostream;
 
 /// \brief Check a function for errors, useful for use when debugging a
@@ -52,8 +54,22 @@ bool verifyModule(const Module &M, raw_o
 /// functionality. When the pass detects a verification error it is always
 /// printed to stderr, and by default they are fatal. You can override that by
 /// passing \c false to \p FatalErrors.
+///
+/// Note that this creates a pass suitable for the legacy pass manager. It has nothing to do with \c VerifierPass.
 FunctionPass *createVerifierPass(bool FatalErrors = true);
 
+class VerifierPass {
+  bool FatalErrors;
+
+public:
+  explicit VerifierPass(bool FatalErrors = true) : FatalErrors(FatalErrors) {}
+
+  PreservedAnalyses run(Module *M);
+  PreservedAnalyses run(Function *F);
+
+  static StringRef name() { return "VerifierPass"; }
+};
+
 } // End llvm namespace
 
 #endif

Modified: llvm/trunk/include/llvm/InitializePasses.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=199646&r1=199645&r2=199646&view=diff
==============================================================================
--- llvm/trunk/include/llvm/InitializePasses.h (original)
+++ llvm/trunk/include/llvm/InitializePasses.h Mon Jan 20 05:34:08 2014
@@ -256,7 +256,7 @@ void initializeTypeBasedAliasAnalysisPas
 void initializeUnifyFunctionExitNodesPass(PassRegistry&);
 void initializeUnreachableBlockElimPass(PassRegistry&);
 void initializeUnreachableMachineBlockElimPass(PassRegistry&);
-void initializeVerifierPassPass(PassRegistry&);
+void initializeVerifierLegacyPassPass(PassRegistry&);
 void initializeVirtRegMapPass(PassRegistry&);
 void initializeVirtRegRewriterPass(PassRegistry&);
 void initializeInstSimplifierPass(PassRegistry&);

Modified: llvm/trunk/lib/IR/Core.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Core.cpp?rev=199646&r1=199645&r2=199646&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Core.cpp (original)
+++ llvm/trunk/lib/IR/Core.cpp Mon Jan 20 05:34:08 2014
@@ -44,7 +44,7 @@ void llvm::initializeCore(PassRegistry &
   initializePrintModulePassWrapperPass(Registry);
   initializePrintFunctionPassWrapperPass(Registry);
   initializePrintBasicBlockPassPass(Registry);
-  initializeVerifierPassPass(Registry);
+  initializeVerifierLegacyPassPass(Registry);
 }
 
 void LLVMInitializeCore(LLVMPassRegistryRef R) {

Modified: llvm/trunk/lib/IR/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=199646&r1=199645&r2=199646&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Verifier.cpp (original)
+++ llvm/trunk/lib/IR/Verifier.cpp Mon Jan 20 05:34:08 2014
@@ -62,9 +62,9 @@
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Metadata.h"
 #include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
 #include "llvm/InstVisitor.h"
 #include "llvm/Pass.h"
-#include "llvm/PassManager.h"
 #include "llvm/Support/CFG.h"
 #include "llvm/Support/CallSite.h"
 #include "llvm/Support/CommandLine.h"
@@ -2387,18 +2387,18 @@ bool llvm::verifyModule(const Module &M,
 }
 
 namespace {
-struct VerifierPass : public FunctionPass {
+struct VerifierLegacyPass : public FunctionPass {
   static char ID;
 
   Verifier V;
   bool FatalErrors;
 
-  VerifierPass() : FunctionPass(ID), FatalErrors(true) {
-    initializeVerifierPassPass(*PassRegistry::getPassRegistry());
+  VerifierLegacyPass() : FunctionPass(ID), FatalErrors(true) {
+    initializeVerifierLegacyPassPass(*PassRegistry::getPassRegistry());
   }
-  explicit VerifierPass(bool FatalErrors)
+  explicit VerifierLegacyPass(bool FatalErrors)
       : FunctionPass(ID), V(dbgs()), FatalErrors(FatalErrors) {
-    initializeVerifierPassPass(*PassRegistry::getPassRegistry());
+    initializeVerifierLegacyPassPass(*PassRegistry::getPassRegistry());
   }
 
   bool runOnFunction(Function &F) {
@@ -2421,10 +2421,23 @@ struct VerifierPass : public FunctionPas
 };
 }
 
-char VerifierPass::ID = 0;
-INITIALIZE_PASS(VerifierPass, "verify", "Module Verifier", false, false)
+char VerifierLegacyPass::ID = 0;
+INITIALIZE_PASS(VerifierLegacyPass, "verify", "Module Verifier", false, false)
 
 FunctionPass *llvm::createVerifierPass(bool FatalErrors) {
-  return new VerifierPass(FatalErrors);
+  return new VerifierLegacyPass(FatalErrors);
 }
 
+PreservedAnalyses VerifierPass::run(Module *M) {
+  if (verifyModule(*M, &dbgs()) && FatalErrors)
+    report_fatal_error("Broken module found, compilation aborted!");
+
+  return PreservedAnalyses::all();
+}
+
+PreservedAnalyses VerifierPass::run(Function *F) {
+  if (verifyFunction(*F, &dbgs()) && FatalErrors)
+    report_fatal_error("Broken function found, compilation aborted!");
+
+  return PreservedAnalyses::all();
+}

Modified: llvm/trunk/test/Other/new-pass-manager.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/new-pass-manager.ll?rev=199646&r1=199645&r2=199646&view=diff
==============================================================================
--- llvm/trunk/test/Other/new-pass-manager.ll (original)
+++ llvm/trunk/test/Other/new-pass-manager.ll Mon Jan 20 05:34:08 2014
@@ -8,19 +8,23 @@
 ; RUN: opt -disable-output -debug-pass-manager -passes=print %s 2>&1 \
 ; RUN:     | FileCheck %s --check-prefix=CHECK-MODULE-PRINT
 ; CHECK-MODULE-PRINT: Starting module pass manager
+; CHECK-MODULE-PRINT: Running module pass: VerifierPass
 ; CHECK-MODULE-PRINT: Running module pass: PrintModulePass
 ; CHECK-MODULE-PRINT: ModuleID
 ; CHECK-MODULE-PRINT: define void @foo()
+; CHECK-MODULE-PRINT: Running module pass: VerifierPass
 ; CHECK-MODULE-PRINT: Finished module pass manager
 
 ; RUN: opt -disable-output -debug-pass-manager -passes='function(print)' %s 2>&1 \
 ; RUN:     | FileCheck %s --check-prefix=CHECK-FUNCTION-PRINT
 ; CHECK-FUNCTION-PRINT: Starting module pass manager
+; CHECK-FUNCTION-PRINT: Running module pass: VerifierPass
 ; CHECK-FUNCTION-PRINT: Starting function pass manager
 ; CHECK-FUNCTION-PRINT: Running function pass: PrintFunctionPass
 ; CHECK-FUNCTION-PRINT-NOT: ModuleID
 ; CHECK-FUNCTION-PRINT: define void @foo()
 ; CHECK-FUNCTION-PRINT: Finished function pass manager
+; CHECK-FUNCTION-PRINT: Running module pass: VerifierPass
 ; CHECK-FUNCTION-PRINT: Finished module pass manager
 
 ; RUN: opt -S -o - -passes='no-op-module,no-op-module' %s \
@@ -34,6 +38,32 @@
 ; RUN:     | llvm-dis \
 ; RUN:     | FileCheck %s --check-prefix=CHECK-NOOP
 
+; RUN: opt -disable-output -debug-pass-manager -verify-each -passes='no-op-module,function(no-op-function)' %s 2>&1 \
+; RUN:     | FileCheck %s --check-prefix=CHECK-VERIFY-EACH
+; CHECK-VERIFY-EACH: Starting module pass manager
+; CHECK-VERIFY-EACH: Running module pass: VerifierPass
+; CHECK-VERIFY-EACH: Running module pass: NoOpModulePass
+; CHECK-VERIFY-EACH: Running module pass: VerifierPass
+; CHECK-VERIFY-EACH: Starting function pass manager
+; CHECK-VERIFY-EACH: Running function pass: NoOpFunctionPass
+; CHECK-VERIFY-EACH: Running function pass: VerifierPass
+; CHECK-VERIFY-EACH: Finished function pass manager
+; CHECK-VERIFY-EACH: Running module pass: VerifierPass
+; CHECK-VERIFY-EACH: Finished module pass manager
+
+; RUN: opt -disable-output -debug-pass-manager -disable-verify -passes='no-op-module,function(no-op-function)' %s 2>&1 \
+; RUN:     | FileCheck %s --check-prefix=CHECK-NO-VERIFY
+; CHECK-NO-VERIFY: Starting module pass manager
+; CHECK-NO-VERIFY-NOT: VerifierPass
+; CHECK-NO-VERIFY: Running module pass: NoOpModulePass
+; CHECK-NO-VERIFY-NOT: VerifierPass
+; CHECK-NO-VERIFY: Starting function pass manager
+; CHECK-NO-VERIFY: Running function pass: NoOpFunctionPass
+; CHECK-NO-VERIFY-NOT: VerifierPass
+; CHECK-NO-VERIFY: Finished function pass manager
+; CHECK-NO-VERIFY-NOT: VerifierPass
+; CHECK-NO-VERIFY: Finished module pass manager
+
 define void @foo() {
   ret void
 }

Modified: llvm/trunk/tools/opt/NewPMDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/NewPMDriver.cpp?rev=199646&r1=199645&r2=199646&view=diff
==============================================================================
--- llvm/trunk/tools/opt/NewPMDriver.cpp (original)
+++ llvm/trunk/tools/opt/NewPMDriver.cpp Mon Jan 20 05:34:08 2014
@@ -21,6 +21,7 @@
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/PassManager.h"
+#include "llvm/IR/Verifier.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/ToolOutputFile.h"
@@ -30,13 +31,20 @@ using namespace opt_tool;
 
 bool llvm::runPassPipeline(StringRef Arg0, LLVMContext &Context, Module &M,
                            tool_output_file *Out, StringRef PassPipeline,
-                           OutputKind OK) {
+                           OutputKind OK, VerifierKind VK) {
   ModulePassManager MPM;
-  if (!parsePassPipeline(MPM, PassPipeline)) {
+
+  if (VK > VK_NoVerifier)
+    MPM.addPass(VerifierPass());
+
+  if (!parsePassPipeline(MPM, PassPipeline, VK == VK_VerifyEachPass)) {
     errs() << Arg0 << ": unable to parse pass pipeline description.\n";
     return false;
   }
 
+  if (VK > VK_NoVerifier)
+    MPM.addPass(VerifierPass());
+
   // Add any relevant output pass at the end of the pipeline.
   switch (OK) {
   case OK_NoOutput:

Modified: llvm/trunk/tools/opt/NewPMDriver.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/NewPMDriver.h?rev=199646&r1=199645&r2=199646&view=diff
==============================================================================
--- llvm/trunk/tools/opt/NewPMDriver.h (original)
+++ llvm/trunk/tools/opt/NewPMDriver.h Mon Jan 20 05:34:08 2014
@@ -34,6 +34,11 @@ enum OutputKind {
   OK_OutputAssembly,
   OK_OutputBitcode
 };
+enum VerifierKind {
+  VK_NoVerifier,
+  VK_VerifyInAndOut,
+  VK_VerifyEachPass
+};
 }
 
 /// \brief Driver function to run the new pass manager over a module.
@@ -44,7 +49,7 @@ enum OutputKind {
 /// when the transition finishes.
 bool runPassPipeline(StringRef Arg0, LLVMContext &Context, Module &M,
                      tool_output_file *Out, StringRef PassPipeline,
-                     opt_tool::OutputKind OK);
+                     opt_tool::OutputKind OK, opt_tool::VerifierKind VK);
 }
 
 #endif

Modified: llvm/trunk/tools/opt/Passes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/Passes.cpp?rev=199646&r1=199645&r2=199646&view=diff
==============================================================================
--- llvm/trunk/tools/opt/Passes.cpp (original)
+++ llvm/trunk/tools/opt/Passes.cpp Mon Jan 20 05:34:08 2014
@@ -17,6 +17,7 @@
 #include "Passes.h"
 #include "llvm/IR/IRPrintingPasses.h"
 #include "llvm/IR/PassManager.h"
+#include "llvm/IR/Verifier.h"
 #include "llvm/Support/Debug.h"
 
 using namespace llvm;
@@ -78,7 +79,8 @@ static bool parseFunctionPassName(Functi
 }
 
 static bool parseFunctionPassPipeline(FunctionPassManager &FPM,
-                                      StringRef &PipelineText) {
+                                      StringRef &PipelineText,
+                                      bool VerifyEachPass) {
   for (;;) {
     // Parse nested pass managers by recursing.
     if (PipelineText.startswith("function(")) {
@@ -86,7 +88,7 @@ static bool parseFunctionPassPipeline(Fu
 
       // Parse the inner pipeline inte the nested manager.
       PipelineText = PipelineText.substr(strlen("function("));
-      if (!parseFunctionPassPipeline(NestedFPM, PipelineText) ||
+      if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) ||
           PipelineText.empty())
         return false;
       assert(PipelineText[0] == ')');
@@ -99,6 +101,8 @@ static bool parseFunctionPassPipeline(Fu
       size_t End = PipelineText.find_first_of(",)");
       if (!parseFunctionPassName(FPM, PipelineText.substr(0, End)))
         return false;
+      if (VerifyEachPass)
+        FPM.addPass(VerifierPass());
 
       PipelineText = PipelineText.substr(End);
     }
@@ -112,7 +116,8 @@ static bool parseFunctionPassPipeline(Fu
 }
 
 static bool parseModulePassPipeline(ModulePassManager &MPM,
-                                    StringRef &PipelineText) {
+                                    StringRef &PipelineText,
+                                    bool VerifyEachPass) {
   for (;;) {
     // Parse nested pass managers by recursing.
     if (PipelineText.startswith("module(")) {
@@ -120,7 +125,7 @@ static bool parseModulePassPipeline(Modu
 
       // Parse the inner pipeline into the nested manager.
       PipelineText = PipelineText.substr(strlen("module("));
-      if (!parseModulePassPipeline(NestedMPM, PipelineText) ||
+      if (!parseModulePassPipeline(NestedMPM, PipelineText, VerifyEachPass) ||
           PipelineText.empty())
         return false;
       assert(PipelineText[0] == ')');
@@ -133,7 +138,7 @@ static bool parseModulePassPipeline(Modu
 
       // Parse the inner pipeline inte the nested manager.
       PipelineText = PipelineText.substr(strlen("function("));
-      if (!parseFunctionPassPipeline(NestedFPM, PipelineText) ||
+      if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) ||
           PipelineText.empty())
         return false;
       assert(PipelineText[0] == ')');
@@ -146,6 +151,8 @@ static bool parseModulePassPipeline(Modu
       size_t End = PipelineText.find_first_of(",)");
       if (!parseModulePassName(MPM, PipelineText.substr(0, End)))
         return false;
+      if (VerifyEachPass)
+        MPM.addPass(VerifierPass());
 
       PipelineText = PipelineText.substr(End);
     }
@@ -161,13 +168,16 @@ static bool parseModulePassPipeline(Modu
 // Primary pass pipeline description parsing routine.
 // FIXME: Should this routine accept a TargetMachine or require the caller to
 // pre-populate the analysis managers with target-specific stuff?
-bool llvm::parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText) {
+bool llvm::parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText,
+                             bool VerifyEachPass) {
   // Look at the first entry to figure out which layer to start parsing at.
   if (PipelineText.startswith("module("))
-    return parseModulePassPipeline(MPM, PipelineText) && PipelineText.empty();
+    return parseModulePassPipeline(MPM, PipelineText, VerifyEachPass) &&
+           PipelineText.empty();
   if (PipelineText.startswith("function(")) {
     FunctionPassManager FPM;
-    if (!parseFunctionPassPipeline(FPM, PipelineText) || !PipelineText.empty())
+    if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) ||
+        !PipelineText.empty())
       return false;
     MPM.addPass(createModuleToFunctionPassAdaptor(FPM));
     return true;
@@ -177,11 +187,13 @@ bool llvm::parsePassPipeline(ModulePassM
   StringRef FirstName =
       PipelineText.substr(0, PipelineText.find_first_of(",)"));
   if (isModulePassName(FirstName))
-    return parseModulePassPipeline(MPM, PipelineText) && PipelineText.empty();
+    return parseModulePassPipeline(MPM, PipelineText, VerifyEachPass) &&
+           PipelineText.empty();
 
   if (isFunctionPassName(FirstName)) {
     FunctionPassManager FPM;
-    if (!parseFunctionPassPipeline(FPM, PipelineText) || !PipelineText.empty())
+    if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) ||
+        !PipelineText.empty())
       return false;
     MPM.addPass(createModuleToFunctionPassAdaptor(FPM));
     return true;

Modified: llvm/trunk/tools/opt/Passes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/Passes.h?rev=199646&r1=199645&r2=199646&view=diff
==============================================================================
--- llvm/trunk/tools/opt/Passes.h (original)
+++ llvm/trunk/tools/opt/Passes.h Mon Jan 20 05:34:08 2014
@@ -49,7 +49,8 @@ class ModulePassManager;
 /// the sequence of passes aren't all the exact same kind of pass, it will be
 /// an error. You cannot mix different levels implicitly, you must explicitly
 /// form a pass manager in which to nest passes.
-bool parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText);
+bool parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText,
+                       bool VerifyEachPass = true);
 
 }
 

Modified: llvm/trunk/tools/opt/opt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/opt.cpp?rev=199646&r1=199645&r2=199646&view=diff
==============================================================================
--- llvm/trunk/tools/opt/opt.cpp (original)
+++ llvm/trunk/tools/opt/opt.cpp Mon Jan 20 05:34:08 2014
@@ -676,11 +676,17 @@ int main(int argc, char **argv) {
     if (!NoOutput)
       OK = OutputAssembly ? OK_OutputAssembly : OK_OutputBitcode;
 
+    VerifierKind VK = VK_VerifyInAndOut;
+    if (NoVerify)
+      VK = VK_NoVerifier;
+    else if (VerifyEach)
+      VK = VK_VerifyEachPass;
+
     // The user has asked to use the new pass manager and provided a pipeline
     // string. Hand off the rest of the functionality to the new code for that
     // layer.
     return runPassPipeline(argv[0], Context, *M.get(), Out.get(), PassPipeline,
-                           OK)
+                           OK, VK)
                ? 0
                : 1;
   }





More information about the llvm-commits mailing list