diff options
author | Chandler Carruth <chandlerc@gmail.com> | 2012-03-10 08:39:09 +0000 |
---|---|---|
committer | Chandler Carruth <chandlerc@gmail.com> | 2012-03-10 08:39:09 +0000 |
commit | 97f6f03c42f32a5edf59a27b56940f68c89d146b (patch) | |
tree | 72ce7ba37172714198857f83a7f51fa1f893c974 /llvm/lib/VMCore/Value.cpp | |
parent | f604212a444c248a5909842bfff67e4476136fdb (diff) | |
download | bcm5719-llvm-97f6f03c42f32a5edf59a27b56940f68c89d146b.tar.gz bcm5719-llvm-97f6f03c42f32a5edf59a27b56940f68c89d146b.zip |
Refactor some methods to look through bitcasts and GEPs on pointers into
a common collection of methods on Value, and share their implementation.
We had two variations in two different places already, and I need the
third variation for inline cost estimation.
Reviewed by Duncan Sands on IRC, but further comments here welcome.
llvm-svn: 152490
Diffstat (limited to 'llvm/lib/VMCore/Value.cpp')
-rw-r--r-- | llvm/lib/VMCore/Value.cpp | 48 |
1 files changed, 42 insertions, 6 deletions
diff --git a/llvm/lib/VMCore/Value.cpp b/llvm/lib/VMCore/Value.cpp index 207c06d2231..40b2d95e3d0 100644 --- a/llvm/lib/VMCore/Value.cpp +++ b/llvm/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. |