[llvm-commits] [llvm] r71252 - in /llvm/trunk: include/llvm/Analysis/ScalarEvolution.h lib/Analysis/ScalarEvolution.cpp

Dan Gohman gohman at apple.com
Fri May 8 13:26:56 PDT 2009


Author: djg
Date: Fri May  8 15:26:55 2009
New Revision: 71252

URL: http://llvm.org/viewvc/llvm-project?rev=71252&view=rev
Log:
Factor out the code for creating SCEVs for GEPs into a
separate function.

Modified:
    llvm/trunk/include/llvm/Analysis/ScalarEvolution.h
    llvm/trunk/lib/Analysis/ScalarEvolution.cpp

Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolution.h?rev=71252&r1=71251&r2=71252&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Analysis/ScalarEvolution.h (original)
+++ llvm/trunk/include/llvm/Analysis/ScalarEvolution.h Fri May  8 15:26:55 2009
@@ -279,6 +279,10 @@
     /// SCEVs.
     SCEVHandle createNodeForPHI(PHINode *PN);
 
+    /// createNodeForGEP - Provide the special handling we need to analyze GEP
+    /// SCEVs.
+    SCEVHandle createNodeForGEP(GetElementPtrInst *GEP);
+
     /// ReplaceSymbolicValueWithConcrete - This looks up the computed SCEV value
     /// for the specified instruction and replaces any references to the
     /// symbolic value SymName with the specified value.  This is used during

Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=71252&r1=71251&r2=71252&view=diff

==============================================================================
--- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)
+++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Fri May  8 15:26:55 2009
@@ -1863,6 +1863,44 @@
   return getUnknown(PN);
 }
 
+/// createNodeForGEP - Expand GEP instructions into add and multiply
+/// operations. This allows them to be analyzed by regular SCEV code.
+///
+SCEVHandle ScalarEvolution::createNodeForGEP(GetElementPtrInst *GEP) {
+
+  const Type *IntPtrTy = TD->getIntPtrType();
+  Value *Base = U->getOperand(0);
+  SCEVHandle TotalOffset = getIntegerSCEV(0, IntPtrTy);
+  gep_type_iterator GTI = gep_type_begin(U);
+  for (GetElementPtrInst::op_iterator I = next(U->op_begin()),
+                                      E = U->op_end();
+       I != E; ++I) {
+    Value *Index = *I;
+    // Compute the (potentially symbolic) offset in bytes for this index.
+    if (const StructType *STy = dyn_cast<StructType>(*GTI++)) {
+      // For a struct, add the member offset.
+      const StructLayout &SL = *TD->getStructLayout(STy);
+      unsigned FieldNo = cast<ConstantInt>(Index)->getZExtValue();
+      uint64_t Offset = SL.getElementOffset(FieldNo);
+      TotalOffset = getAddExpr(TotalOffset,
+                                  getIntegerSCEV(Offset, IntPtrTy));
+    } else {
+      // For an array, add the element offset, explicitly scaled.
+      SCEVHandle LocalOffset = getSCEV(Index);
+      if (!isa<PointerType>(LocalOffset->getType()))
+        // Getelementptr indicies are signed.
+        LocalOffset = getTruncateOrSignExtend(LocalOffset,
+                                              IntPtrTy);
+      LocalOffset =
+        getMulExpr(LocalOffset,
+                   getIntegerSCEV(TD->getTypePaddedSize(*GTI),
+                                  IntPtrTy));
+      TotalOffset = getAddExpr(TotalOffset, LocalOffset);
+    }
+  }
+  return getAddExpr(getSCEV(Base), TotalOffset);
+}
+
 /// GetMinTrailingZeros - Determine the minimum number of zero bits that S is
 /// guaranteed to end in (at every loop iteration).  It is, at the same time,
 /// the minimum number of times S is divisible by 2.  For example, given {4,+,8}
@@ -2073,40 +2111,9 @@
     return getTruncateOrZeroExtend(getSCEV(U->getOperand(0)),
                                    U->getType());
 
-  case Instruction::GetElementPtr: {
+  case Instruction::GetElementPtr:
     if (!TD) break; // Without TD we can't analyze pointers.
-    const Type *IntPtrTy = TD->getIntPtrType();
-    Value *Base = U->getOperand(0);
-    SCEVHandle TotalOffset = getIntegerSCEV(0, IntPtrTy);
-    gep_type_iterator GTI = gep_type_begin(U);
-    for (GetElementPtrInst::op_iterator I = next(U->op_begin()),
-                                        E = U->op_end();
-         I != E; ++I) {
-      Value *Index = *I;
-      // Compute the (potentially symbolic) offset in bytes for this index.
-      if (const StructType *STy = dyn_cast<StructType>(*GTI++)) {
-        // For a struct, add the member offset.
-        const StructLayout &SL = *TD->getStructLayout(STy);
-        unsigned FieldNo = cast<ConstantInt>(Index)->getZExtValue();
-        uint64_t Offset = SL.getElementOffset(FieldNo);
-        TotalOffset = getAddExpr(TotalOffset,
-                                    getIntegerSCEV(Offset, IntPtrTy));
-      } else {
-        // For an array, add the element offset, explicitly scaled.
-        SCEVHandle LocalOffset = getSCEV(Index);
-        if (!isa<PointerType>(LocalOffset->getType()))
-          // Getelementptr indicies are signed.
-          LocalOffset = getTruncateOrSignExtend(LocalOffset,
-                                                IntPtrTy);
-        LocalOffset =
-          getMulExpr(LocalOffset,
-                     getIntegerSCEV(TD->getTypePaddedSize(*GTI),
-                                    IntPtrTy));
-        TotalOffset = getAddExpr(TotalOffset, LocalOffset);
-      }
-    }
-    return getAddExpr(getSCEV(Base), TotalOffset);
-  }
+    return createNodeForGEP(cast<GetElementPtrInst>(U));
 
   case Instruction::PHI:
     return createNodeForPHI(cast<PHINode>(U));





More information about the llvm-commits mailing list