diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/opt/NewPMDriver.cpp | 12 | ||||
-rw-r--r-- | tools/opt/NewPMDriver.h | 7 | ||||
-rw-r--r-- | tools/opt/Passes.cpp | 32 | ||||
-rw-r--r-- | tools/opt/Passes.h | 3 | ||||
-rw-r--r-- | tools/opt/opt.cpp | 8 |
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; } |