summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Analysis/LoopPass.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Analysis/LoopPass.cpp')
-rw-r--r--contrib/llvm/lib/Analysis/LoopPass.cpp139
1 files changed, 42 insertions, 97 deletions
diff --git a/contrib/llvm/lib/Analysis/LoopPass.cpp b/contrib/llvm/lib/Analysis/LoopPass.cpp
index e9fcf02..dc42473 100644
--- a/contrib/llvm/lib/Analysis/LoopPass.cpp
+++ b/contrib/llvm/lib/Analysis/LoopPass.cpp
@@ -16,6 +16,7 @@
#include "llvm/Analysis/LoopPass.h"
#include "llvm/IR/IRPrintingPasses.h"
#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
@@ -27,35 +28,26 @@ namespace {
/// PrintLoopPass - Print a Function corresponding to a Loop.
///
-class PrintLoopPass : public LoopPass {
-private:
- std::string Banner;
- raw_ostream &Out; // raw_ostream to print on.
+class PrintLoopPassWrapper : public LoopPass {
+ PrintLoopPass P;
public:
static char ID;
- PrintLoopPass(const std::string &B, raw_ostream &o)
- : LoopPass(ID), Banner(B), Out(o) {}
+ PrintLoopPassWrapper() : LoopPass(ID) {}
+ PrintLoopPassWrapper(raw_ostream &OS, const std::string &Banner)
+ : LoopPass(ID), P(OS, Banner) {}
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesAll();
}
bool runOnLoop(Loop *L, LPPassManager &) override {
- Out << Banner;
- for (Loop::block_iterator b = L->block_begin(), be = L->block_end();
- b != be;
- ++b) {
- if (*b)
- (*b)->print(Out);
- else
- Out << "Printing <null> block";
- }
+ P.run(*L);
return false;
}
};
-char PrintLoopPass::ID = 0;
+char PrintLoopPassWrapper::ID = 0;
}
//===----------------------------------------------------------------------===//
@@ -66,81 +58,34 @@ char LPPassManager::ID = 0;
LPPassManager::LPPassManager()
: FunctionPass(ID), PMDataManager() {
- skipThisLoop = false;
- redoThisLoop = false;
LI = nullptr;
CurrentLoop = nullptr;
}
-/// Delete loop from the loop queue and loop hierarchy (LoopInfo).
-void LPPassManager::deleteLoopFromQueue(Loop *L) {
-
- LI->updateUnloop(L);
-
- // Notify passes that the loop is being deleted.
- deleteSimpleAnalysisLoop(L);
-
- // If L is current loop then skip rest of the passes and let
- // runOnFunction remove L from LQ. Otherwise, remove L from LQ now
- // and continue applying other passes on CurrentLoop.
- if (CurrentLoop == L)
- skipThisLoop = true;
-
- delete L;
-
- if (skipThisLoop)
- return;
-
- for (std::deque<Loop *>::iterator I = LQ.begin(),
- E = LQ.end(); I != E; ++I) {
- if (*I == L) {
- LQ.erase(I);
- break;
- }
- }
-}
-
// Inset loop into loop nest (LoopInfo) and loop queue (LQ).
-void LPPassManager::insertLoop(Loop *L, Loop *ParentLoop) {
-
- assert (CurrentLoop != L && "Cannot insert CurrentLoop");
+Loop &LPPassManager::addLoop(Loop *ParentLoop) {
+ // Create a new loop. LI will take ownership.
+ Loop *L = new Loop();
- // Insert into loop nest
- if (ParentLoop)
- ParentLoop->addChildLoop(L);
- else
+ // Insert into the loop nest and the loop queue.
+ if (!ParentLoop) {
+ // This is the top level loop.
LI->addTopLevelLoop(L);
-
- insertLoopIntoQueue(L);
-}
-
-void LPPassManager::insertLoopIntoQueue(Loop *L) {
- // Insert L into loop queue
- if (L == CurrentLoop)
- redoLoop(L);
- else if (!L->getParentLoop())
- // This is top level loop.
LQ.push_front(L);
- else {
- // Insert L after the parent loop.
- for (std::deque<Loop *>::iterator I = LQ.begin(),
- E = LQ.end(); I != E; ++I) {
- if (*I == L->getParentLoop()) {
- // deque does not support insert after.
- ++I;
- LQ.insert(I, 1, L);
- break;
- }
- }
+ return *L;
}
-}
-// Reoptimize this loop. LPPassManager will re-insert this loop into the
-// queue. This allows LoopPass to change loop nest for the loop. This
-// utility may send LPPassManager into infinite loops so use caution.
-void LPPassManager::redoLoop(Loop *L) {
- assert (CurrentLoop == L && "Can redo only CurrentLoop");
- redoThisLoop = true;
+ ParentLoop->addChildLoop(L);
+ // Insert L into the loop queue after the parent loop.
+ for (auto I = LQ.begin(), E = LQ.end(); I != E; ++I) {
+ if (*I == L->getParentLoop()) {
+ // deque does not support insert after.
+ ++I;
+ LQ.insert(I, 1, L);
+ break;
+ }
+ }
+ return *L;
}
/// cloneBasicBlockSimpleAnalysis - Invoke cloneBasicBlockAnalysis hook for
@@ -230,10 +175,7 @@ bool LPPassManager::runOnFunction(Function &F) {
// Walk Loops
while (!LQ.empty()) {
- CurrentLoop = LQ.back();
- skipThisLoop = false;
- redoThisLoop = false;
-
+ CurrentLoop = LQ.back();
// Run all passes on the current Loop.
for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
LoopPass *P = getContainedPass(Index);
@@ -253,11 +195,15 @@ bool LPPassManager::runOnFunction(Function &F) {
if (Changed)
dumpPassInfo(P, MODIFICATION_MSG, ON_LOOP_MSG,
- skipThisLoop ? "<deleted>" :
- CurrentLoop->getHeader()->getName());
+ CurrentLoop->isUnloop()
+ ? "<deleted>"
+ : CurrentLoop->getHeader()->getName());
dumpPreservedSet(P);
- if (!skipThisLoop) {
+ if (CurrentLoop->isUnloop()) {
+ // Notify passes that the loop is being deleted.
+ deleteSimpleAnalysisLoop(CurrentLoop);
+ } else {
// Manually check that this loop is still healthy. This is done
// instead of relying on LoopInfo::verifyLoop since LoopInfo
// is a function pass and it's really expensive to verify every
@@ -276,12 +222,12 @@ bool LPPassManager::runOnFunction(Function &F) {
removeNotPreservedAnalysis(P);
recordAvailableAnalysis(P);
- removeDeadPasses(P,
- skipThisLoop ? "<deleted>" :
- CurrentLoop->getHeader()->getName(),
+ removeDeadPasses(P, CurrentLoop->isUnloop()
+ ? "<deleted>"
+ : CurrentLoop->getHeader()->getName(),
ON_LOOP_MSG);
- if (skipThisLoop)
+ if (CurrentLoop->isUnloop())
// Do not run other passes on this loop.
break;
}
@@ -289,17 +235,16 @@ bool LPPassManager::runOnFunction(Function &F) {
// If the loop was deleted, release all the loop passes. This frees up
// some memory, and avoids trouble with the pass manager trying to call
// verifyAnalysis on them.
- if (skipThisLoop)
+ if (CurrentLoop->isUnloop()) {
for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
Pass *P = getContainedPass(Index);
freePass(P, "<deleted>", ON_LOOP_MSG);
}
+ delete CurrentLoop;
+ }
// Pop the loop from queue after running all passes.
LQ.pop_back();
-
- if (redoThisLoop)
- LQ.push_back(CurrentLoop);
}
// Finalization
@@ -327,7 +272,7 @@ void LPPassManager::dumpPassStructure(unsigned Offset) {
Pass *LoopPass::createPrinterPass(raw_ostream &O,
const std::string &Banner) const {
- return new PrintLoopPass(Banner, O);
+ return new PrintLoopPassWrapper(O, Banner);
}
// Check if this pass is suitable for the current LPPassManager, if
OpenPOWER on IntegriCloud