diff options
Diffstat (limited to 'contrib/llvm/lib/Analysis/LoopPass.cpp')
-rw-r--r-- | contrib/llvm/lib/Analysis/LoopPass.cpp | 139 |
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 |