From 97f6f03c42f32a5edf59a27b56940f68c89d146b Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Sat, 10 Mar 2012 08:39:09 +0000 Subject: 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 --- llvm/lib/VMCore/Value.cpp | 48 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 6 deletions(-) (limited to 'llvm/lib/VMCore') 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(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 +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 Visited; - Value *V = this; Visited.insert(V); do { if (GEPOperator *GEP = dyn_cast(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(V)->getOperand(0); @@ -346,6 +369,19 @@ Value *Value::stripPointerCasts() { return V; } +} // namespace + +Value *Value::stripPointerCasts() { + return stripPointerCastsAndOffsets(this); +} + +Value *Value::stripConstantOffsets() { + return stripPointerCastsAndOffsets(this); +} + +Value *Value::stripInBoundsOffsets() { + return stripPointerCastsAndOffsets(this); +} /// isDereferenceablePointer - Test if this value is always a pointer to /// allocated and suitably aligned memory for a simple load or store. -- cgit v1.2.3