summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2014-01-20 11:34:08 +0000
committerChandler Carruth <chandlerc@gmail.com>2014-01-20 11:34:08 +0000
commit1d9ab2556024514c403135bb8fe5da34fc4f0c63 (patch)
tree527695cc0c1fb52c6e85df1a39bdb48cd60bb516 /tools
parent843fa74d3851e93abf5f534f9a98021282ab3dbd (diff)
downloadllvm-1d9ab2556024514c403135bb8fe5da34fc4f0c63.tar.gz
llvm-1d9ab2556024514c403135bb8fe5da34fc4f0c63.tar.bz2
llvm-1d9ab2556024514c403135bb8fe5da34fc4f0c63.tar.xz
[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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199646 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools')
-rw-r--r--tools/opt/NewPMDriver.cpp12
-rw-r--r--tools/opt/NewPMDriver.h7
-rw-r--r--tools/opt/Passes.cpp32
-rw-r--r--tools/opt/Passes.h3
-rw-r--r--tools/opt/opt.cpp8
5 files changed, 47 insertions, 15 deletions
diff --git a/tools/opt/NewPMDriver.cpp b/tools/opt/NewPMDriver.cpp
index 2d210387f8..f21a68fc8a 100644
--- a/tools/opt/NewPMDriver.cpp
+++ b/tools/opt/NewPMDriver.cpp
@@ -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:
diff --git a/tools/opt/NewPMDriver.h b/tools/opt/NewPMDriver.h
index 2ae1ad5d83..3661d3e677 100644
--- a/tools/opt/NewPMDriver.h
+++ b/tools/opt/NewPMDriver.h
@@ -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
diff --git a/tools/opt/Passes.cpp b/tools/opt/Passes.cpp
index e79ac422eb..36fe6ad126 100644
--- a/tools/opt/Passes.cpp
+++ b/tools/opt/Passes.cpp
@@ -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(FunctionPassManager &FPM, StringRef Name) {
}
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(FunctionPassManager &FPM,
// 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(FunctionPassManager &FPM,
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(FunctionPassManager &FPM,
}
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(ModulePassManager &MPM,
// 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(ModulePassManager &MPM,
// 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(ModulePassManager &MPM,
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(ModulePassManager &MPM,
// 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(ModulePassManager &MPM, StringRef PipelineText) {
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;
diff --git a/tools/opt/Passes.h b/tools/opt/Passes.h
index 6016b74c80..3bd6752692 100644
--- a/tools/opt/Passes.h
+++ b/tools/opt/Passes.h
@@ -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);
}
diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp
index ef8c504d0f..782cac213f 100644
--- a/tools/opt/opt.cpp
+++ b/tools/opt/opt.cpp
@@ -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;
}