summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/Analysis/LoopInfo.h38
-rw-r--r--llvm/lib/Analysis/LoopInfo.cpp21
-rw-r--r--llvm/test/Analysis/LoopInfo/2003-05-15-NestingProblem.ll1
-rw-r--r--llvm/tools/opt/PassRegistry.def2
-rw-r--r--llvm/tools/opt/Passes.cpp1
5 files changed, 63 insertions, 0 deletions
diff --git a/llvm/include/llvm/Analysis/LoopInfo.h b/llvm/include/llvm/Analysis/LoopInfo.h
index 0b78983380f..7811f24b863 100644
--- a/llvm/include/llvm/Analysis/LoopInfo.h
+++ b/llvm/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 <typename IRUnitT> class AnalysisManager;
+class PreservedAnalyses;
+
template<typename T>
inline void RemoveFromVector(std::vector<T*> &V, T *N) {
typename std::vector<T*>::iterator I = std::find(V.begin(), V.end(), N);
@@ -716,6 +721,39 @@ template <> struct GraphTraits<Loop*> {
}
};
+/// \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<Function> *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<Function> *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/llvm/lib/Analysis/LoopInfo.cpp b/llvm/lib/Analysis/LoopInfo.cpp
index 5fde485beca..95f6eb0af0f 100644
--- a/llvm/lib/Analysis/LoopInfo.cpp
+++ b/llvm/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 <algorithm>
@@ -667,6 +668,26 @@ void LoopInfo::updateUnloop(Loop *Unloop) {
}
}
+char LoopAnalysis::PassID;
+
+LoopInfo LoopAnalysis::run(Function &F, AnalysisManager<Function> *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<DominatorTreeAnalysis>(F));
+ return std::move(LI);
+}
+
+PreservedAnalyses LoopPrinterPass::run(Function &F,
+ AnalysisManager<Function> *AM) {
+ AM->getResult<LoopAnalysis>(F).print(OS);
+ return PreservedAnalyses::all();
+}
+
//===----------------------------------------------------------------------===//
// LoopInfo implementation
//
diff --git a/llvm/test/Analysis/LoopInfo/2003-05-15-NestingProblem.ll b/llvm/test/Analysis/LoopInfo/2003-05-15-NestingProblem.ll
index a87bab7cabf..599b3e4b031 100644
--- a/llvm/test/Analysis/LoopInfo/2003-05-15-NestingProblem.ll
+++ b/llvm/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<loops>' -disable-output 2>&1 | FileCheck %s
; CHECK: Loop at depth 4 containing: %loopentry.7<header><latch><exiting>
diff --git a/llvm/tools/opt/PassRegistry.def b/llvm/tools/opt/PassRegistry.def
index 411ca0f02d8..66ee5e56272 100644
--- a/llvm/tools/opt/PassRegistry.def
+++ b/llvm/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<all>", InvalidateAllAnalysesPass())
FUNCTION_PASS("no-op-function", NoOpFunctionPass())
FUNCTION_PASS("print", PrintFunctionPass(dbgs()))
FUNCTION_PASS("print<domtree>", DominatorTreePrinterPass(dbgs()))
+FUNCTION_PASS("print<loops>", LoopPrinterPass(dbgs()))
FUNCTION_PASS("verify", VerifierPass())
FUNCTION_PASS("verify<domtree>", DominatorTreeVerifierPass())
#undef FUNCTION_PASS
diff --git a/llvm/tools/opt/Passes.cpp b/llvm/tools/opt/Passes.cpp
index 1af4d52b870..ee515430554 100644
--- a/llvm/tools/opt/Passes.cpp
+++ b/llvm/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"
OpenPOWER on IntegriCloud