X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=tools%2Fopt%2FPasses.cpp;h=a171f42691a873ca1ff9cb2a89eca2b40caef116;hb=5f3f254ed1d601c60d03e4437f75783774b03583;hp=4a6341d5123757fbdc2d1de65ac95aeb64cb83c2;hpb=e7687650c9ff5e52f572d8e70752f7c808ca707e;p=oota-llvm.git diff --git a/tools/opt/Passes.cpp b/tools/opt/Passes.cpp index 4a6341d5123..a171f42691a 100644 --- a/tools/opt/Passes.cpp +++ b/tools/opt/Passes.cpp @@ -15,7 +15,12 @@ //===----------------------------------------------------------------------===// #include "Passes.h" +#include "llvm/Analysis/CGSCCPassManager.h" +#include "llvm/Analysis/LazyCallGraph.h" +#include "llvm/IR/IRPrintingPasses.h" #include "llvm/IR/PassManager.h" +#include "llvm/IR/Verifier.h" +#include "llvm/Support/Debug.h" using namespace llvm; @@ -27,6 +32,14 @@ struct NoOpModulePass { static StringRef name() { return "NoOpModulePass"; } }; +/// \brief No-op CGSCC pass which does nothing. +struct NoOpCGSCCPass { + PreservedAnalyses run(LazyCallGraph::SCC *C) { + return PreservedAnalyses::all(); + } + static StringRef name() { return "NoOpCGSCCPass"; } +}; + /// \brief No-op function pass which does nothing. struct NoOpFunctionPass { PreservedAnalyses run(Function *F) { return PreservedAnalyses::all(); } @@ -35,40 +48,84 @@ struct NoOpFunctionPass { } // End anonymous namespace. -// FIXME: Factor all of the parsing logic into a .def file that we include -// under different macros. static bool isModulePassName(StringRef Name) { if (Name == "no-op-module") return true; +#define MODULE_PASS(NAME, CREATE_PASS) if (Name == NAME) return true; +#include "PassRegistry.def" + + return false; +} + +static bool isCGSCCPassName(StringRef Name) { + if (Name == "no-op-cgscc") return true; + +#define CGSCC_PASS(NAME, CREATE_PASS) if (Name == NAME) return true; +#include "PassRegistry.def" + return false; } static bool isFunctionPassName(StringRef Name) { if (Name == "no-op-function") return true; +#define FUNCTION_PASS(NAME, CREATE_PASS) if (Name == NAME) return true; +#include "PassRegistry.def" + return false; } static bool parseModulePassName(ModulePassManager &MPM, StringRef Name) { - assert(isModulePassName(Name)); if (Name == "no-op-module") { MPM.addPass(NoOpModulePass()); return true; } + +#define MODULE_PASS(NAME, CREATE_PASS) \ + if (Name == NAME) { \ + MPM.addPass(CREATE_PASS); \ + return true; \ + } +#include "PassRegistry.def" + + return false; +} + +static bool parseCGSCCPassName(CGSCCPassManager &CGPM, StringRef Name) { + if (Name == "no-op-cgscc") { + CGPM.addPass(NoOpCGSCCPass()); + return true; + } + +#define CGSCC_PASS(NAME, CREATE_PASS) \ + if (Name == NAME) { \ + CGPM.addPass(CREATE_PASS); \ + return true; \ + } +#include "PassRegistry.def" + return false; } static bool parseFunctionPassName(FunctionPassManager &FPM, StringRef Name) { - assert(isFunctionPassName(Name)); if (Name == "no-op-function") { FPM.addPass(NoOpFunctionPass()); return true; } + +#define FUNCTION_PASS(NAME, CREATE_PASS) \ + if (Name == NAME) { \ + FPM.addPass(CREATE_PASS); \ + return true; \ + } +#include "PassRegistry.def" + return false; } static bool parseFunctionPassPipeline(FunctionPassManager &FPM, - StringRef &PipelineText) { + StringRef &PipelineText, + bool VerifyEachPass) { for (;;) { // Parse nested pass managers by recursing. if (PipelineText.startswith("function(")) { @@ -76,18 +133,70 @@ 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.empty() && PipelineText[0] == ')'); + assert(PipelineText[0] == ')'); PipelineText = PipelineText.substr(1); // Add the nested pass manager with the appropriate adaptor. - FPM.addPass(NestedFPM); + FPM.addPass(std::move(NestedFPM)); } else { // Otherwise try to parse a pass name. 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); + } + + if (PipelineText.empty() || PipelineText[0] == ')') + return true; + + assert(PipelineText[0] == ','); + PipelineText = PipelineText.substr(1); + } +} + +static bool parseCGSCCPassPipeline(CGSCCPassManager &CGPM, + StringRef &PipelineText, + bool VerifyEachPass) { + for (;;) { + // Parse nested pass managers by recursing. + if (PipelineText.startswith("cgscc(")) { + CGSCCPassManager NestedCGPM; + + // Parse the inner pipeline into the nested manager. + PipelineText = PipelineText.substr(strlen("cgscc(")); + if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass) || + PipelineText.empty()) + return false; + assert(PipelineText[0] == ')'); + PipelineText = PipelineText.substr(1); + + // Add the nested pass manager with the appropriate adaptor. + CGPM.addPass(std::move(NestedCGPM)); + } else if (PipelineText.startswith("function(")) { + FunctionPassManager NestedFPM; + + // Parse the inner pipeline inte the nested manager. + PipelineText = PipelineText.substr(strlen("function(")); + if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) || + PipelineText.empty()) + return false; + assert(PipelineText[0] == ')'); + PipelineText = PipelineText.substr(1); + + // Add the nested pass manager with the appropriate adaptor. + CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(NestedFPM))); + } else { + // Otherwise try to parse a pass name. + size_t End = PipelineText.find_first_of(",)"); + if (!parseCGSCCPassName(CGPM, PipelineText.substr(0, End))) + return false; + // FIXME: No verifier support for CGSCC passes! PipelineText = PipelineText.substr(End); } @@ -101,7 +210,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(")) { @@ -109,30 +219,48 @@ 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.empty() && PipelineText[0] == ')'); + assert(PipelineText[0] == ')'); PipelineText = PipelineText.substr(1); // Now add the nested manager as a module pass. - MPM.addPass(NestedMPM); + MPM.addPass(std::move(NestedMPM)); + } else if (PipelineText.startswith("cgscc(")) { + CGSCCPassManager NestedCGPM; + + // Parse the inner pipeline inte the nested manager. + PipelineText = PipelineText.substr(strlen("cgscc(")); + if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass) || + PipelineText.empty()) + return false; + assert(PipelineText[0] == ')'); + PipelineText = PipelineText.substr(1); + + // Add the nested pass manager with the appropriate adaptor. + MPM.addPass( + createModuleToPostOrderCGSCCPassAdaptor(std::move(NestedCGPM))); } else if (PipelineText.startswith("function(")) { FunctionPassManager NestedFPM; // 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.empty() && PipelineText[0] == ')'); + assert(PipelineText[0] == ')'); PipelineText = PipelineText.substr(1); // Add the nested pass manager with the appropriate adaptor. - MPM.addPass(createModuleToFunctionPassAdaptor(NestedFPM)); + MPM.addPass(createModuleToFunctionPassAdaptor(std::move(NestedFPM))); } else { // Otherwise try to parse a pass name. 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); } @@ -148,28 +276,51 @@ 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); + return parseModulePassPipeline(MPM, PipelineText, VerifyEachPass) && + PipelineText.empty(); + if (PipelineText.startswith("cgscc(")) { + CGSCCPassManager CGPM; + if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass) || + !PipelineText.empty()) + return false; + MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM))); + return true; + } if (PipelineText.startswith("function(")) { FunctionPassManager FPM; - if (!parseFunctionPassPipeline(FPM, PipelineText)) + if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) || + !PipelineText.empty()) return false; - MPM.addPass(createModuleToFunctionPassAdaptor(FPM)); + MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); return true; } // This isn't a direct pass manager name, look for the end of a pass name. - StringRef FirstName = PipelineText.substr(0, PipelineText.find_first_of(",")); + StringRef FirstName = + PipelineText.substr(0, PipelineText.find_first_of(",)")); if (isModulePassName(FirstName)) - return parseModulePassPipeline(MPM, PipelineText); + return parseModulePassPipeline(MPM, PipelineText, VerifyEachPass) && + PipelineText.empty(); + + if (isCGSCCPassName(FirstName)) { + CGSCCPassManager CGPM; + if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass) || + !PipelineText.empty()) + return false; + MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM))); + return true; + } if (isFunctionPassName(FirstName)) { FunctionPassManager FPM; - if (!parseFunctionPassPipeline(FPM, PipelineText)) + if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) || + !PipelineText.empty()) return false; - MPM.addPass(createModuleToFunctionPassAdaptor(FPM)); + MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); return true; }