diff options
Diffstat (limited to 'lib/VMCore/Value.cpp')
-rw-r--r-- | lib/VMCore/Value.cpp | 48 |
1 files changed, 42 insertions, 6 deletions
diff --git a/lib/VMCore/Value.cpp b/lib/VMCore/Value.cpp index 207c06d223..40b2d95e3d 100644 --- a/lib/VMCore/Value.cpp +++ b/lib/VMCore/Value.cpp @@ -317,20 +317,43 @@ void Value::replaceAllUsesWith(Value *New) { BB->replaceSuccessorsPhiUsesWith(cast<BasicBlock>(New)); } -Value *Value::stripPointerCasts() { - if (!getType()->isPointerTy()) - return this; +namespace { +// Various metrics for how much to strip off of pointers. +enum PointerStripKind { + PSK_ZeroIndices, + PSK_ConstantIndices, + PSK_InBounds, + PSK_All +}; + +template <PointerStripKind StripKind> +static Value *stripPointerCastsAndOffsets(Value *V) { + if (!V->getType()->isPointerTy()) + return V; // Even though we don't look through PHI nodes, we could be called on an // instruction in an unreachable block, which may be on a cycle. SmallPtrSet<Value *, 4> Visited; - Value *V = this; Visited.insert(V); do { if (GEPOperator *GEP = dyn_cast<GEPOperator>(V)) { - if (!GEP->hasAllZeroIndices()) - return V; + switch (StripKind) { + case PSK_ZeroIndices: + if (!GEP->hasAllZeroIndices()) + return V; + break; + case PSK_ConstantIndices: + if (!GEP->hasAllConstantIndices()) + return V; + break; + case PSK_InBounds: + if (!GEP->isInBounds()) + return V; + break; + case PSK_All: + break; + } V = GEP->getPointerOperand(); } else if (Operator::getOpcode(V) == Instruction::BitCast) { V = cast<Operator>(V)->getOperand(0); @@ -346,6 +369,19 @@ Value *Value::stripPointerCasts() { return V; } +} // namespace + +Value *Value::stripPointerCasts() { + return stripPointerCastsAndOffsets<PSK_ZeroIndices>(this); +} + +Value *Value::stripConstantOffsets() { + return stripPointerCastsAndOffsets<PSK_ConstantIndices>(this); +} + +Value *Value::stripInBoundsOffsets() { + return stripPointerCastsAndOffsets<PSK_InBounds>(this); +} /// isDereferenceablePointer - Test if this value is always a pointer to /// allocated and suitably aligned memory for a simple load or store. |