diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h index 0b78983380f..7811f24b863 100644 --- a/include/llvm/Analysis/LoopInfo.h +++ b/include/llvm/Analysis/LoopInfo.h @@ -42,6 +42,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; + template inline void RemoveFromVector(std::vector &V, T *N) { typename std::vector::iterator I = std::find(V.begin(), V.end(), N); @@ -716,6 +721,39 @@ template <> struct GraphTraits { } }; +/// \brief Analysis pass that exposes the \c LoopInfo for a function. +class LoopAnalysis { + static char PassID; + +public: + typedef LoopInfo Result; + + /// \brief Opaque, unique identifier for this analysis pass. + static void *ID() { return (void *)&PassID; } + + /// \brief Provide a name for the analysis for debugging and logging. + static StringRef name() { return "LoopAnalysis"; } + + LoopAnalysis() {} + LoopAnalysis(const LoopAnalysis &Arg) {} + LoopAnalysis(LoopAnalysis &&Arg) {} + LoopAnalysis &operator=(const LoopAnalysis &RHS) { return *this; } + LoopAnalysis &operator=(LoopAnalysis &&RHS) { return *this; } + + LoopInfo run(Function &F, AnalysisManager *AM); +}; + +/// \brief Printer pass for the \c LoopAnalysis results. +class LoopPrinterPass { + raw_ostream &OS; + +public: + explicit LoopPrinterPass(raw_ostream &OS) : OS(OS) {} + PreservedAnalyses run(Function &F, AnalysisManager *AM); + + static StringRef name() { return "LoopPrinterPass"; } +}; + /// \brief The legacy pass manager's analysis pass to compute loop information. class LoopInfoWrapperPass : public FunctionPass { LoopInfo LI; diff --git a/lib/Analysis/LoopInfo.cpp b/lib/Analysis/LoopInfo.cpp index 5fde485beca..95f6eb0af0f 100644 --- a/lib/Analysis/LoopInfo.cpp +++ b/lib/Analysis/LoopInfo.cpp @@ -26,6 +26,7 @@ #include "llvm/IR/Instructions.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" +#include "llvm/IR/PassManager.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include @@ -667,6 +668,26 @@ void LoopInfo::updateUnloop(Loop *Unloop) { } } +char LoopAnalysis::PassID; + +LoopInfo LoopAnalysis::run(Function &F, AnalysisManager *AM) { + // FIXME: Currently we create a LoopInfo from scratch for every function. + // This may prove to be too wasteful due to deallocating and re-allocating + // memory each time for the underlying map and vector datastructures. At some + // point it may prove worthwhile to use a freelist and recycle LoopInfo + // objects. I don't want to add that kind of complexity until the scope of + // the problem is better understood. + LoopInfo LI; + LI.Analyze(AM->getResult(F)); + return std::move(LI); +} + +PreservedAnalyses LoopPrinterPass::run(Function &F, + AnalysisManager *AM) { + AM->getResult(F).print(OS); + return PreservedAnalyses::all(); +} + //===----------------------------------------------------------------------===// // LoopInfo implementation // diff --git a/test/Analysis/LoopInfo/2003-05-15-NestingProblem.ll b/test/Analysis/LoopInfo/2003-05-15-NestingProblem.ll index a87bab7cabf..599b3e4b031 100644 --- a/test/Analysis/LoopInfo/2003-05-15-NestingProblem.ll +++ b/test/Analysis/LoopInfo/2003-05-15-NestingProblem.ll @@ -2,6 +2,7 @@ ; not a child of the loopentry.6 loop. ; ; RUN: opt < %s -analyze -loops | FileCheck %s +; RUN: opt < %s -passes='print' -disable-output 2>&1 | FileCheck %s ; CHECK: Loop at depth 4 containing: %loopentry.7
diff --git a/tools/opt/PassRegistry.def b/tools/opt/PassRegistry.def index 411ca0f02d8..66ee5e56272 100644 --- a/tools/opt/PassRegistry.def +++ b/tools/opt/PassRegistry.def @@ -51,6 +51,7 @@ CGSCC_PASS("no-op-cgscc", NoOpCGSCCPass()) #define FUNCTION_ANALYSIS(NAME, CREATE_PASS) #endif FUNCTION_ANALYSIS("domtree", DominatorTreeAnalysis()) +FUNCTION_ANALYSIS("loops", LoopAnalysis()) FUNCTION_ANALYSIS("no-op-function", NoOpFunctionAnalysis()) #undef FUNCTION_ANALYSIS @@ -61,6 +62,7 @@ FUNCTION_PASS("invalidate", InvalidateAllAnalysesPass()) FUNCTION_PASS("no-op-function", NoOpFunctionPass()) FUNCTION_PASS("print", PrintFunctionPass(dbgs())) FUNCTION_PASS("print", DominatorTreePrinterPass(dbgs())) +FUNCTION_PASS("print", LoopPrinterPass(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 1af4d52b870..ee515430554 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/Analysis/LoopInfo.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/IRPrintingPasses.h"