aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/ScalarEvolution.cpp
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2009-05-08 20:26:55 +0000
committerDan Gohman <gohman@apple.com>2009-05-08 20:26:55 +0000
commit26466c0eb3451c5c953b3cca8940359152c4f8e3 (patch)
tree4d4994cf7d0a4eb34645602e441233e541f00d9e /lib/Analysis/ScalarEvolution.cpp
parent185cf0395c9d7d72ea12ce4d316a6cb2eab9115e (diff)
Factor out the code for creating SCEVs for GEPs into a
separate function. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@71252 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/ScalarEvolution.cpp')
-rw-r--r--lib/Analysis/ScalarEvolution.cpp73
1 files changed, 40 insertions, 33 deletions
diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp
index 89d14ca40a..81bf7e8dd9 100644
--- a/lib/Analysis/ScalarEvolution.cpp
+++ b/lib/Analysis/ScalarEvolution.cpp
@@ -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));