diff options
author | Dan Gohman <gohman@apple.com> | 2009-05-08 20:26:55 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2009-05-08 20:26:55 +0000 |
commit | 26466c0eb3451c5c953b3cca8940359152c4f8e3 (patch) | |
tree | 4d4994cf7d0a4eb34645602e441233e541f00d9e /lib/Analysis/ScalarEvolution.cpp | |
parent | 185cf0395c9d7d72ea12ce4d316a6cb2eab9115e (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.cpp | 73 |
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)); |