[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