diff --git a/include/llvm/IR/Dominators.h b/include/llvm/IR/Dominators.h index 4e7dacc1a37..c1f208e3d72 100644 --- a/include/llvm/IR/Dominators.h +++ b/include/llvm/IR/Dominators.h @@ -31,6 +31,11 @@ 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 class AnalysisManager; +class PreservedAnalyses; + EXTERN_TEMPLATE_INSTANTIATION(class DomTreeNodeBase); EXTERN_TEMPLATE_INSTANTIATION(class DominatorTreeBase); @@ -162,6 +167,43 @@ template <> struct GraphTraits }; /// \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 *AM); + + static StringRef name() { return "DominatorTreePrinterPass"; } +}; + +/// \brief Verifier pass for the \c DominatorTree. +struct DominatorTreeVerifierPass { + PreservedAnalyses run(Function &F, AnalysisManager *AM); + + static StringRef name() { return "DominatorTreeVerifierPass"; } +}; + +/// \brief Legacy analysis pass which computes a \c DominatorTree. class DominatorTreeWrapperPass : public FunctionPass { DominatorTree DT; diff --git a/lib/IR/Dominators.cpp b/lib/IR/Dominators.cpp index d6649d6c706..9b6ff1eb136 100644 --- a/lib/IR/Dominators.cpp +++ b/lib/IR/Dominators.cpp @@ -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(F).print(OS); + + return PreservedAnalyses::all(); +} + +PreservedAnalyses DominatorTreeVerifierPass::run(Function &F, + FunctionAnalysisManager *AM) { + AM->getResult(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. // //===----------------------------------------------------------------------===// diff --git a/test/Analysis/Dominators/basic.ll b/test/Analysis/Dominators/basic.ll index 8627a87b557..353c3397b5d 100644 --- a/test/Analysis/Dominators/basic.ll +++ b/test/Analysis/Dominators/basic.ll @@ -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' 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 diff --git a/tools/opt/NewPMDriver.cpp b/tools/opt/NewPMDriver.cpp index d37211faf6d..f215c77459a 100644 --- a/tools/opt/NewPMDriver.cpp +++ b/tools/opt/NewPMDriver.cpp @@ -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" diff --git a/tools/opt/PassRegistry.def b/tools/opt/PassRegistry.def index e05dae871b8..c98de60b570 100644 --- a/tools/opt/PassRegistry.def +++ b/tools/opt/PassRegistry.def @@ -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", InvalidateAllAnalysesPass()) FUNCTION_PASS("no-op-function", NoOpFunctionPass()) FUNCTION_PASS("print", PrintFunctionPass(dbgs())) +FUNCTION_PASS("print", DominatorTreePrinterPass(dbgs())) FUNCTION_PASS("verify", VerifierPass()) +FUNCTION_PASS("verify", DominatorTreeVerifierPass()) #undef FUNCTION_PASS diff --git a/tools/opt/Passes.cpp b/tools/opt/Passes.cpp index c81c5633684..518112a1c88 100644 --- a/tools/opt/Passes.cpp +++ b/tools/opt/Passes.cpp @@ -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"