diff options
author | Dan Gohman <gohman@apple.com> | 2009-09-28 14:37:51 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2009-09-28 14:37:51 +0000 |
commit | d84db1133345234738b646c70b907bf8a0983ac9 (patch) | |
tree | 2a05c1fab009c020e9d20c14a135dbcb686b2f56 /lib/Transforms/IPO/LoopExtractor.cpp | |
parent | 522ce975327e1aeba8317b233cdb54366e2645b5 (diff) |
Convert LoopSimplify and LoopExtractor from FunctionPass to LoopPass.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82990 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/IPO/LoopExtractor.cpp')
-rw-r--r-- | lib/Transforms/IPO/LoopExtractor.cpp | 104 |
1 files changed, 41 insertions, 63 deletions
diff --git a/lib/Transforms/IPO/LoopExtractor.cpp b/lib/Transforms/IPO/LoopExtractor.cpp index 4b0988441d..02ac3bb903 100644 --- a/lib/Transforms/IPO/LoopExtractor.cpp +++ b/lib/Transforms/IPO/LoopExtractor.cpp @@ -20,7 +20,7 @@ #include "llvm/Module.h" #include "llvm/Pass.h" #include "llvm/Analysis/Dominators.h" -#include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/LoopPass.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" #include "llvm/Transforms/Scalar.h" @@ -33,23 +33,19 @@ using namespace llvm; STATISTIC(NumExtracted, "Number of loops extracted"); namespace { - // FIXME: This is not a function pass, but the PassManager doesn't allow - // Module passes to require FunctionPasses, so we can't get loop info if we're - // not a function pass. - struct VISIBILITY_HIDDEN LoopExtractor : public FunctionPass { + struct VISIBILITY_HIDDEN LoopExtractor : public LoopPass { static char ID; // Pass identification, replacement for typeid unsigned NumLoops; explicit LoopExtractor(unsigned numLoops = ~0) - : FunctionPass(&ID), NumLoops(numLoops) {} + : LoopPass(&ID), NumLoops(numLoops) {} - virtual bool runOnFunction(Function &F); + virtual bool runOnLoop(Loop *L, LPPassManager &LPM); virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequiredID(BreakCriticalEdgesID); AU.addRequiredID(LoopSimplifyID); AU.addRequired<DominatorTree>(); - AU.addRequired<LoopInfo>(); } }; } @@ -73,68 +69,50 @@ Y("loop-extract-single", "Extract at most one loop into a new function"); // createLoopExtractorPass - This pass extracts all natural loops from the // program into a function if it can. // -FunctionPass *llvm::createLoopExtractorPass() { return new LoopExtractor(); } +Pass *llvm::createLoopExtractorPass() { return new LoopExtractor(); } -bool LoopExtractor::runOnFunction(Function &F) { - LoopInfo &LI = getAnalysis<LoopInfo>(); - - // If this function has no loops, there is nothing to do. - if (LI.empty()) +bool LoopExtractor::runOnLoop(Loop *L, LPPassManager &LPM) { + // Only visit top-level loops. + if (L->getParentLoop()) return false; DominatorTree &DT = getAnalysis<DominatorTree>(); - - // If there is more than one top-level loop in this function, extract all of - // the loops. bool Changed = false; - if (LI.end()-LI.begin() > 1) { - for (LoopInfo::iterator i = LI.begin(), e = LI.end(); i != e; ++i) { - if (NumLoops == 0) return Changed; - --NumLoops; - Changed |= ExtractLoop(DT, *i) != 0; - ++NumExtracted; - } - } else { - // Otherwise there is exactly one top-level loop. If this function is more - // than a minimal wrapper around the loop, extract the loop. - Loop *TLL = *LI.begin(); - bool ShouldExtractLoop = false; - - // Extract the loop if the entry block doesn't branch to the loop header. - TerminatorInst *EntryTI = F.getEntryBlock().getTerminator(); - if (!isa<BranchInst>(EntryTI) || - !cast<BranchInst>(EntryTI)->isUnconditional() || - EntryTI->getSuccessor(0) != TLL->getHeader()) - ShouldExtractLoop = true; - else { - // Check to see if any exits from the loop are more than just return - // blocks. - SmallVector<BasicBlock*, 8> ExitBlocks; - TLL->getExitBlocks(ExitBlocks); - for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) - if (!isa<ReturnInst>(ExitBlocks[i]->getTerminator())) { - ShouldExtractLoop = true; - break; - } - } - if (ShouldExtractLoop) { - if (NumLoops == 0) return Changed; - --NumLoops; - Changed |= ExtractLoop(DT, TLL) != 0; - ++NumExtracted; - } else { - // Okay, this function is a minimal container around the specified loop. - // If we extract the loop, we will continue to just keep extracting it - // infinitely... so don't extract it. However, if the loop contains any - // subloops, extract them. - for (Loop::iterator i = TLL->begin(), e = TLL->end(); i != e; ++i) { - if (NumLoops == 0) return Changed; - --NumLoops; - Changed |= ExtractLoop(DT, *i) != 0; - ++NumExtracted; + // If there is more than one top-level loop in this function, extract all of + // the loops. Otherwise there is exactly one top-level loop; in this case if + // this function is more than a minimal wrapper around the loop, extract + // the loop. + bool ShouldExtractLoop = false; + + // Extract the loop if the entry block doesn't branch to the loop header. + TerminatorInst *EntryTI = + L->getHeader()->getParent()->getEntryBlock().getTerminator(); + if (!isa<BranchInst>(EntryTI) || + !cast<BranchInst>(EntryTI)->isUnconditional() || + EntryTI->getSuccessor(0) != L->getHeader()) + ShouldExtractLoop = true; + else { + // Check to see if any exits from the loop are more than just return + // blocks. + SmallVector<BasicBlock*, 8> ExitBlocks; + L->getExitBlocks(ExitBlocks); + for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) + if (!isa<ReturnInst>(ExitBlocks[i]->getTerminator())) { + ShouldExtractLoop = true; + break; } + } + if (ShouldExtractLoop) { + if (NumLoops == 0) return Changed; + --NumLoops; + if (ExtractLoop(DT, L) != 0) { + Changed = true; + // After extraction, the loop is replaced by a function call, so + // we shouldn't try to run any more loop passes on it. + LPM.deleteLoopFromQueue(L); } + ++NumExtracted; } return Changed; @@ -143,7 +121,7 @@ bool LoopExtractor::runOnFunction(Function &F) { // createSingleLoopExtractorPass - This pass extracts one natural loop from the // program into a function if it can. This is used by bugpoint. // -FunctionPass *llvm::createSingleLoopExtractorPass() { +Pass *llvm::createSingleLoopExtractorPass() { return new SingleLoopExtractor(); } |