[PM] Create a separate library for high-level pass management code.
authorChandler Carruth <chandlerc@gmail.com>
Sat, 7 Mar 2015 09:02:36 +0000 (09:02 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Sat, 7 Mar 2015 09:02:36 +0000 (09:02 +0000)
This will provide the analogous replacements for the PassManagerBuilder
and other code long term. This code is extracted from the opt tool
currently, and I plan to extend it as I build up support for using the
new pass manager in Clang and other places.

Mailing this out for review in part to let folks comment on the terrible names
here. A brief word about why I chose the names I did.

The library is called "Passes" to try and make it clear that it is a high-level
utility and where *all* of the passes come together and are registered in
a common library. I didn't want it to be *limited* to a registry though, the
registry is just one component.

The class is a "PassBuilder" but this name I'm less happy with. It doesn't
build passes in any traditional sense and isn't a Builder-style API at all. The
class is a PassRegisterer or PassAdder, but neither of those really make a lot
of sense. This class is responsible for constructing passes for registry in an
analysis manager or for population of a pass pipeline. If anyone has a better
name, I would love to hear it. The other candidate I looked at was
PassRegistrar, but that doesn't really fit either. There is no register of all
the passes in use, and so I think continuing the "registry" analog outside of
the registry of pass *names* and *types* is a mistake. The objects themselves
are just objects with the new pass manager.

Differential Revision: http://reviews.llvm.org/D8054

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@231556 91177308-0d34-0410-b5e6-96231b3b80d8

16 files changed:
include/llvm/Passes/PassBuilder.h [new file with mode: 0644]
lib/CMakeLists.txt
lib/LLVMBuild.txt
lib/Makefile
lib/Passes/CMakeLists.txt [new file with mode: 0644]
lib/Passes/LLVMBuild.txt [new file with mode: 0644]
lib/Passes/Makefile [new file with mode: 0644]
lib/Passes/PassBuilder.cpp [new file with mode: 0644]
lib/Passes/PassRegistry.def [new file with mode: 0644]
tools/opt/CMakeLists.txt
tools/opt/LLVMBuild.txt
tools/opt/Makefile
tools/opt/NewPMDriver.cpp
tools/opt/PassRegistry.def [deleted file]
tools/opt/Passes.cpp [deleted file]
tools/opt/Passes.h [deleted file]

diff --git a/include/llvm/Passes/PassBuilder.h b/include/llvm/Passes/PassBuilder.h
new file mode 100644 (file)
index 0000000..1e605e3
--- /dev/null
@@ -0,0 +1,105 @@
+//===- Parsing, selection, and construction of pass pipelines --*- C++ -*--===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// Interfaces for registering analysis passes, producing common pass manager
+/// configurations, and parsing of pass pipelines.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PASSES_PASSBUILDER_H
+#define LLVM_PASSES_PASSBUILDER_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Analysis/CGSCCPassManager.h"
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+class TargetMachine;
+
+/// \brief This class provides access to building LLVM's passes.
+///
+/// It's members provide the baseline state available to passes during their
+/// construction. The \c PassRegistry.def file specifies how to construct all
+/// of the built-in passes, and those may reference these members during
+/// construction.
+class PassBuilder {
+  TargetMachine *TM;
+
+public:
+  explicit PassBuilder(TargetMachine *TM = nullptr) : TM(TM) {}
+
+  /// \brief Registers all available module analysis passes.
+  ///
+  /// This is an interface that can be used to populate a \c
+  /// ModuleAnalysisManager with all registered module analyses. Callers can
+  /// still manually register any additional analyses.
+  void registerModuleAnalyses(ModuleAnalysisManager &MAM);
+
+  /// \brief Registers all available CGSCC analysis passes.
+  ///
+  /// This is an interface that can be used to populate a \c CGSCCAnalysisManager
+  /// with all registered CGSCC analyses. Callers can still manually register any
+  /// additional analyses.
+  void registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM);
+
+  /// \brief Registers all available function analysis passes.
+  ///
+  /// This is an interface that can be used to populate a \c
+  /// FunctionAnalysisManager with all registered function analyses. Callers can
+  /// still manually register any additional analyses.
+  void registerFunctionAnalyses(FunctionAnalysisManager &FAM);
+
+  /// \brief Parse a textual pass pipeline description into a \c ModulePassManager.
+  ///
+  /// The format of the textual pass pipeline description looks something like:
+  ///
+  ///   module(function(instcombine,sroa),dce,cgscc(inliner,function(...)),...)
+  ///
+  /// Pass managers have ()s describing the nest structure of passes. All passes
+  /// are comma separated. As a special shortcut, if the very first pass is not
+  /// a module pass (as a module pass manager is), this will automatically form
+  /// the shortest stack of pass managers that allow inserting that first pass.
+  /// So, assuming function passes 'fpassN', CGSCC passes 'cgpassN', and loop passes
+  /// 'lpassN', all of these are valid:
+  ///
+  ///   fpass1,fpass2,fpass3
+  ///   cgpass1,cgpass2,cgpass3
+  ///   lpass1,lpass2,lpass3
+  ///
+  /// And they are equivalent to the following (resp.):
+  ///
+  ///   module(function(fpass1,fpass2,fpass3))
+  ///   module(cgscc(cgpass1,cgpass2,cgpass3))
+  ///   module(function(loop(lpass1,lpass2,lpass3)))
+  ///
+  /// This shortcut is especially useful for debugging and testing small pass
+  /// combinations. Note that these shortcuts don't introduce any other magic. If
+  /// 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 VerifyEachPass = true, bool DebugLogging = false);
+
+private:
+  bool parseModulePassName(ModulePassManager &MPM, StringRef Name);
+  bool parseCGSCCPassName(CGSCCPassManager &CGPM, StringRef Name);
+  bool parseFunctionPassName(FunctionPassManager &FPM, StringRef Name);
+  bool parseFunctionPassPipeline(FunctionPassManager &FPM,
+                                 StringRef &PipelineText, bool VerifyEachPass,
+                                 bool DebugLogging);
+  bool parseCGSCCPassPipeline(CGSCCPassManager &CGPM, StringRef &PipelineText,
+                              bool VerifyEachPass, bool DebugLogging);
+  bool parseModulePassPipeline(ModulePassManager &MPM, StringRef &PipelineText,
+                               bool VerifyEachPass, bool DebugLogging);
+};
+
+}
+
+#endif
index 8ab2d6e..ce10998 100644 (file)
@@ -18,3 +18,4 @@ add_subdirectory(AsmParser)
 add_subdirectory(LineEditor)
 add_subdirectory(ProfileData)
 add_subdirectory(Fuzzer)
