Factor out the code for creating SCEVs for GEPs into a
authorDan Gohman <gohman@apple.com>
Fri, 8 May 2009 20:26:55 +0000 (20:26 +0000)
committerDan Gohman <gohman@apple.com>
Fri, 8 May 2009 20:26:55 +0000 (20:26 +0000)
separate function.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@71252 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Analysis/ScalarEvolution.h
lib/Analysis/ScalarEvolution.cpp

index fb22fd47b3a288f389c6734659dd3fb8d87ada9e..96490229f487390d09fa62544e7e0832c6576188 100644 (file)
@@ -279,6 +279,10 @@ namespace llvm {
     /// 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
index 89d14ca40a966f9f0b9ae6eeab4b5ec106d17cd0..81bf7e8dd9e56361fe4fd8a728376db384e89d9a 100644 (file)
@@ -1863,6 +1863,44 @@ SCEVHandle ScalarEvolution::createNodeForPHI(PHINode *PN) {
   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 @@ SCEVHandle ScalarEvolution::createSCEV(Value *V) {
     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));