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 | 84dfc32ff906271c373819595e60a173624e1184 (patch) | |
tree | 0c403b25ac3430940d7e009bf0ee9b307d2e298b /lib/VMCore/Value.cpp | |
parent | e060eb8916820fb7a2035dd14c848aa1fd545efe (diff) | |
download | llvm-84dfc32ff906271c373819595e60a173624e1184.tar.gz llvm-84dfc32ff906271c373819595e60a173624e1184.tar.bz2 llvm-84dfc32ff906271c373819595e60a173624e1184.tar.xz |
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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@152490 91177308-0d34-0410-b5e6-96231b3b80d8
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. |