+add_subdirectory(Passes)
index ad5b22b..bc2448d 100644 (file)
@@ -16,7 +16,7 @@
 ;===------------------------------------------------------------------------===;
 
 [common]
-subdirectories = Analysis AsmParser Bitcode CodeGen DebugInfo ExecutionEngine LineEditor Linker IR IRReader LTO MC Object Option ProfileData Support TableGen Target Transforms
+subdirectories = Analysis AsmParser Bitcode CodeGen DebugInfo ExecutionEngine LineEditor Linker IR IRReader LTO MC Object Option Passes ProfileData Support TableGen Target Transforms
 
 [component_0]
 type = Group
index 52fdaaf..f75ca58 100644 (file)
@@ -12,6 +12,6 @@ include $(LEVEL)/Makefile.config
 
 PARALLEL_DIRS := IR AsmParser Bitcode Analysis Transforms CodeGen Target      \
                  ExecutionEngine Linker LTO MC Object Option DebugInfo        \
-                 IRReader LineEditor ProfileData
+                 IRReader LineEditor ProfileData Passes
 
 include $(LEVEL)/Makefile.common
diff --git a/lib/Passes/CMakeLists.txt b/lib/Passes/CMakeLists.txt
new file mode 100644 (file)
index 0000000..3d6b3fb
--- /dev/null
@@ -0,0 +1,6 @@
+add_llvm_library(LLVMPasses
+  PassBuilder.cpp
+
+  ADDITIONAL_HEADER_DIRS
+  ${LLVM_MAIN_INCLUDE_DIR}/llvm/Passes
+  )
diff --git a/lib/Passes/LLVMBuild.txt b/lib/Passes/LLVMBuild.txt
new file mode 100644 (file)
index 0000000..3063fe3
--- /dev/null
@@ -0,0 +1,22 @@
+;===- ./lib/Passes/LLVMBuild.txt -------------------------------*- Conf -*--===;
+;
+;                     The LLVM Compiler Infrastructure
+;
+; This file is distributed under the University of Illinois Open Source
+; License. See LICENSE.TXT for details.
+;
+;===------------------------------------------------------------------------===;
+;
+; This is an LLVMBuild description file for the components in this subdirectory.
+;
+; For more information on the LLVMBuild system, please see:
+;
+;   http://llvm.org/docs/LLVMBuild.html
+;
+;===------------------------------------------------------------------------===;
+
+[component_0]
+type = Library
+name = Passes
+parent = Libraries
+required_libraries = Analysis Core IPA IPO InstCombine Scalar Support TransformUtils Vectorize
diff --git a/lib/Passes/Makefile b/lib/Passes/Makefile
new file mode 100644 (file)
index 0000000..413dc5c
--- /dev/null
@@ -0,0 +1,14 @@
+##===- lib/Passes/Makefile ---------------------------------*- Makefile -*-===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../..
+LIBRARYNAME = LLVMPasses
+BUILD_ARCHIVE := 1
+
+include $(LEVEL)/Makefile.common
diff --git a/lib/Passes/PassBuilder.cpp b/lib/Passes/PassBuilder.cpp
new file mode 100644 (file)
index 0000000..ba71320
--- /dev/null
@@ -0,0 +1,412 @@
+//===- Parsing, selection, and construction of pass pipelines -------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// This file provides the implementation of the PassBuilder based on our
+/// static pass registry as well as related functionality. It also provides
+/// helpers to aid in analyzing, debugging, and testing passes and pass
+/// pipelines.
+///
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Passes/PassBuilder.h"
+#include "llvm/Analysis/AssumptionCache.h"
+#include "llvm/Analysis/CGSCCPassManager.h"
+#include "llvm/Analysis/LazyCallGraph.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/IRPrintingPasses.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/IR/Verifier.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Transforms/InstCombine/InstCombine.h"
+#include "llvm/Transforms/Scalar/EarlyCSE.h"
+#include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h"
+#include "llvm/Transforms/Scalar/SimplifyCFG.h"
+
+using namespace llvm;
+
+namespace {
+
+/// \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 module analysis.
+struct NoOpModuleAnalysis {
+  struct Result {};
+  Result run(Module &) { return Result(); }
+  static StringRef name() { return "NoOpModuleAnalysis"; }
+  static void *ID() { return (void *)&PassID; }
+private:
+  static char PassID;
+};
+
+char NoOpModuleAnalysis::PassID;
+
+/// \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 CGSCC analysis.
+struct NoOpCGSCCAnalysis {
+  struct Result {};
+  Result run(LazyCallGraph::SCC &) { return Result(); }
+  static StringRef name() { return "NoOpCGSCCAnalysis"; }
+  static void *ID() { return (void *)&PassID; }
+private:
+  static char PassID;
+};
+
+char NoOpCGSCCAnalysis::PassID;
+
+/// \brief No-op function pass which does nothing.
+struct NoOpFunctionPass {
+  PreservedAnalyses run(Function &F) { return PreservedAnalyses::all(); }
+  static StringRef name() { return "NoOpFunctionPass"; }
+};
+
+/// \brief No-op function analysis.
+struct NoOpFunctionAnalysis {
+  struct Result {};
+  Result run(Function &) { return Result(); }
+  static StringRef name() { return "NoOpFunctionAnalysis"; }
+  static void *ID() { return (void *)&PassID; }
+private:
+  static char PassID;
+};
+
+char NoOpFunctionAnalysis::PassID;
+
+} // End anonymous namespace.
+
+void PassBuilder::registerModuleAnalyses(ModuleAnalysisManager &MAM) {
+#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
+  MAM.registerPass(CREATE_PASS);
+#include "PassRegistry.def"
+}
+
+void PassBuilder::registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM) {
+#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
+  CGAM.registerPass(CREATE_PASS);
+#include "PassRegistry.def"
+}
+
+void PassBuilder::registerFunctionAnalyses(FunctionAnalysisManager &FAM) {
+#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
+  FAM.registerPass(CREATE_PASS);
+#include "PassRegistry.def"
+}
+
+#ifndef NDEBUG
+static bool isModulePassName(StringRef Name) {
+#define MODULE_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
+#define MODULE_ANALYSIS(NAME, CREATE_PASS)                                     \
+  if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">")           \
+    return true;
+#include "PassRegistry.def"
+
+  return false;
+}
+#endif
+
+static bool isCGSCCPassName(StringRef Name) {
+#define CGSCC_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
+#define CGSCC_ANALYSIS(NAME, CREATE_PASS)                                      \
+  if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">")           \
+    return true;
+#include "PassRegistry.def"
+
+  return false;
+}
+
+static bool isFunctionPassName(StringRef Name) {
+#define FUNCTION_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
+#define FUNCTION_ANALYSIS(NAME, CREATE_PASS)                                   \
+  if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">")           \
+    return true;
+#include "PassRegistry.def"
+
+  return false;
+}
+
+bool PassBuilder::parseModulePassName(ModulePassManager &MPM, StringRef Name) {
+#define MODULE_PASS(NAME, CREATE_PASS)                                         \
+  if (Name == NAME) {                                                          \
+    MPM.addPass(CREATE_PASS);                                                  \
+    return true;                                                               \
+  }
+#define MODULE_ANALYSIS(NAME, CREATE_PASS)                                     \
+  if (Name == "require<" NAME ">") {                                           \
+    MPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>());                 \
+    return true;                                                               \
+  }                                                                            \
+  if (Name == "invalidate<" NAME ">") {                                        \
+    MPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>());              \
+    return true;                                                               \
+  }
+#include "PassRegistry.def"
+
+  return false;
+}
+
+bool PassBuilder::parseCGSCCPassName(CGSCCPassManager &CGPM, StringRef Name) {
+#define CGSCC_PASS(NAME, CREATE_PASS)                                          \
+  if (Name == NAME) {                                                          \
+    CGPM.addPass(CREATE_PASS);                                                 \
+    return true;                                                               \
+  }
+#define CGSCC_ANALYSIS(NAME, CREATE_PASS)                                      \
+  if (Name == "require<" NAME ">") {                                           \
+    CGPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>());                \
+    return true;                                                               \
+  }                                                                            \
+  if (Name == "invalidate<" NAME ">") {                                        \
+    CGPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>());             \
+    return true;                                                               \
+  }
+#include "PassRegistry.def"
+
+  return false;
+}
+
+bool PassBuilder::parseFunctionPassName(FunctionPassManager &FPM,
+                                        StringRef Name) {
+#define FUNCTION_PASS(NAME, CREATE_PASS)                                       \
+  if (Name == NAME) {                                                          \
+    FPM.addPass(CREATE_PASS);                                                  \
+    return true;                                                               \
+  }
+#define FUNCTION_ANALYSIS(NAME, CREATE_PASS)                                   \
+  if (Name == "require<" NAME ">") {                                           \
+    FPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>());                 \
+    return true;                                                               \
+  }                                                                            \
+  if (Name == "invalidate<" NAME ">") {                                        \
+    FPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>());              \
+    return true;                                                               \
+  }
+#include "PassRegistry.def"
+
+  return false;
+}
+
+bool PassBuilder::parseFunctionPassPipeline(FunctionPassManager &FPM,
+                                            StringRef &PipelineText,
+                                            bool VerifyEachPass,
+                                            bool DebugLogging) {
+  for (;;) {
+    // Parse nested pass managers by recursing.
+    if (PipelineText.startswith("function(")) {
+      FunctionPassManager NestedFPM(DebugLogging);
+
+      // Parse the inner pipeline inte the nested manager.
+      PipelineText = PipelineText.substr(strlen("function("));
+      if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
+                                     DebugLogging) ||
+          PipelineText.empty())
+        return false;
+      assert(PipelineText[0] == ')');
+      PipelineText = PipelineText.substr(1);
+
+      // Add the nested pass manager with the appropriate adaptor.
+      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);
+  }
+}
+
+bool PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
+                                         StringRef &PipelineText,
+                                         bool VerifyEachPass,
+                                         bool DebugLogging) {
+  for (;;) {
+    // Parse nested pass managers by recursing.
+    if (PipelineText.startswith("cgscc(")) {
+      CGSCCPassManager NestedCGPM(DebugLogging);
+
+      // Parse the inner pipeline into the nested manager.
+      PipelineText = PipelineText.substr(strlen("cgscc("));
+      if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
+                                  DebugLogging) ||
+          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(DebugLogging);
+
+      // Parse the inner pipeline inte the nested manager.
+      PipelineText = PipelineText.substr(strlen("function("));
+      if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
+                                     DebugLogging) ||
+          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);
+  }
+}
+
+bool PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
+                                          StringRef &PipelineText,
+                                          bool VerifyEachPass,
+                                          bool DebugLogging) {
+  for (;;) {
+    // Parse nested pass managers by recursing.
+    if (PipelineText.startswith("module(")) {
+      ModulePassManager NestedMPM(DebugLogging);
+
+      // Parse the inner pipeline into the nested manager.
+      PipelineText = PipelineText.substr(strlen("module("));
+      if (!parseModulePassPipeline(NestedMPM, PipelineText, VerifyEachPass,
+                                   DebugLogging) ||
+          PipelineText.empty())
+        return false;
+      assert(PipelineText[0] == ')');
+      PipelineText = PipelineText.substr(1);
+
+      // Now add the nested manager as a module pass.
+      MPM.addPass(std::move(NestedMPM));
+    } else if (PipelineText.startswith("cgscc(")) {
+      CGSCCPassManager NestedCGPM(DebugLogging);
+
+      // Parse the inner pipeline inte the nested manager.
+      PipelineText = PipelineText.substr(strlen("cgscc("));
+      if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
+                                  DebugLogging) ||
+          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(DebugLogging);
+
+      // Parse the inner pipeline inte the nested manager.
+      PipelineText = PipelineText.substr(strlen("function("));
+      if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
+                                     DebugLogging) ||
+          PipelineText.empty())
+        return false;
+      assert(PipelineText[0] == ')');
+      PipelineText = PipelineText.substr(1);
+
+      // Add the nested pass manager with the appropriate adaptor.
+      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);
+    }
+
+    if (PipelineText.empty() || PipelineText[0] == ')')
+      return true;
+
+    assert(PipelineText[0] == ',');
+    PipelineText = PipelineText.substr(1);
+  }
+}
+
+// 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 PassBuilder::parsePassPipeline(ModulePassManager &MPM,
+                                    StringRef PipelineText, bool VerifyEachPass,
+                                    bool DebugLogging) {
+  // By default, try to parse the pipeline as-if it were within an implicit
+  // 'module(...)' pass pipeline. If this will parse at all, it needs to
+  // consume the entire string.
+  if (parseModulePassPipeline(MPM, PipelineText, VerifyEachPass, DebugLogging))
+    return PipelineText.empty();
+
+  // This isn't parsable as a module pipeline, look for the end of a pass name
+  // and directly drop down to that layer.
+  StringRef FirstName =
+      PipelineText.substr(0, PipelineText.find_first_of(",)"));
+  assert(!isModulePassName(FirstName) &&
+         "Already handled all module pipeline options.");
+
+  // If this looks like a CGSCC pass, parse the whole thing as a CGSCC
+  // pipeline.
+  if (isCGSCCPassName(FirstName)) {
+    CGSCCPassManager CGPM(DebugLogging);
+    if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass,
+                                DebugLogging) ||
+        !PipelineText.empty())
+      return false;
+    MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
+    return true;
+  }
+
+  // Similarly, if this looks like a Function pass, parse the whole thing as
+  // a Function pipelien.
+  if (isFunctionPassName(FirstName)) {
+    FunctionPassManager FPM(DebugLogging);
+    if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass,
+                                   DebugLogging) ||
+        !PipelineText.empty())
+      return false;
+    MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
+    return true;
+  }
+
+  return false;
+}
diff --git a/lib/Passes/PassRegistry.def b/lib/Passes/PassRegistry.def
new file mode 100644 (file)
index 0000000..d768a3a
--- /dev/null
@@ -0,0 +1,77 @@
+//===- PassRegistry.def - Registry of passes --------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is used as the registry of passes that are part of the core LLVM
+// libraries. This file describes both transformation passes and analyses
+// Analyses are registered while transformation passes have names registered
+// that can be used when providing a textual pass pipeline.
+//
+//===----------------------------------------------------------------------===//
+
+// NOTE: NO INCLUDE GUARD DESIRED!
+
+#ifndef MODULE_ANALYSIS
+#define MODULE_ANALYSIS(NAME, CREATE_PASS)
+#endif
+MODULE_ANALYSIS("lcg", LazyCallGraphAnalysis())
+MODULE_ANALYSIS("no-op-module", NoOpModuleAnalysis())
+MODULE_ANALYSIS("targetlibinfo", TargetLibraryAnalysis())
+#undef MODULE_ANALYSIS
+
+#ifndef MODULE_PASS
+#define MODULE_PASS(NAME, CREATE_PASS)
+#endif
+MODULE_PASS("invalidate<all>", InvalidateAllAnalysesPass())
+MODULE_PASS("no-op-module", NoOpModulePass())
+MODULE_PASS("print", PrintModulePass(dbgs()))
+MODULE_PASS("print-cg", LazyCallGraphPrinterPass(dbgs()))
+MODULE_PASS("verify", VerifierPass())
+#undef MODULE_PASS
+
+#ifndef CGSCC_ANALYSIS
+#define CGSCC_ANALYSIS(NAME, CREATE_PASS)
+#endif
+CGSCC_ANALYSIS("no-op-cgscc", NoOpCGSCCAnalysis())
+#undef CGSCC_ANALYSIS
+
+#ifndef CGSCC_PASS
+#define CGSCC_PASS(NAME, CREATE_PASS)
+#endif
+CGSCC_PASS("invalidate<all>", InvalidateAllAnalysesPass())
+CGSCC_PASS("no-op-cgscc", NoOpCGSCCPass())
+#undef CGSCC_PASS
+
+#ifndef FUNCTION_ANALYSIS
+#define FUNCTION_ANALYSIS(NAME, CREATE_PASS)
+#endif
+FUNCTION_ANALYSIS("assumptions", AssumptionAnalysis())
+FUNCTION_ANALYSIS("domtree", DominatorTreeAnalysis())
+FUNCTION_ANALYSIS("loops", LoopAnalysis())
+FUNCTION_ANALYSIS("no-op-function", NoOpFunctionAnalysis())
+FUNCTION_ANALYSIS("targetlibinfo", TargetLibraryAnalysis())
+FUNCTION_ANALYSIS("targetir",
+                  TM ? TM->getTargetIRAnalysis() : TargetIRAnalysis())
+#undef FUNCTION_ANALYSIS
+
+#ifndef FUNCTION_PASS
+#define FUNCTION_PASS(NAME, CREATE_PASS)
+#endif
+FUNCTION_PASS("early-cse", EarlyCSEPass())
+FUNCTION_PASS("instcombine", InstCombinePass())
+FUNCTION_PASS("invalidate<all>", InvalidateAllAnalysesPass())
+FUNCTION_PASS("no-op-function", NoOpFunctionPass())
+FUNCTION_PASS("lower-expect", LowerExpectIntrinsicPass())
+FUNCTION_PASS("print", PrintFunctionPass(dbgs()))
+FUNCTION_PASS("print<assumptions>", AssumptionPrinterPass(dbgs()))
+FUNCTION_PASS("print<domtree>", DominatorTreePrinterPass(dbgs()))
+FUNCTION_PASS("print<loops>", LoopPrinterPass(dbgs()))
+FUNCTION_PASS("simplify-cfg", SimplifyCFGPass())
+FUNCTION_PASS("verify", VerifierPass())
+FUNCTION_PASS("verify<domtree>", DominatorTreeVerifierPass())
+#undef FUNCTION_PASS
index 1d3f08d..12dc4f0 100644 (file)
@@ -16,6 +16,7 @@ set(LLVM_LINK_COMPONENTS
   Target
   TransformUtils
   Vectorize
+  Passes
   )
 
 # Support plugins.
