X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FAnalysis%2FLoopPass.cpp;h=d42425d753eab8a93db046e0f123ec55b7e2570e;hb=9ba0e1d411584c37b9ba53e58383962566dbe183;hp=90f64fb865782bc15c7d2a6e56afa53844656807;hpb=cf84b5ba5eecf5ae1b3d8b7af77fbb9f08b48d49;p=oota-llvm.git diff --git a/lib/Analysis/LoopPass.cpp b/lib/Analysis/LoopPass.cpp index 90f64fb8657..d42425d753e 100644 --- a/lib/Analysis/LoopPass.cpp +++ b/lib/Analysis/LoopPass.cpp @@ -15,10 +15,14 @@ #include "llvm/Analysis/LoopPass.h" #include "llvm/IR/IRPrintingPasses.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Timer.h" +#include "llvm/Support/raw_ostream.h" using namespace llvm; +#define DEBUG_TYPE "loop-pass-manager" + namespace { /// PrintLoopPass - Print a Function corresponding to a Loop. @@ -33,16 +37,19 @@ public: PrintLoopPass(const std::string &B, raw_ostream &o) : LoopPass(ID), Banner(B), Out(o) {} - virtual void getAnalysisUsage(AnalysisUsage &AU) const { + void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesAll(); } - bool runOnLoop(Loop *L, LPPassManager &) { + bool runOnLoop(Loop *L, LPPassManager &) override { Out << Banner; for (Loop::block_iterator b = L->block_begin(), be = L->block_end(); b != be; ++b) { - (*b)->print(Out); + if (*b) + (*b)->print(Out); + else + Out << "Printing block"; } return false; } @@ -60,9 +67,8 @@ char LPPassManager::ID = 0; LPPassManager::LPPassManager() : FunctionPass(ID), PMDataManager() { skipThisLoop = false; - redoThisLoop = false; - LI = NULL; - CurrentLoop = NULL; + LI = nullptr; + CurrentLoop = nullptr; } /// Delete loop from the loop queue and loop hierarchy (LoopInfo). @@ -70,6 +76,9 @@ 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. @@ -91,46 +100,29 @@ void LPPassManager::deleteLoopFromQueue(Loop *L) { } // 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::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 @@ -158,6 +150,14 @@ void LPPassManager::deleteSimpleAnalysisValue(Value *V, Loop *L) { } } +/// Invoke deleteAnalysisLoop hook for all passes. +void LPPassManager::deleteSimpleAnalysisLoop(Loop *L) { + for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { + LoopPass *LP = getContainedPass(Index); + LP->deleteAnalysisLoop(L); + } +} + // Recurse through all subloops and all loops into LQ. static void addLoopIntoQueue(Loop *L, std::deque &LQ) { @@ -170,14 +170,15 @@ static void addLoopIntoQueue(Loop *L, std::deque &LQ) { void LPPassManager::getAnalysisUsage(AnalysisUsage &Info) const { // LPPassManager needs LoopInfo. In the long term LoopInfo class will // become part of LPPassManager. - Info.addRequired(); + Info.addRequired(); Info.setPreservesAll(); } /// run - Execute all of the passes scheduled for execution. Keep track of /// whether any of the passes modifies the function, and if so, return true. bool LPPassManager::runOnFunction(Function &F) { - LI = &getAnalysis(); + auto &LIWP = getAnalysis(); + LI = &LIWP.getLoopInfo(); bool Changed = false; // Collect inherited analysis from Module level pass manager. @@ -213,7 +214,6 @@ bool LPPassManager::runOnFunction(Function &F) { CurrentLoop = LQ.back(); skipThisLoop = false; - redoThisLoop = false; // Run all passes on the current Loop. for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { @@ -245,12 +245,14 @@ bool LPPassManager::runOnFunction(Function &F) { // loop in the function every time. That level of checking can be // enabled with the -verify-loop-info option. { - TimeRegion PassTimer(getPassTimer(LI)); + TimeRegion PassTimer(getPassTimer(&LIWP)); CurrentLoop->verifyLoop(); } // Then call the regular verifyAnalysis functions. verifyPreservedAnalysis(P); + + F.getContext().yield(); } removeNotPreservedAnalysis(P); @@ -276,9 +278,6 @@ bool LPPassManager::runOnFunction(Function &F) { // Pop the loop from queue after running all passes. LQ.pop_back(); - - if (redoThisLoop) - LQ.push_back(CurrentLoop); } // Finalization