summaryrefslogtreecommitdiff
path: root/lib/VMCore/Value.cpp
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2012-03-10 08:39:09 +0000
committerChandler Carruth <chandlerc@gmail.com>2012-03-10 08:39:09 +0000
commit84dfc32ff906271c373819595e60a173624e1184 (patch)
tree0c403b25ac3430940d7e009bf0ee9b307d2e298b /lib/VMCore/Value.cpp
parente060eb8916820fb7a2035dd14c848aa1fd545efe (diff)
downloadllvm-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.cpp48
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.