@@ -26,7 +27,6 @@ add_llvm_tool(opt
   BreakpointPrinter.cpp
   GraphPrinters.cpp
   NewPMDriver.cpp
-  Passes.cpp
   PassPrinters.cpp
   PrintSCC.cpp
   opt.cpp
index b3589f8..b162ab6 100644 (file)
@@ -19,4 +19,4 @@
 type = Tool
 name = opt
 parent = Tools
-required_libraries = AsmParser BitReader BitWriter CodeGen IRReader IPO Instrumentation Scalar ObjCARC all-targets
+required_libraries = AsmParser BitReader BitWriter CodeGen IRReader IPO Instrumentation Scalar ObjCARC Passes all-targets
index cfa9c31..2422eb4 100644 (file)
@@ -9,7 +9,7 @@
 
 LEVEL := ../..
 TOOLNAME := opt
-LINK_COMPONENTS := bitreader bitwriter asmparser irreader instrumentation scalaropts objcarcopts ipo vectorize all-targets codegen
+LINK_COMPONENTS := bitreader bitwriter asmparser irreader instrumentation scalaropts objcarcopts ipo vectorize all-targets codegen passes
 
 # Support plugins.
 NO_DEAD_STRIP := 1
index a73750d..9216d5c 100644 (file)
@@ -14,7 +14,6 @@
 //===----------------------------------------------------------------------===//
 
 #include "NewPMDriver.h"
-#include "Passes.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Analysis/CGSCCPassManager.h"
 #include "llvm/Bitcode/BitcodeWriterPass.h"
@@ -24,6 +23,7 @@
 #include "llvm/IR/Module.h"
 #include "llvm/IR/PassManager.h"
 #include "llvm/IR/Verifier.h"
+#include "llvm/Passes/PassBuilder.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/ToolOutputFile.h"
@@ -40,16 +40,16 @@ bool llvm::runPassPipeline(StringRef Arg0, LLVMContext &Context, Module &M,
                            TargetMachine *TM, tool_output_file *Out,
                            StringRef PassPipeline, OutputKind OK,
                            VerifierKind VK) {
-  Passes P(TM);
+  PassBuilder PB(TM);
 
   FunctionAnalysisManager FAM(DebugPM);
   CGSCCAnalysisManager CGAM(DebugPM);
   ModuleAnalysisManager MAM(DebugPM);
 
   // Register all the basic analyses with the managers.
-  P.registerModuleAnalyses(MAM);
-  P.registerCGSCCAnalyses(CGAM);
-  P.registerFunctionAnalyses(FAM);
+  PB.registerModuleAnalyses(MAM);
+  PB.registerCGSCCAnalyses(CGAM);
+  PB.registerFunctionAnalyses(FAM);
 
   // Cross register the analysis managers through their proxies.
   MAM.registerPass(FunctionAnalysisManagerModuleProxy(FAM));
@@ -63,8 +63,8 @@ bool llvm::runPassPipeline(StringRef Arg0, LLVMContext &Context, Module &M,
   if (VK > VK_NoVerifier)
     MPM.addPass(VerifierPass());
 
-  if (!P.parsePassPipeline(MPM, PassPipeline, VK == VK_VerifyEachPass,
-                           DebugPM)) {
+  if (!PB.parsePassPipeline(MPM, PassPipeline, VK == VK_VerifyEachPass,
+                            DebugPM)) {
     errs() << Arg0 << ": unable to parse pass pipeline description.\n";
     return false;
   }
diff --git a/tools/opt/PassRegistry.def b/tools/opt/PassRegistry.def
deleted file mode 100644 (file)
index d768a3a..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-//===- PassRegistry.def - Registry of passes --------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is used as the registry of passes that are part of the core LLVM
-// libraries. This file describes both transformation passes and analyses
-// Analyses are registered while transformation passes have names registered
-// that can be used when providing a textual pass pipeline.
-//
-//===----------------------------------------------------------------------===//
-
-// NOTE: NO INCLUDE GUARD DESIRED!
-
-#ifndef MODULE_ANALYSIS
-#define MODULE_ANALYSIS(NAME, CREATE_PASS)
-#endif
-MODULE_ANALYSIS("lcg", LazyCallGraphAnalysis())
-MODULE_ANALYSIS("no-op-module", NoOpModuleAnalysis())
-MODULE_ANALYSIS("targetlibinfo", TargetLibraryAnalysis())
-#undef MODULE_ANALYSIS
-
-#ifndef MODULE_PASS
-#define MODULE_PASS(NAME, CREATE_PASS)
-#endif
-MODULE_PASS("invalidate<all>", InvalidateAllAnalysesPass())
-MODULE_PASS("no-op-module", NoOpModulePass())
-MODULE_PASS("print", PrintModulePass(dbgs()))
-MODULE_PASS("print-cg", LazyCallGraphPrinterPass(dbgs()))
-MODULE_PASS("verify", VerifierPass())
-#undef MODULE_PASS
-
-#ifndef CGSCC_ANALYSIS
-#define CGSCC_ANALYSIS(NAME, CREATE_PASS)
-#endif
-CGSCC_ANALYSIS("no-op-cgscc", NoOpCGSCCAnalysis())
-#undef CGSCC_ANALYSIS
-
-#ifndef CGSCC_PASS
-#define CGSCC_PASS(NAME, CREATE_PASS)
-#endif
-CGSCC_PASS("invalidate<all>", InvalidateAllAnalysesPass())
-CGSCC_PASS("no-op-cgscc", NoOpCGSCCPass())
-#undef CGSCC_PASS
-
-#ifndef FUNCTION_ANALYSIS
-#define FUNCTION_ANALYSIS(NAME, CREATE_PASS)
-#endif
-FUNCTION_ANALYSIS("assumptions", AssumptionAnalysis())
-FUNCTION_ANALYSIS("domtree", DominatorTreeAnalysis())
-FUNCTION_ANALYSIS("loops", LoopAnalysis())
-FUNCTION_ANALYSIS("no-op-function", NoOpFunctionAnalysis())
-FUNCTION_ANALYSIS("targetlibinfo", TargetLibraryAnalysis())
-FUNCTION_ANALYSIS("targetir",
-                  TM ? TM->getTargetIRAnalysis() : TargetIRAnalysis())
-#undef FUNCTION_ANALYSIS
-
-#ifndef FUNCTION_PASS
-#define FUNCTION_PASS(NAME, CREATE_PASS)
-#endif
-FUNCTION_PASS("early-cse", EarlyCSEPass())
-FUNCTION_PASS("instcombine", InstCombinePass())
-FUNCTION_PASS("invalidate<all>", InvalidateAllAnalysesPass())
-FUNCTION_PASS("no-op-function", NoOpFunctionPass())
-FUNCTION_PASS("lower-expect", LowerExpectIntrinsicPass())
-FUNCTION_PASS("print", PrintFunctionPass(dbgs()))
-FUNCTION_PASS("print<assumptions>", AssumptionPrinterPass(dbgs()))
-FUNCTION_PASS("print<domtree>", DominatorTreePrinterPass(dbgs()))
-FUNCTION_PASS("print<loops>", LoopPrinterPass(dbgs()))
-FUNCTION_PASS("simplify-cfg", SimplifyCFGPass())
-FUNCTION_PASS("verify", VerifierPass())
-FUNCTION_PASS("verify<domtree>", DominatorTreeVerifierPass())
-#undef FUNCTION_PASS
diff --git a/tools/opt/Passes.cpp b/tools/opt/Passes.cpp
deleted file mode 100644 (file)
index e5ad5c0..0000000
+++ /dev/null
@@ -1,406 +0,0 @@
-//===- Passes.cpp - Parsing, selection, and running of passes -------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-/// \file
-///
-/// This file provides the infrastructure to parse and build a custom pass
-/// manager based on a commandline flag. It also provides helpers to aid in
-/// analyzing, debugging, and testing pass structures.
-///
-//===----------------------------------------------------------------------===//
-
-#include "Passes.h"
-#include "llvm/Analysis/AssumptionCache.h"
-#include "llvm/Analysis/CGSCCPassManager.h"
-#include "llvm/Analysis/LazyCallGraph.h"
-#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/TargetLibraryInfo.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/IR/Dominators.h"
-#include "llvm/IR/IRPrintingPasses.h"
-#include "llvm/IR/PassManager.h"
-#include "llvm/IR/Verifier.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Transforms/InstCombine/InstCombine.h"
-#include "llvm/Transforms/Scalar/EarlyCSE.h"
-#include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h"
-#include "llvm/Transforms/Scalar/SimplifyCFG.h"
-
-using namespace llvm;
-
-namespace {
-
-/// \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 module analysis.
-struct NoOpModuleAnalysis {
-  struct Result {};
-  Result run(Module &) { return Result(); }
-  static StringRef name() { return "NoOpModuleAnalysis"; }
-  static void *ID() { return (void *)&PassID; }
-private:
-  static char PassID;
-};
-
-char NoOpModuleAnalysis::PassID;
-
-/// \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 CGSCC analysis.
-struct NoOpCGSCCAnalysis {
-  struct Result {};
-  Result run(LazyCallGraph::SCC &) { return Result(); }
-  static StringRef name() { return "NoOpCGSCCAnalysis"; }
-  static void *ID() { return (void *)&PassID; }
-private:
-  static char PassID;
-};
-
-char NoOpCGSCCAnalysis::PassID;
-
-/// \brief No-op function pass which does nothing.
-struct NoOpFunctionPass {
-  PreservedAnalyses run(Function &F) { return PreservedAnalyses::all(); }
-  static StringRef name() { return "NoOpFunctionPass"; }
-};
-
-/// \brief No-op function analysis.
-struct NoOpFunctionAnalysis {
-  struct Result {};
-  Result run(Function &) { return Result(); }
-  static StringRef name() { return "NoOpFunctionAnalysis"; }
-  static void *ID() { return (void *)&PassID; }
-private:
-  static char PassID;
-};
-
-char NoOpFunctionAnalysis::PassID;
-
-} // End anonymous namespace.
-
-void Passes::registerModuleAnalyses(ModuleAnalysisManager &MAM) {
-#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
-  MAM.registerPass(CREATE_PASS);
-#include "PassRegistry.def"
-}
-
-void Passes::registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM) {
-#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
-  CGAM.registerPass(CREATE_PASS);
-#include "PassRegistry.def"
-}
-
-void Passes::registerFunctionAnalyses(FunctionAnalysisManager &FAM) {
-#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
-  FAM.registerPass(CREATE_PASS);
-#include "PassRegistry.def"
-}
-
-#ifndef NDEBUG
-static bool isModulePassName(StringRef Name) {
-#define MODULE_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
-#define MODULE_ANALYSIS(NAME, CREATE_PASS)                                     \
-  if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">")           \
-    return true;
-#include "PassRegistry.def"
-
-  return false;
-}
-#endif
-
-static bool isCGSCCPassName(StringRef Name) {
-#define CGSCC_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
-#define CGSCC_ANALYSIS(NAME, CREATE_PASS)                                      \
-  if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">")           \
-    return true;
-#include "PassRegistry.def"
-
-  return false;
-}
-
-static bool isFunctionPassName(StringRef Name) {
-#define FUNCTION_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
-#define FUNCTION_ANALYSIS(NAME, CREATE_PASS)                                   \
-  if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">")           \
-    return true;
-#include "PassRegistry.def"
-
-  return false;
-}
-
-bool Passes::parseModulePassName(ModulePassManager &MPM, StringRef Name) {
-#define MODULE_PASS(NAME, CREATE_PASS)                                         \
-  if (Name == NAME) {                                                          \
-    MPM.addPass(CREATE_PASS);                                                  \
-    return true;                                                               \
-  }
-#define MODULE_ANALYSIS(NAME, CREATE_PASS)                                     \
-  if (Name == "require<" NAME ">") {                                           \
-    MPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>());                 \
-    return true;                                                               \
-  }                                                                            \
-  if (Name == "invalidate<" NAME ">") {                                        \
-    MPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>());              \
-    return true;                                                               \
-  }
-#include "PassRegistry.def"
-
-  return false;
-}
-
-bool Passes::parseCGSCCPassName(CGSCCPassManager &CGPM, StringRef Name) {
-#define CGSCC_PASS(NAME, CREATE_PASS)                                          \
-  if (Name == NAME) {                                                          \
-    CGPM.addPass(CREATE_PASS);                                                 \
-    return true;                                                               \
-  }
-#define CGSCC_ANALYSIS(NAME, CREATE_PASS)                                      \
-  if (Name == "require<" NAME ">") {                                           \
-    CGPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>());                \
-    return true;                                                               \
-  }                                                                            \
-  if (Name == "invalidate<" NAME ">") {                                        \
-    CGPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>());             \
-    return true;                                                               \
-  }
-#include "PassRegistry.def"
-
-  return false;
-}
-
-bool Passes::parseFunctionPassName(FunctionPassManager &FPM, StringRef Name) {
-#define FUNCTION_PASS(NAME, CREATE_PASS)                                       \
-  if (Name == NAME) {                                                          \
-    FPM.addPass(CREATE_PASS);                                                  \
-    return true;                                                               \
-  }
-#define FUNCTION_ANALYSIS(NAME, CREATE_PASS)                                   \
-  if (Name == "require<" NAME ">") {                                           \
-    FPM.addPass(RequireAnalysisPass<decltype(CREATE_PASS)>());                 \
-    return true;                                                               \
-  }                                                                            \
-  if (Name == "invalidate<" NAME ">") {                                        \
-    FPM.addPass(InvalidateAnalysisPass<decltype(CREATE_PASS)>());              \
-    return true;                                                               \
-  }
-#include "PassRegistry.def"
-
-  return false;
-}
-
-bool Passes::parseFunctionPassPipeline(FunctionPassManager &FPM,
-                                       StringRef &PipelineText,
-                                       bool VerifyEachPass, bool DebugLogging) {
-  for (;;) {
-    // Parse nested pass managers by recursing.
-    if (PipelineText.startswith("function(")) {
-      FunctionPassManager NestedFPM(DebugLogging);
-
-      // Parse the inner pipeline inte the nested manager.
-      PipelineText = PipelineText.substr(strlen("function("));
-      if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
-                                     DebugLogging) ||
-          PipelineText.empty())
-        return false;
-      assert(PipelineText[0] == ')');
-      PipelineText = PipelineText.substr(1);
-
-      // Add the nested pass manager with the appropriate adaptor.
-      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);
-  }
-}
-
-bool Passes::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
-                                    StringRef &PipelineText,
-                                    bool VerifyEachPass, bool DebugLogging) {
-  for (;;) {
-    // Parse nested pass managers by recursing.
-    if (PipelineText.startswith("cgscc(")) {
-      CGSCCPassManager NestedCGPM(DebugLogging);
-
-      // Parse the inner pipeline into the nested manager.
-      PipelineText = PipelineText.substr(strlen("cgscc("));
-      if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
-                                  DebugLogging) ||
-          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(DebugLogging);
-
-      // Parse the inner pipeline inte the nested manager.
-      PipelineText = PipelineText.substr(strlen("function("));
-      if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
-                                     DebugLogging) ||
-          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);
-  }
-}
-
-bool Passes::parseModulePassPipeline(ModulePassManager &MPM,
-                                     StringRef &PipelineText,
-                                     bool VerifyEachPass, bool DebugLogging) {
-  for (;;) {
-    // Parse nested pass managers by recursing.
-    if (PipelineText.startswith("module(")) {
-      ModulePassManager NestedMPM(DebugLogging);
-
-      // Parse the inner pipeline into the nested manager.
-      PipelineText = PipelineText.substr(strlen("module("));
-      if (!parseModulePassPipeline(NestedMPM, PipelineText, VerifyEachPass,
-                                   DebugLogging) ||
-          PipelineText.empty())
-        return false;
-      assert(PipelineText[0] == ')');
-      PipelineText = PipelineText.substr(1);
-
-      // Now add the nested manager as a module pass.
-      MPM.addPass(std::move(NestedMPM));
-    } else if (PipelineText.startswith("cgscc(")) {
-      CGSCCPassManager NestedCGPM(DebugLogging);
-
-      // Parse the inner pipeline inte the nested manager.
-      PipelineText = PipelineText.substr(strlen("cgscc("));
-      if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
-                                  DebugLogging) ||
-          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(DebugLogging);
-
-      // Parse the inner pipeline inte the nested manager.
-      PipelineText = PipelineText.substr(strlen("function("));
-      if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
-                                     DebugLogging) ||
-          PipelineText.empty())
-        return false;
-      assert(PipelineText[0] == ')');
-      PipelineText = PipelineText.substr(1);
-
-      // Add the nested pass manager with the appropriate adaptor.
-      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);
-    }
-
-    if (PipelineText.empty() || PipelineText[0] == ')')
-      return true;
-
-    assert(PipelineText[0] == ',');
-    PipelineText = PipelineText.substr(1);
-  }
-}
-
-// 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 Passes::parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText,
-                               bool VerifyEachPass, bool DebugLogging) {
-  // By default, try to parse the pipeline as-if it were within an implicit
-  // 'module(...)' pass pipeline. If this will parse at all, it needs to
-  // consume the entire string.
-  if (parseModulePassPipeline(MPM, PipelineText, VerifyEachPass, DebugLogging))
-    return PipelineText.empty();
-
-  // This isn't parsable as a module pipeline, look for the end of a pass name
-  // and directly drop down to that layer.
-  StringRef FirstName =
-      PipelineText.substr(0, PipelineText.find_first_of(",)"));
-  assert(!isModulePassName(FirstName) &&
-         "Already handled all module pipeline options.");
-
-  // If this looks like a CGSCC pass, parse the whole thing as a CGSCC
-  // pipeline.
-  if (isCGSCCPassName(FirstName)) {
-    CGSCCPassManager CGPM(DebugLogging);
-    if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass,
-                                DebugLogging) ||
-        !PipelineText.empty())
-      return false;
-    MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
-    return true;
-  }
-
-  // Similarly, if this looks like a Function pass, parse the whole thing as
-  // a Function pipelien.
-  if (isFunctionPassName(FirstName)) {
-    FunctionPassManager FPM(DebugLogging);
-    if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass,
-                                   DebugLogging) ||
-        !PipelineText.empty())
-      return false;
-    MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
-    return true;
-  }
-
-  return false;
-}
diff --git a/tools/opt/Passes.h b/tools/opt/Passes.h
deleted file mode 100644 (file)
index d3cb628..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-//===- Passes.h - Utilities for manipulating all passes ---------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-/// \file
-///
-/// Interfaces for registering passes, producing common pass manager
-/// configurations, and parsing of pass pipelines.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TOOLS_OPT_PASSES_H
-#define LLVM_TOOLS_OPT_PASSES_H
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Analysis/CGSCCPassManager.h"
-#include "llvm/IR/PassManager.h"
-
-namespace llvm {
-class TargetMachine;
-
-/// \brief This class provides access to all of LLVM's passes.
-///
-/// It's members provide the baseline state available to passes during their
-/// construction. The \c PassRegistry.def file specifies how to construct all
-/// of the built-in passes, and those may reference these members during
-/// construction.
-class Passes {
-  TargetMachine *TM;
-
-public:
-  explicit Passes(TargetMachine *TM = nullptr) : TM(TM) {}
-
-  /// \brief Registers all available module analysis passes.
-  ///
-  /// This is an interface that can be used to populate a \c
-  /// ModuleAnalysisManager with all registered module analyses. Callers can
-  /// still manually register any additional analyses.
-  void registerModuleAnalyses(ModuleAnalysisManager &MAM);
-
-  /// \brief Registers all available CGSCC analysis passes.
-  ///
-  /// This is an interface that can be used to populate a \c CGSCCAnalysisManager
-  /// with all registered CGSCC analyses. Callers can still manually register any
-  /// additional analyses.
-  void registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM);
-
-  /// \brief Registers all available function analysis passes.
-  ///
-  /// This is an interface that can be used to populate a \c
-  /// FunctionAnalysisManager with all registered function analyses. Callers can
-  /// still manually register any additional analyses.
-  void registerFunctionAnalyses(FunctionAnalysisManager &FAM);
-
-  /// \brief Parse a textual pass pipeline description into a \c ModulePassManager.
-  ///
-  /// The format of the textual pass pipeline description looks something like:
-  ///
-  ///   module(function(instcombine,sroa),dce,cgscc(inliner,function(...)),...)
-  ///
-  /// Pass managers have ()s describing the nest structure of passes. All passes
-  /// are comma separated. As a special shortcut, if the very first pass is not
-  /// a module pass (as a module pass manager is), this will automatically form
-  /// the shortest stack of pass managers that allow inserting that first pass.
-  /// So, assuming function passes 'fpassN', CGSCC passes 'cgpassN', and loop passes
-  /// 'lpassN', all of these are valid:
-  ///
-  ///   fpass1,fpass2,fpass3
-  ///   cgpass1,cgpass2,cgpass3
-  ///   lpass1,lpass2,lpass3
-  ///
-  /// And they are equivalent to the following (resp.):
-  ///
-  ///   module(function(fpass1,fpass2,fpass3))
-  ///   module(cgscc(cgpass1,cgpass2,cgpass3))
-  ///   module(function(loop(lpass1,lpass2,lpass3)))
-  ///
-  /// This shortcut is especially useful for debugging and testing small pass
-  /// combinations. Note that these shortcuts don't introduce any other magic. If
-  /// 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 VerifyEachPass = true, bool DebugLogging = false);
-
-private:
-  bool parseModulePassName(ModulePassManager &MPM, StringRef Name);
-  bool parseCGSCCPassName(CGSCCPassManager &CGPM, StringRef Name);
-  bool parseFunctionPassName(FunctionPassManager &FPM, StringRef Name);
-  bool parseFunctionPassPipeline(FunctionPassManager &FPM,
-                                 StringRef &PipelineText, bool VerifyEachPass,
-                                 bool DebugLogging);
-  bool parseCGSCCPassPipeline(CGSCCPassManager &CGPM, StringRef &PipelineText,
-                              bool VerifyEachPass, bool DebugLogging);
-  bool parseModulePassPipeline(ModulePassManager &MPM, StringRef &PipelineText,
-                               bool VerifyEachPass, bool DebugLogging);
-};
-
-}
-
-#endif