summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
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;
}