summaryrefslogtreecommitdiff
path: root/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
authorNuno Lopes <nunoplopes@sapo.pt>2012-12-31 20:48:35 +0000
committerNuno Lopes <nunoplopes@sapo.pt>2012-12-31 20:48:35 +0000
commit5cec34754d540faac87fc0173fce42005c76b7d9 (patch)
treed887758f932b50ad3a121d59489144f04b2cc803 /lib/Analysis/ValueTracking.cpp
parent0a9ff4cab3a3fc1179c37855717a54ae44a5312e (diff)
downloadllvm-5cec34754d540faac87fc0173fce42005c76b7d9.tar.gz
llvm-5cec34754d540faac87fc0173fce42005c76b7d9.tar.bz2
llvm-5cec34754d540faac87fc0173fce42005c76b7d9.tar.xz
reimplement GetPointerBaseWithConstantOffset().
The new code is an improved copy of the code I deleted from Analysis/Loads.cpp. One less compute-constant-gep-offset implementation. yay :) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@171326 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/ValueTracking.cpp')
-rw-r--r--lib/Analysis/ValueTracking.cpp52
1 files changed, 21 insertions, 31 deletions
diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp
index c6e169d337..0fe2059035 100644
--- a/lib/Analysis/ValueTracking.cpp
+++ b/lib/Analysis/ValueTracking.cpp
@@ -1672,40 +1672,30 @@ Value *llvm::FindInsertedValue(Value *V, ArrayRef<unsigned> idx_range,
/// base and offset to the caller.
Value *llvm::GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset,
const DataLayout &TD) {
- Operator *PtrOp = dyn_cast<Operator>(Ptr);
- if (PtrOp == 0 || Ptr->getType()->isVectorTy())
- return Ptr;
-
- // Just look through bitcasts.
- if (PtrOp->getOpcode() == Instruction::BitCast)
- return GetPointerBaseWithConstantOffset(PtrOp->getOperand(0), Offset, TD);
-
- // If this is a GEP with constant indices, we can look through it.
- GEPOperator *GEP = dyn_cast<GEPOperator>(PtrOp);
- if (GEP == 0 || !GEP->hasAllConstantIndices()) return Ptr;
-
- gep_type_iterator GTI = gep_type_begin(GEP);
- for (User::op_iterator I = GEP->idx_begin(), E = GEP->idx_end(); I != E;
- ++I, ++GTI) {
- ConstantInt *OpC = cast<ConstantInt>(*I);
- if (OpC->isZero()) continue;
-
- // Handle a struct and array indices which add their offset to the pointer.
- if (StructType *STy = dyn_cast<StructType>(*GTI)) {
- Offset += TD.getStructLayout(STy)->getElementOffset(OpC->getZExtValue());
+ unsigned BitWidth = TD.getPointerSizeInBits();
+ APInt ByteOffset(BitWidth, 0);
+ while (1) {
+ if (Ptr->getType()->isVectorTy())
+ break;
+
+ if (GEPOperator *GEP = dyn_cast<GEPOperator>(Ptr)) {
+ APInt GEPOffset(BitWidth, 0);
+ if (!GEP->accumulateConstantOffset(TD, GEPOffset))
+ break;
+ ByteOffset += GEPOffset;
+ Ptr = GEP->getPointerOperand();
+ } else if (Operator::getOpcode(Ptr) == Instruction::BitCast) {
+ Ptr = cast<Operator>(Ptr)->getOperand(0);
+ } else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(Ptr)) {
+ if (GA->mayBeOverridden())
+ break;
+ Ptr = GA->getAliasee();
} else {
- uint64_t Size = TD.getTypeAllocSize(GTI.getIndexedType());
- Offset += OpC->getSExtValue()*Size;
+ break;
}
}
-
- // Re-sign extend from the pointer size if needed to get overflow edge cases
- // right.
- unsigned PtrSize = TD.getPointerSizeInBits();
- if (PtrSize < 64)
- Offset = SignExtend64(Offset, PtrSize);
-
- return GetPointerBaseWithConstantOffset(GEP->getPointerOperand(), Offset, TD);
+ Offset = ByteOffset.getSExtValue();
+ return Ptr;
}