Change the canonical induction variable that we insert.
authorChris Lattner <sabre@nondot.org>
Thu, 15 Apr 2004 15:21:43 +0000 (15:21 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 15 Apr 2004 15:21:43 +0000 (15:21 +0000)
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

lib/Transforms/Scalar/IndVarSimplify.cpp

index 0622b170c8c6643d13468853345f6b2a91db1efe..728e20e0cff978a3d0feaf18b031c6d44068850f 100644 (file)
 
 #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