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

Jeff Cohen jeffc at jolt-lang.org
Sat Mar 5 14:40:45 PST 2005



Changes in directory llvm/lib/Transforms/Scalar:

LoopStrengthReduce.cpp updated: 1.6 -> 1.7
---
Log message:

Reuse induction variables created for strength-reduced GEPs by other similar GEPs.


---
Diffs of the changes:  (+61 -32)

 LoopStrengthReduce.cpp |   93 ++++++++++++++++++++++++++++++++-----------------
 1 files changed, 61 insertions(+), 32 deletions(-)


Index: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
diff -u llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.6 llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.7
--- llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.6	Thu Mar  3 22:04:26 2005
+++ llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp	Sat Mar  5 16:40:34 2005
@@ -35,6 +35,22 @@
 namespace {
   Statistic<> NumReduced ("loop-reduce", "Number of GEPs strength reduced");
 
+  class GEPCache
+  {
+  public:
+    GEPCache() : CachedPHINode(0), Map() {}
+
+    GEPCache* operator[](Value *v) {
+      std::map<Value *, GEPCache>::iterator I = Map.find(v);
+      if (I == Map.end())
+        I = Map.insert(std::pair<Value *, GEPCache>(v, GEPCache())).first;
+      return &(I->second);
+    }
+
+    PHINode *CachedPHINode;
+    std::map<Value *, GEPCache> Map;
+  };
+
   class LoopStrengthReduce : public FunctionPass {
     LoopInfo *LI;
     DominatorSet *DS;
@@ -65,6 +81,7 @@
   private:
     void runOnLoop(Loop *L);
     void strengthReduceGEP(GetElementPtrInst *GEPI, Loop *L,
+                           GEPCache* GEPCache,
                            Instruction *InsertBefore,
                            std::set<Instruction*> &DeadInsts);
     void DeleteTriviallyDeadInstructions(std::set<Instruction*> &Insts);
@@ -96,6 +113,7 @@
 }
 
 void LoopStrengthReduce::strengthReduceGEP(GetElementPtrInst *GEPI, Loop *L,
+                                           GEPCache *Cache,
                                            Instruction *InsertBefore,
                                            std::set<Instruction*> &DeadInsts) {
   // We will strength reduce the GEP by splitting it into two parts.  The first
@@ -117,6 +135,7 @@
   BasicBlock *Header = L->getHeader();
   BasicBlock *Preheader = L->getLoopPreheader();
   bool AllConstantOperands = true;
+  Cache = (*Cache)[GEPI->getOperand(0)];
 
   for (unsigned op = 1, e = GEPI->getNumOperands(); op != e; ++op) {
     Value *operand = GEPI->getOperand(op);
@@ -145,6 +164,7 @@
       AllConstantOperands = false;
     } else
       return;
+    Cache = (*Cache)[operand];
   }
   assert(indvar > 0 && "Indvar used by GEP not found in operand list");
   
@@ -157,7 +177,7 @@
     if (!DS->dominates(GepPtrOp, Preheader->getTerminator()))
       return;
 
-  // Don't reduced multiplies that the target can handle via addressing modes.
+  // Don't reduce multiplies that the target can handle via addressing modes.
   uint64_t sz = getAnalysis<TargetData>().getTypeSize(ty);
   for (unsigned i = 1; i <= MaxTargetAMSize; i *= 2)
     if (i == sz)
@@ -169,38 +189,46 @@
   // If there is only one operand after the initial non-constant one, we know
   // that it was the induction variable, and has been replaced by a constant
   // null value.  In this case, replace the GEP with a use of pointer directly.
-  Value *PreGEP;
-  if (AllConstantOperands && isa<Constant>(GEPI->getOperand(0))) {
-    Constant *C = dyn_cast<Constant>(GEPI->getOperand(0));
-    PreGEP = ConstantExpr::getGetElementPtr(C, pre_op_vector);
-  } else if (pre_op_vector.size() == 1) {
-    PreGEP = GEPI->getOperand(0);
+  PHINode *NewPHI;
+  if (1) {
+    Value *PreGEP;
+    if (AllConstantOperands && isa<Constant>(GEPI->getOperand(0))) {
+      Constant *C = dyn_cast<Constant>(GEPI->getOperand(0));
+      PreGEP = ConstantExpr::getGetElementPtr(C, pre_op_vector);
+    } else if (pre_op_vector.size() == 1) {
+      PreGEP = GEPI->getOperand(0);
+    } else {
+      PreGEP = new GetElementPtrInst(GEPI->getOperand(0),
+                                    pre_op_vector, GEPI->getName()+".pre", 
+                                    Preheader->getTerminator());
+    }
+
+    // The next step of the strength reduction is to create a PHI that will choose
+    // between the initial GEP we created and inserted into the preheader, and 
+    // the incremented GEP that we will create below and insert into the loop body
+    NewPHI = new PHINode(PreGEP->getType(), 
+                                  GEPI->getName()+".str", InsertBefore);
+    NewPHI->addIncoming(PreGEP, Preheader);
+    
+    // Now, create the GEP instruction to increment by one the value selected by
+    // the PHI instruction we just created above, and add it as the second
+    // incoming Value/BasicBlock pair to the PHINode.  It is inserted before the
+    // increment of the canonical induction variable.
+    Instruction *IncrInst = 
+      const_cast<Instruction*>(L->getCanonicalInductionVariableIncrement());
+    GetElementPtrInst *StrGEP = new GetElementPtrInst(NewPHI, inc_op_vector,
+                                                      GEPI->getName()+".inc",
+                                                      IncrInst);
+    pred_iterator PI = pred_begin(Header);
+    if (*PI == Preheader)
+      ++PI;
+    NewPHI->addIncoming(StrGEP, *PI);
+    Cache->CachedPHINode = NewPHI;
   } else {
-    PreGEP = new GetElementPtrInst(GEPI->getOperand(0),
-                                   pre_op_vector, GEPI->getName()+".pre", 
-                                   Preheader->getTerminator());
+    // Reuse previously created pointer, as it is identical to the one we were
+    // about to create.
+    NewPHI = Cache->CachedPHINode;
   }
-
-  // The next step of the strength reduction is to create a PHI that will choose
-  // between the initial GEP we created and inserted into the preheader, and 
-  // the incremented GEP that we will create below and insert into the loop body
-  PHINode *NewPHI = new PHINode(PreGEP->getType(), 
-                                GEPI->getName()+".str", InsertBefore);
-  NewPHI->addIncoming(PreGEP, Preheader);
-  
-  // Now, create the GEP instruction to increment by one the value selected by
-  // the PHI instruction we just created above, and add it as the second
-  // incoming Value/BasicBlock pair to the PHINode.  It is inserted before the
-  // increment of the canonical induction variable.
-  Instruction *IncrInst = 
-    const_cast<Instruction*>(L->getCanonicalInductionVariableIncrement());
-  GetElementPtrInst *StrGEP = new GetElementPtrInst(NewPHI, inc_op_vector,
-                                                    GEPI->getName()+".inc",
-                                                    IncrInst);
-  pred_iterator PI = pred_begin(Header);
-  if (*PI == Preheader)
-    ++PI;
-  NewPHI->addIncoming(StrGEP, *PI);
   
   if (GEPI->getNumOperands() - 1 == indvar) {
     // If there were no operands following the induction variable, replace all
@@ -246,10 +274,11 @@
   // strength reduced pointers we'll be creating after the canonical induction
   // variable's PHI.
   std::set<Instruction*> DeadInsts;
+  GEPCache Cache;
   for (Value::use_iterator UI = PN->use_begin(), UE = PN->use_end();
        UI != UE; ++UI)
     if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(*UI))
-      strengthReduceGEP(GEPI, L, PN->getNext(), DeadInsts);
+      strengthReduceGEP(GEPI, L, &Cache, PN->getNext(), DeadInsts);
 
   // Clean up after ourselves
   if (!DeadInsts.empty()) {






More information about the llvm-commits mailing list