diff options
author | Chandler Carruth <chandlerc@gmail.com> | 2014-01-12 09:34:22 +0000 |
---|---|---|
committer | Chandler Carruth <chandlerc@gmail.com> | 2014-01-12 09:34:22 +0000 |
commit | e7687650c9ff5e52f572d8e70752f7c808ca707e (patch) | |
tree | f54cfd4d339974434ba44a10116bc26d46d0932e /tools/opt | |
parent | 3d83eb48ac55f20e16997e210a59486f3717402a (diff) | |
download | llvm-e7687650c9ff5e52f572d8e70752f7c808ca707e.tar.gz llvm-e7687650c9ff5e52f572d8e70752f7c808ca707e.tar.bz2 llvm-e7687650c9ff5e52f572d8e70752f7c808ca707e.tar.xz |
[PM] Add support for parsing function passes and function pass manager
nests to the opt commandline support. This also showcases the
implicit-initial-manager support which will be most useful for testing.
There are several bugs that I spotted by inspection here that I'll fix
with test cases in subsequent commits.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199038 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/opt')
-rw-r--r-- | tools/opt/Passes.cpp | 85 |
1 files changed, 81 insertions, 4 deletions
diff --git a/tools/opt/Passes.cpp b/tools/opt/Passes.cpp index 44b3acee59..4a6341d512 100644 --- a/tools/opt/Passes.cpp +++ b/tools/opt/Passes.cpp @@ -21,12 +21,18 @@ using namespace llvm; namespace { - /// \brief No-op module pass which does nothing. +/// \brief No-op module pass which does nothing. struct NoOpModulePass { PreservedAnalyses run(Module *M) { return PreservedAnalyses::all(); } static StringRef name() { return "NoOpModulePass"; } }; +/// \brief No-op function pass which does nothing. +struct NoOpFunctionPass { + PreservedAnalyses run(Function *F) { return PreservedAnalyses::all(); } + static StringRef name() { return "NoOpFunctionPass"; } +}; + } // End anonymous namespace. // FIXME: Factor all of the parsing logic into a .def file that we include @@ -37,6 +43,12 @@ static bool isModulePassName(StringRef Name) { return false; } +static bool isFunctionPassName(StringRef Name) { + if (Name == "no-op-function") return true; + + return false; +} + static bool parseModulePassName(ModulePassManager &MPM, StringRef Name) { assert(isModulePassName(Name)); if (Name == "no-op-module") { @@ -46,6 +58,48 @@ static bool parseModulePassName(ModulePassManager &MPM, StringRef Name) { return false; } +static bool parseFunctionPassName(FunctionPassManager &FPM, StringRef Name) { + assert(isFunctionPassName(Name)); + if (Name == "no-op-function") { + FPM.addPass(NoOpFunctionPass()); + return true; + } + return false; +} + +static bool parseFunctionPassPipeline(FunctionPassManager &FPM, + StringRef &PipelineText) { + for (;;) { + // Parse nested pass managers by recursing. + if (PipelineText.startswith("function(")) { + FunctionPassManager NestedFPM; + + // Parse the inner pipeline inte the nested manager. + PipelineText = PipelineText.substr(strlen("function(")); + if (!parseFunctionPassPipeline(NestedFPM, PipelineText)) + return false; + assert(!PipelineText.empty() && PipelineText[0] == ')'); + PipelineText = PipelineText.substr(1); + + // Add the nested pass manager with the appropriate adaptor. + FPM.addPass(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; + + PipelineText = PipelineText.substr(End); + } + + if (PipelineText.empty() || PipelineText[0] == ')') + return true; + + assert(PipelineText[0] == ','); + PipelineText = PipelineText.substr(1); + } +} + static bool parseModulePassPipeline(ModulePassManager &MPM, StringRef &PipelineText) { for (;;) { @@ -62,6 +116,18 @@ static bool parseModulePassPipeline(ModulePassManager &MPM, // Now add the nested manager as a module pass. MPM.addPass(NestedMPM); + } else if (PipelineText.startswith("function(")) { + FunctionPassManager NestedFPM; + + // Parse the inner pipeline inte the nested manager. + PipelineText = PipelineText.substr(strlen("function(")); + if (!parseFunctionPassPipeline(NestedFPM, PipelineText)) + return false; + assert(!PipelineText.empty() && PipelineText[0] == ')'); + PipelineText = PipelineText.substr(1); + + // Add the nested pass manager with the appropriate adaptor. + MPM.addPass(createModuleToFunctionPassAdaptor(NestedFPM)); } else { // Otherwise try to parse a pass name. size_t End = PipelineText.find_first_of(",)"); @@ -86,15 +152,26 @@ bool llvm::parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText) { // Look at the first entry to figure out which layer to start parsing at. if (PipelineText.startswith("module(")) return parseModulePassPipeline(MPM, PipelineText); - - // FIXME: Support parsing function pass manager nests. + if (PipelineText.startswith("function(")) { + FunctionPassManager FPM; + if (!parseFunctionPassPipeline(FPM, PipelineText)) + return false; + MPM.addPass(createModuleToFunctionPassAdaptor(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(",")); if (isModulePassName(FirstName)) return parseModulePassPipeline(MPM, PipelineText); - // FIXME: Support parsing function pass names. + if (isFunctionPassName(FirstName)) { + FunctionPassManager FPM; + if (!parseFunctionPassPipeline(FPM, PipelineText)) + return false; + MPM.addPass(createModuleToFunctionPassAdaptor(FPM)); + return true; + } return false; } |