[PM] Port domtree to the new pass manager (at last).
authorChandler Carruth <chandlerc@gmail.com>
Wed, 14 Jan 2015 10:19:28 +0000 (10:19 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Wed, 14 Jan 2015 10:19:28 +0000 (10:19 +0000)
This adds the domtree analysis to the new pass manager. The analysis
returns the same DominatorTree result entity used by the old pass
manager and essentially all of the code is shared. We just have
different boilerplate for running and printing the analysis.

I've converted one test to run in both modes just to make sure this is
exercised while both are live in the tree.

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

include/llvm/IR/Dominators.h
lib/IR/Dominators.cpp
test/Analysis/Dominators/basic.ll
tools/opt/NewPMDriver.cpp
tools/opt/PassRegistry.def
tools/opt/Passes.cpp

index 4e7dacc1a373cedb3490fb3b96ffa0cd0ee7befa..c1f208e3d72fffb5f81aa0cbe6d63c432c55581f 100644 (file)
 
 namespace llvm {
 
+// FIXME: Replace this brittle forward declaration with the include of the new
+// PassManager.h when doing so doesn't break the PassManagerBuilder.
+template <typename IRUnitT> class AnalysisManager;
+class PreservedAnalyses;
+
 EXTERN_TEMPLATE_INSTANTIATION(class DomTreeNodeBase<BasicBlock>);
 EXTERN_TEMPLATE_INSTANTIATION(class DominatorTreeBase<BasicBlock>);
 
@@ -162,6 +167,43 @@ template <> struct GraphTraits<DominatorTree*>
 };
 
 /// \brief Analysis pass which computes a \c DominatorTree.
+class DominatorTreeAnalysis {
+public:
+  /// \brief Provide the result typedef for this analysis pass.
+  typedef DominatorTree Result;
+
+  /// \brief Opaque, unique identifier for this analysis pass.
+  static void *ID() { return (void *)&PassID; }
+
+  /// \brief Run the analysis pass over a function and produce a dominator tree.
+  DominatorTree run(Function &F);
+
+  /// \brief Provide access to a name for this pass for debugging purposes.
+  static StringRef name() { return "DominatorTreeAnalysis"; }
+
+private:
+  static char PassID;
+};
+
+/// \brief Printer pass for the \c DominatorTree.
+class DominatorTreePrinterPass {
+  raw_ostream &OS;
+
+public:
+  explicit DominatorTreePrinterPass(raw_ostream &OS);
+  PreservedAnalyses run(Function &F, AnalysisManager<Function> *AM);
+
+  static StringRef name() { return "DominatorTreePrinterPass"; }
+};
+
+/// \brief Verifier pass for the \c DominatorTree.
+struct DominatorTreeVerifierPass {
+  PreservedAnalyses run(Function &F, AnalysisManager<Function> *AM);
+
+  static StringRef name() { return "DominatorTreeVerifierPass"; }
+};
+
+/// \brief Legacy analysis pass which computes a \c DominatorTree.
 class DominatorTreeWrapperPass : public FunctionPass {
   DominatorTree DT;
 
index d6649d6c7064bcc862abb2878b26ca524585da30..9b6ff1eb1366df3f923975fdc234e9450e445e21 100644 (file)
@@ -20,6 +20,7 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/IR/CFG.h"
 #include "llvm/IR/Instructions.h"
+#include "llvm/IR/PassManager.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/Debug.h"
@@ -297,11 +298,46 @@ void DominatorTree::verifyDomTree() const {
   }
 }
 
+//===----------------------------------------------------------------------===//
+//  DominatorTreeAnalysis and related pass implementations
+//===----------------------------------------------------------------------===//
+//
+// This implements the DominatorTreeAnalysis which is used with the new pass
+// manager. It also implements some methods from utility passes.
+//
+//===----------------------------------------------------------------------===//
+
+DominatorTree DominatorTreeAnalysis::run(Function &F) {
+  DominatorTree DT;
+  DT.recalculate(F);
+  return DT;
+}
+
+char DominatorTreeAnalysis::PassID;
+
+DominatorTreePrinterPass::DominatorTreePrinterPass(raw_ostream &OS) : OS(OS) {}
+
+PreservedAnalyses DominatorTreePrinterPass::run(Function &F,
+                                                FunctionAnalysisManager *AM) {
+  OS << "DominatorTree for function: " << F.getName() << "\n";
+  AM->getResult<DominatorTreeAnalysis>(F).print(OS);
+
+  return PreservedAnalyses::all();
+}
+
+PreservedAnalyses DominatorTreeVerifierPass::run(Function &F,
+                                                 FunctionAnalysisManager *AM) {
+  AM->getResult<DominatorTreeAnalysis>(F).verifyDomTree();
+
+  return PreservedAnalyses::all();
+}
+
 //===----------------------------------------------------------------------===//
 //  DominatorTreeWrapperPass Implementation
 //===----------------------------------------------------------------------===//
 //
-// The implementation details of the wrapper pass that holds a DominatorTree.
+// The implementation details of the wrapper pass that holds a DominatorTree
+// suitable for use with the legacy pass manager.
 //
 //===----------------------------------------------------------------------===//
 
index 8627a87b5573071baa267643103b00edaca4db2e..353c3397b5da7a8f2606ba40dde2a06080020bcc 100644 (file)
@@ -1,7 +1,9 @@
-; RUN: opt < %s -domtree -analyze | FileCheck %s
+; RUN: opt < %s -domtree -analyze | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-OLDPM
+; RUN: opt < %s -disable-output -passes='print<domtree>' 2>&1 | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-NEWPM
 
 define void @test1() {
-; CHECK-LABEL: 'Dominator Tree Construction' for function 'test1':
+; CHECK-OLDPM-LABEL: 'Dominator Tree Construction' for function 'test1':
+; CHECK-NEWPM-LABEL: DominatorTree for function: test1
 ; CHECK:      [1] %entry
 ; CHECK-NEXT:   [2] %a
 ; CHECK-NEXT:   [2] %c
@@ -29,7 +31,8 @@ e:
 }
 
 define void @test2() {
-; CHECK-LABEL: 'Dominator Tree Construction' for function 'test2':
+; CHECK-OLDPM-LABEL: 'Dominator Tree Construction' for function 'test2':
+; CHECK-NEWPM-LABEL: DominatorTree for function: test2
 ; CHECK:      [1] %entry
 ; CHECK-NEXT:   [2] %a
 ; CHECK-NEXT:     [3] %b
index d37211faf6d53fb9dfd71541d588119ab9f0b982..f215c77459a854960e7f260742970e3fb89aa76c 100644 (file)
@@ -18,6 +18,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Analysis/CGSCCPassManager.h"
 #include "llvm/Bitcode/BitcodeWriterPass.h"
+#include "llvm/IR/Dominators.h"
 #include "llvm/IR/IRPrintingPasses.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
index e05dae871b8fb4e59cdf8290e1f9772a3ff715e5..c98de60b5706826c5bfa162ac5acd58b2c4a8653 100644 (file)
@@ -49,6 +49,7 @@ CGSCC_PASS("no-op-cgscc", NoOpCGSCCPass())
 #ifndef FUNCTION_ANALYSIS
 #define FUNCTION_ANALYSIS(NAME, CREATE_PASS)
 #endif
+FUNCTION_ANALYSIS("domtree", DominatorTreeAnalysis())
 FUNCTION_ANALYSIS("no-op-function", NoOpFunctionAnalysis())
 #undef FUNCTION_ANALYSIS
 
@@ -58,5 +59,7 @@ FUNCTION_ANALYSIS("no-op-function", NoOpFunctionAnalysis())
 FUNCTION_PASS("invalidate<all>", InvalidateAllAnalysesPass())
 FUNCTION_PASS("no-op-function", NoOpFunctionPass())
 FUNCTION_PASS("print", PrintFunctionPass(dbgs()))
+FUNCTION_PASS("print<domtree>", DominatorTreePrinterPass(dbgs()))
 FUNCTION_PASS("verify", VerifierPass())
+FUNCTION_PASS("verify<domtree>", DominatorTreeVerifierPass())
 #undef FUNCTION_PASS
index c81c5633684490ebf1c6812970598fe6a3998f78..518112a1c88c05475bf6f0fd853c88f3ec3f417d 100644 (file)
@@ -17,6 +17,7 @@
 #include "Passes.h"
 #include "llvm/Analysis/CGSCCPassManager.h"
 #include "llvm/Analysis/LazyCallGraph.h"
+#include "llvm/IR/Dominators.h"
 #include "llvm/IR/IRPrintingPasses.h"
 #include "llvm/IR/PassManager.h"
 #include "llvm/IR/Verifier.h"