[llvm-commits] CVS: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp

Chris Lattner lattner at cs.uiuc.edu
Wed Apr 21 17:22:02 PDT 2004


Changes in directory llvm/lib/Transforms/Scalar:

IndVarSimplify.cpp updated: 1.59 -> 1.60

---
Log message:

Implement a fixme.  The helps loops that have induction variables of different
types in them.  Instead of creating an induction variable for all types, it
creates a single induction variable and casts to the other sizes.  This generates
this code:

no_exit:                ; preds = %entry, %no_exit
        %indvar = phi uint [ %indvar.next, %no_exit ], [ 0, %entry ]            ; <uint> [#uses=4]
***     %j.0.0 = cast uint %indvar to short             ; <short> [#uses=1]
        %indvar = cast uint %indvar to int              ; <int> [#uses=1]
        %tmp.7 = getelementptr short* %P, uint %indvar          ; <short*> [#uses=1]
        store short %j.0.0, short* %tmp.7
        %inc.0 = add int %indvar, 1             ; <int> [#uses=2]
        %tmp.2 = setlt int %inc.0, %N           ; <bool> [#uses=1]
        %indvar.next = add uint %indvar, 1              ; <uint> [#uses=1]
        br bool %tmp.2, label %no_exit, label %loopexit

instead of:

no_exit:                ; preds = %entry, %no_exit
        %indvar = phi ushort [ %indvar.next, %no_exit ], [ 0, %entry ]          ; <ushort> [#uses=2]
***     %indvar = phi uint [ %indvar.next, %no_exit ], [ 0, %entry ]            ; <uint> [#uses=3]
        %indvar = cast uint %indvar to int              ; <int> [#uses=1]
        %indvar = cast ushort %indvar to short          ; <short> [#uses=1]
        %tmp.7 = getelementptr short* %P, uint %indvar          ; <short*> [#uses=1]
        store short %indvar, short* %tmp.7
        %inc.0 = add int %indvar, 1             ; <int> [#uses=2]
        %tmp.2 = setlt int %inc.0, %N           ; <bool> [#uses=1]
        %indvar.next = add uint %indvar, 1
***     %indvar.next = add ushort %indvar, 1
        br bool %tmp.2, label %no_exit, label %loopexit

This is an improvement in register pressure, but probably doesn't happen that 
often.

The more important fix will be to get rid of the redundant add.



---
Diffs of the changes:  (+20 -17)

Index: llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
diff -u llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.59 llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.60
--- llvm/lib/Transforms/Scalar/IndVarSimplify.cpp:1.59	Sun Apr 18 17:14:10 2004
+++ llvm/lib/Transforms/Scalar/IndVarSimplify.cpp	Wed Apr 21 17:22:01 2004
@@ -390,10 +390,8 @@
   // Compute the type of the largest recurrence expression.
   //
   const Type *LargestType = IndVars[0].first->getType();
-  bool DifferingSizes = false;
   for (unsigned i = 1, e = IndVars.size(); i != e; ++i) {
     const Type *Ty = IndVars[i].first->getType();
-    DifferingSizes |= Ty->getPrimitiveSize() != LargestType->getPrimitiveSize();
     if (Ty->getPrimitiveSize() > LargestType->getPrimitiveSize())
       LargestType = Ty;
   }
@@ -411,30 +409,35 @@
   if (!isa<SCEVCouldNotCompute>(IterationCount))
     LinearFunctionTestReplace(L, IterationCount, Rewriter);
 
-#if 0
-  // If there were induction variables of other sizes, cast the primary
-  // induction variable to the right size for them, avoiding the need for the
-  // code evaluation methods to insert induction variables of different sizes.
-  // FIXME!
-  if (DifferingSizes) {
-    std::map<unsigned, Value*> InsertedSizes;
-    for (unsigned i = 0, e = IndVars.size(); i != e; ++i) {
-    }    
-  }
-#endif
-
   // Now that we have a canonical induction variable, we can rewrite any
   // recurrences in terms of the induction variable.  Start with the auxillary
   // induction variables, and recursively rewrite any of their uses.
   BasicBlock::iterator InsertPt = Header->begin();
   while (isa<PHINode>(InsertPt)) ++InsertPt;
 
+  // If there were induction variables of other sizes, cast the primary
+  // induction variable to the right size for them, avoiding the need for the
+  // code evaluation methods to insert induction variables of different sizes.
+  std::map<unsigned, Value*> InsertedSizes;
+  InsertedSizes[LargestType->getPrimitiveSize()] = IndVar;
   while (!IndVars.empty()) {
     PHINode *PN = IndVars.back().first;
-    Value *NewVal = Rewriter.ExpandCodeFor(IndVars.back().second, InsertPt,
-                                           PN->getType());
+
+    const Type *Ty = PN->getType()->getUnsignedVersion();
+    Value *&IV = InsertedSizes[Ty->getPrimitiveSize()];
+    if (IV == 0) {
+      // Insert a new cast instruction, which will hold this recurrence.
+      std::string Name = PN->getName();
+      PN->setName("");
+      IV = new CastInst(IndVar, Ty, Name, InsertPt);
+    }
+
+    Value *V = IV;
+    if (PN->getType() != Ty)
+      V = new CastInst(V, PN->getType(), V->getName(), InsertPt);
+
     // Replace the old PHI Node with the inserted computation.
-    PN->replaceAllUsesWith(NewVal);
+    PN->replaceAllUsesWith(V);
     DeadInsts.insert(PN);
     IndVars.pop_back();
     ++NumRemoved;





More information about the llvm-commits mailing list