diff options
author | Dan Gohman <gohman@apple.com> | 2009-07-15 01:25:43 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2009-07-15 01:25:43 +0000 |
commit | bdc017edacb713119b24ab269d250a82d62fffeb (patch) | |
tree | 7cf92dc3dd53533075ad262c08ec0d23e0dd7e1d | |
parent | 2e2ad51ffd1e0822c7dc128d96113874017ad079 (diff) | |
download | external_llvm-bdc017edacb713119b24ab269d250a82d62fffeb.zip external_llvm-bdc017edacb713119b24ab269d250a82d62fffeb.tar.gz external_llvm-bdc017edacb713119b24ab269d250a82d62fffeb.tar.bz2 |
Make makeLoopInvariant report whether it made any changes or not,
and use this to simplify more code.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75722 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/Analysis/LoopInfo.h | 6 | ||||
-rw-r--r-- | lib/Analysis/LoopInfo.cpp | 11 | ||||
-rw-r--r-- | lib/Transforms/Scalar/LoopDeletion.cpp | 52 | ||||
-rw-r--r-- | lib/Transforms/Scalar/LoopUnswitch.cpp | 5 | ||||
-rw-r--r-- | lib/Transforms/Utils/LoopSimplify.cpp | 10 |
5 files changed, 28 insertions, 56 deletions
diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h index 90afc01..de9a30d 100644 --- a/include/llvm/Analysis/LoopInfo.h +++ b/include/llvm/Analysis/LoopInfo.h @@ -490,7 +490,8 @@ public: /// If InsertPt is specified, it is the point to hoist instructions to. /// If null, the terminator of the loop preheader is used. /// - bool makeLoopInvariant(Value *V, Instruction *InsertPt = 0) const; + bool makeLoopInvariant(Value *V, bool &Changed, + Instruction *InsertPt = 0) const; /// makeLoopInvariant - If the given instruction is inside of the /// loop and it can be hoisted, do so to make it trivially loop-invariant. @@ -501,7 +502,8 @@ public: /// If InsertPt is specified, it is the point to hoist instructions to. /// If null, the terminator of the loop preheader is used. /// - bool makeLoopInvariant(Instruction *I, Instruction *InsertPt = 0) const; + bool makeLoopInvariant(Instruction *I, bool &Changed, + Instruction *InsertPt = 0) const; /// getCanonicalInductionVariable - Check to see if the loop has a canonical /// induction variable: an integer recurrence that starts at 0 and increments diff --git a/lib/Analysis/LoopInfo.cpp b/lib/Analysis/LoopInfo.cpp index fb8027c..63de1aa 100644 --- a/lib/Analysis/LoopInfo.cpp +++ b/lib/Analysis/LoopInfo.cpp @@ -58,9 +58,10 @@ bool Loop::isLoopInvariant(Instruction *I) const { /// If InsertPt is specified, it is the point to hoist instructions to. /// If null, the terminator of the loop preheader is used. /// -bool Loop::makeLoopInvariant(Value *V, Instruction *InsertPt) const { +bool Loop::makeLoopInvariant(Value *V, bool &Changed, + Instruction *InsertPt) const { if (Instruction *I = dyn_cast<Instruction>(V)) - return makeLoopInvariant(I); + return makeLoopInvariant(I, Changed, InsertPt); return true; // All non-instructions are loop-invariant. } @@ -73,7 +74,8 @@ bool Loop::makeLoopInvariant(Value *V, Instruction *InsertPt) const { /// If InsertPt is specified, it is the point to hoist instructions to. /// If null, the terminator of the loop preheader is used. /// -bool Loop::makeLoopInvariant(Instruction *I, Instruction *InsertPt) const { +bool Loop::makeLoopInvariant(Instruction *I, bool &Changed, + Instruction *InsertPt) const { // Test if the value is already loop-invariant. if (isLoopInvariant(I)) return true; @@ -96,10 +98,11 @@ bool Loop::makeLoopInvariant(Instruction *I, Instruction *InsertPt) const { } // Don't hoist instructions with loop-variant operands. for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) - if (!makeLoopInvariant(I->getOperand(i), InsertPt)) + if (!makeLoopInvariant(I->getOperand(i), Changed, InsertPt)) return false; // Hoist. I->moveBefore(InsertPt); + Changed = true; return true; } diff --git a/lib/Transforms/Scalar/LoopDeletion.cpp b/lib/Transforms/Scalar/LoopDeletion.cpp index 38d0b39..525d03f 100644 --- a/lib/Transforms/Scalar/LoopDeletion.cpp +++ b/lib/Transforms/Scalar/LoopDeletion.cpp @@ -38,9 +38,9 @@ namespace { bool SingleDominatingExit(Loop* L, SmallVector<BasicBlock*, 4>& exitingBlocks); bool IsLoopDead(Loop* L, SmallVector<BasicBlock*, 4>& exitingBlocks, - SmallVector<BasicBlock*, 4>& exitBlocks); - bool IsLoopInvariantInst(Instruction *I, Loop* L); - + SmallVector<BasicBlock*, 4>& exitBlocks, + bool &Changed, BasicBlock *Preheader); + virtual void getAnalysisUsage(AnalysisUsage& AU) const { AU.addRequired<ScalarEvolution>(); AU.addRequired<DominatorTree>(); @@ -84,32 +84,13 @@ bool LoopDeletion::SingleDominatingExit(Loop* L, return DT.dominates(exitingBlocks[0], latch); } -/// IsLoopInvariantInst - Checks if an instruction is invariant with respect to -/// a loop, which is defined as being true if all of its operands are defined -/// outside of the loop. These instructions can be hoisted out of the loop -/// if their results are needed. This could be made more aggressive by -/// recursively checking the operands for invariance, but it's not clear that -/// it's worth it. -bool LoopDeletion::IsLoopInvariantInst(Instruction *I, Loop* L) { - // PHI nodes are not loop invariant if defined in the loop. - if (isa<PHINode>(I) && L->contains(I->getParent())) - return false; - - // The instruction is loop invariant if all of its operands are loop-invariant - for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) - if (!L->isLoopInvariant(I->getOperand(i))) - return false; - - // If we got this far, the instruction is loop invariant! - return true; -} - /// IsLoopDead - Determined if a loop is dead. This assumes that we've already /// checked for unique exit and exiting blocks, and that the code is in LCSSA /// form. bool LoopDeletion::IsLoopDead(Loop* L, SmallVector<BasicBlock*, 4>& exitingBlocks, - SmallVector<BasicBlock*, 4>& exitBlocks) { + SmallVector<BasicBlock*, 4>& exitBlocks, + bool &Changed, BasicBlock *Preheader) { BasicBlock* exitingBlock = exitingBlocks[0]; BasicBlock* exitBlock = exitBlocks[0]; @@ -122,7 +103,7 @@ bool LoopDeletion::IsLoopDead(Loop* L, while (PHINode* P = dyn_cast<PHINode>(BI)) { Value* incoming = P->getIncomingValueForBlock(exitingBlock); if (Instruction* I = dyn_cast<Instruction>(incoming)) - if (!IsLoopInvariantInst(I, L)) + if (!L->makeLoopInvariant(I, Changed, Preheader->getTerminator())) return false; BI++; @@ -181,15 +162,16 @@ bool LoopDeletion::runOnLoop(Loop* L, LPPassManager& LPM) { return false; // Finally, we have to check that the loop really is dead. - if (!IsLoopDead(L, exitingBlocks, exitBlocks)) - return false; + bool Changed = false; + if (!IsLoopDead(L, exitingBlocks, exitBlocks, Changed, preheader)) + return Changed; // Don't remove loops for which we can't solve the trip count. // They could be infinite, in which case we'd be changing program behavior. ScalarEvolution& SE = getAnalysis<ScalarEvolution>(); const SCEV *S = SE.getBackedgeTakenCount(L); if (isa<SCEVCouldNotCompute>(S)) - return false; + return Changed; // Now that we know the removal is safe, remove the loop by changing the // branch from the preheader to go to the single exit block. @@ -205,17 +187,6 @@ bool LoopDeletion::runOnLoop(Loop* L, LPPassManager& LPM) { // to determine what it needs to clean up. SE.forgetLoopBackedgeTakenCount(L); - // Move simple loop-invariant expressions out of the loop, since they - // might be needed by the exit phis. - for (Loop::block_iterator LI = L->block_begin(), LE = L->block_end(); - LI != LE; ++LI) - for (BasicBlock::iterator BI = (*LI)->begin(), BE = (*LI)->end(); - BI != BE; ) { - Instruction* I = BI++; - if (!I->use_empty() && IsLoopInvariantInst(I, L)) - I->moveBefore(preheader->getTerminator()); - } - // Connect the preheader directly to the exit block. TerminatorInst* TI = preheader->getTerminator(); TI->replaceUsesOfWith(L->getHeader(), exitBlock); @@ -273,8 +244,9 @@ bool LoopDeletion::runOnLoop(Loop* L, LPPassManager& LPM) { // The last step is to inform the loop pass manager that we've // eliminated this loop. LPM.deleteLoopFromQueue(L); + Changed = true; NumDeleted++; - return true; + return Changed; } diff --git a/lib/Transforms/Scalar/LoopUnswitch.cpp b/lib/Transforms/Scalar/LoopUnswitch.cpp index f5061b5..daf1841 100644 --- a/lib/Transforms/Scalar/LoopUnswitch.cpp +++ b/lib/Transforms/Scalar/LoopUnswitch.cpp @@ -168,13 +168,10 @@ static Value *FindLIVLoopCondition(Value *Cond, Loop *L, bool &Changed) { if (isa<Constant>(Cond)) return 0; // TODO: Handle: br (VARIANT|INVARIANT). - if (L->isLoopInvariant(Cond)) return Cond; // Hoist simple values out. - if (L->makeLoopInvariant(Cond)) { - Changed = true; + if (L->makeLoopInvariant(Cond, Changed)) return Cond; - } if (BinaryOperator *BO = dyn_cast<BinaryOperator>(Cond)) if (BO->getOpcode() == Instruction::And || diff --git a/lib/Transforms/Utils/LoopSimplify.cpp b/lib/Transforms/Utils/LoopSimplify.cpp index cfdfcb0..81fa4f9 100644 --- a/lib/Transforms/Utils/LoopSimplify.cpp +++ b/lib/Transforms/Utils/LoopSimplify.cpp @@ -93,7 +93,7 @@ namespace { BasicBlock *RewriteLoopExitBlock(Loop *L, BasicBlock *Exit); BasicBlock *InsertPreheaderForLoop(Loop *L); Loop *SeparateNestedLoop(Loop *L); - void InsertUniqueBackedgeBlock(Loop *L); + void InsertUniqueBackedgeBlock(Loop *L, BasicBlock *Preheader); void PlaceSplitBlockCarefully(BasicBlock *NewBB, SmallVectorImpl<BasicBlock*> &SplitPreds, Loop *L); @@ -244,7 +244,7 @@ ReprocessLoop: // If we either couldn't, or didn't want to, identify nesting of the loops, // insert a new block that all backedges target, then make it jump to the // loop header. - InsertUniqueBackedgeBlock(L); + InsertUniqueBackedgeBlock(L, Preheader); NumInserted++; Changed = true; } @@ -288,9 +288,8 @@ ReprocessLoop: Instruction *Inst = I++; if (Inst == CI) continue; - if (!L->makeLoopInvariant(Inst, Preheader->getTerminator())) { + if (!L->makeLoopInvariant(Inst, Changed, Preheader->getTerminator())) { AllInvariant = false; - Changed = true; break; } } @@ -574,11 +573,10 @@ Loop *LoopSimplify::SeparateNestedLoop(Loop *L) { /// backedges to target a new basic block and have that block branch to the loop /// header. This ensures that loops have exactly one backedge. /// -void LoopSimplify::InsertUniqueBackedgeBlock(Loop *L) { +void LoopSimplify::InsertUniqueBackedgeBlock(Loop *L, BasicBlock *Preheader) { assert(L->getNumBackEdges() > 1 && "Must have > 1 backedge!"); // Get information about the loop - BasicBlock *Preheader = L->getLoopPreheader(); BasicBlock *Header = L->getHeader(); Function *F = Header->getParent(); |