diff options
author | Chris Lattner <sabre@nondot.org> | 2004-04-15 15:21:43 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2004-04-15 15:21:43 +0000 |
commit | 59fdaeeae8f183e18bb6ad5c382ca23e28e6aaf6 (patch) | |
tree | 6e96696fbfe286878d151f4a49b0e63c69d092d6 /lib/Transforms/Scalar/IndVarSimplify.cpp | |
parent | 92020faa2ca025996c2232c682c0e484f98cc56c (diff) |
Change the canonical induction variable that we insert.
Instead of producing code like this:
Loop:
X = phi 0, X2
...
X2 = X + 1
if (X != N-1) goto Loop
We now generate code that looks like this:
Loop:
X = phi 0, X2
...
X2 = X + 1
if (X2 != N) goto Loop
This has two big advantages:
1. The trip count of the loop is now explicit in the code, allowing
the direct implementation of Loop::getTripCount()
2. This reduces register pressure in the loop, and allows X and X2 to be
put into the same register.
As a consequence of the second point, the code we generate for loops went
from:
.LBB2: # no_exit.1
...
mov %EDI, %ESI
inc %EDI
cmp %ESI, 2
mov %ESI, %EDI
jne .LBB2 # PC rel: no_exit.1
To:
.LBB2: # no_exit.1
...
inc %ESI
cmp %ESI, 3
jne .LBB2 # PC rel: no_exit.1
... which has two fewer moves, and uses one less register.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12961 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/IndVarSimplify.cpp')
-rw-r--r-- | lib/Transforms/Scalar/IndVarSimplify.cpp | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/lib/Transforms/Scalar/IndVarSimplify.cpp b/lib/Transforms/Scalar/IndVarSimplify.cpp index 0622b170c8..728e20e0cf 100644 --- a/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -39,10 +39,10 @@ #include "llvm/Transforms/Scalar.h" #include "llvm/BasicBlock.h" -#include "llvm/Constant.h" +#include "llvm/Constants.h" #include "llvm/Instructions.h" #include "llvm/Type.h" -#include "llvm/Analysis/ScalarEvolution.h" +#include "llvm/Analysis/ScalarEvolutionExpressions.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Support/CFG.h" #include "llvm/Transforms/Utils/Local.h" @@ -85,7 +85,7 @@ namespace { void EliminatePointerRecurrence(PHINode *PN, BasicBlock *Preheader, std::set<Instruction*> &DeadInsts); void LinearFunctionTestReplace(Loop *L, SCEV *IterationCount, - Value *IndVar, ScalarEvolutionRewriter &RW); + ScalarEvolutionRewriter &RW); void RewriteLoopExitValues(Loop *L); void DeleteTriviallyDeadInstructions(std::set<Instruction*> &Insts); @@ -177,12 +177,11 @@ void IndVarSimplify::EliminatePointerRecurrence(PHINode *PN, } /// LinearFunctionTestReplace - This method rewrites the exit condition of the -/// loop to be a canonical != comparison against the loop induction variable. -/// This pass is able to rewrite the exit tests of any loop where the SCEV -/// analysis can determine the trip count of the loop, which is actually a much -/// broader range than just linear tests. +/// loop to be a canonical != comparison against the incremented loop induction +/// variable. This pass is able to rewrite the exit tests of any loop where the +/// SCEV analysis can determine a loop-invariant trip count of the loop, which +/// is actually a much broader range than just linear tests. void IndVarSimplify::LinearFunctionTestReplace(Loop *L, SCEV *IterationCount, - Value *IndVar, ScalarEvolutionRewriter &RW) { // Find the exit block for the loop. We can currently only handle loops with // a single exit. @@ -210,9 +209,17 @@ void IndVarSimplify::LinearFunctionTestReplace(Loop *L, SCEV *IterationCount, if (Instruction *Cond = dyn_cast<Instruction>(BI->getCondition())) InstructionsToDelete.insert(Cond); + // The IterationCount expression contains the number of times that the + // backedge actually branches to the loop header. This is one less than the + // number of times the loop executes, so add one to it. + Constant *OneC = ConstantInt::get(IterationCount->getType(), 1); + SCEVHandle TripCount=SCEVAddExpr::get(IterationCount, SCEVUnknown::get(OneC)); + + Value *IndVar = L->getCanonicalInductionVariableIncrement(); + // Expand the code for the iteration count into the preheader of the loop. BasicBlock *Preheader = L->getLoopPreheader(); - Value *ExitCnt = RW.ExpandCodeFor(IterationCount, Preheader->getTerminator(), + Value *ExitCnt = RW.ExpandCodeFor(TripCount, Preheader->getTerminator(), IndVar->getType()); // Insert a new setne or seteq instruction before the branch. @@ -368,7 +375,7 @@ void IndVarSimplify::runOnLoop(Loop *L) { Changed = true; if (!isa<SCEVCouldNotCompute>(IterationCount)) - LinearFunctionTestReplace(L, IterationCount, IndVar, Rewriter); + LinearFunctionTestReplace(L, IterationCount, Rewriter); #if 0 // If there were induction variables of other sizes, cast the primary |