summaryrefslogtreecommitdiff
path: root/tools/opt/Passes.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/opt/Passes.cpp')
-rw-r--r--tools/opt/Passes.cpp114
1 files changed, 114 insertions, 0 deletions
diff --git a/tools/opt/Passes.cpp b/tools/opt/Passes.cpp
index e4791b8ac8..a171f42691 100644
--- a/tools/opt/Passes.cpp
+++ b/tools/opt/Passes.cpp
@@ -15,6 +15,7 @@
//===----------------------------------------------------------------------===//
#include "Passes.h"
+#include "llvm/Analysis/CGSCCPassManager.h"
#include "llvm/Analysis/LazyCallGraph.h"
#include "llvm/IR/IRPrintingPasses.h"
#include "llvm/IR/PassManager.h"
@@ -31,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(); }
@@ -48,6 +57,15 @@ static bool isModulePassName(StringRef Name) {
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;
@@ -73,6 +91,22 @@ static bool parseModulePassName(ModulePassManager &MPM, StringRef Name) {
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) {
if (Name == "no-op-function") {
FPM.addPass(NoOpFunctionPass());
@@ -126,6 +160,55 @@ static bool parseFunctionPassPipeline(FunctionPassManager &FPM,
}
}
+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);
+ }
+
+ if (PipelineText.empty() || PipelineText[0] == ')')
+ return true;
+
+ assert(PipelineText[0] == ',');
+ PipelineText = PipelineText.substr(1);
+ }
+}
+
static bool parseModulePassPipeline(ModulePassManager &MPM,
StringRef &PipelineText,
bool VerifyEachPass) {
@@ -144,6 +227,20 @@ static bool parseModulePassPipeline(ModulePassManager &MPM,
// Now add the nested manager as a module pass.
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;
@@ -185,6 +282,14 @@ bool llvm::parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText,
if (PipelineText.startswith("module("))
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, VerifyEachPass) ||
@@ -201,6 +306,15 @@ bool llvm::parsePassPipeline(ModulePassManager &MPM, StringRef 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, VerifyEachPass) ||