From 26466c0eb3451c5c953b3cca8940359152c4f8e3 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 8 May 2009 20:26:55 +0000 Subject: [PATCH] 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 --- include/llvm/Analysis/ScalarEvolution.h | 4 ++ lib/Analysis/ScalarEvolution.cpp | 73 ++++++++++++++----------- 2 files changed, 44 insertions(+), 33 deletions(-) diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h index fb22fd47b3a..96490229f48 100644 --- a/include/llvm/Analysis/ScalarEvolution.h +++ b/include/llvm/Analysis/ScalarEvolution.h @@ -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 diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp index 89d14ca40a9..81bf7e8dd9e 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(*GTI++)) { + // For a struct, add the member offset. + const StructLayout &SL = *TD->getStructLayout(STy); + unsigned FieldNo = cast(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(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(*GTI++)) { - // For a struct, add the member offset. - const StructLayout &SL = *TD->getStructLayout(STy); - unsigned FieldNo = cast(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(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(U)); case Instruction::PHI: return createNodeForPHI(cast(U));