From 5034dd318a9dfa0dc45a3ac01e58e60f2aa2498d Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 15 Dec 2010 20:02:24 +0000 Subject: [PATCH] Move Value::getUnderlyingObject to be a standalone function so that it can live in Analysis instead of VMCore. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121885 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Analysis/ValueTracking.h | 12 +++++++++++ include/llvm/Value.h | 10 --------- lib/Analysis/BasicAliasAnalysis.cpp | 16 +++++++------- lib/Analysis/ConstantFolding.cpp | 2 +- lib/Analysis/IPA/GlobalsModRef.cpp | 9 ++++---- lib/Analysis/LazyValueInfo.cpp | 5 +++-- lib/Analysis/Lint.cpp | 2 +- lib/Analysis/Loads.cpp | 2 +- lib/Analysis/LoopDependenceAnalysis.cpp | 5 +++-- lib/Analysis/MemoryDependenceAnalysis.cpp | 3 ++- lib/Analysis/ValueTracking.cpp | 20 ++++++++++++++++++ lib/CodeGen/ScheduleDAGInstrs.cpp | 5 +++-- .../Scalar/DeadStoreElimination.cpp | 8 +++---- lib/Transforms/Scalar/GVN.cpp | 2 +- .../Scalar/ScalarReplAggregates.cpp | 7 ++++--- lib/VMCore/Value.cpp | 21 ------------------- 16 files changed, 68 insertions(+), 61 deletions(-) diff --git a/include/llvm/Analysis/ValueTracking.h b/include/llvm/Analysis/ValueTracking.h index 953d9106ed6..dcc150d18d9 100644 --- a/include/llvm/Analysis/ValueTracking.h +++ b/include/llvm/Analysis/ValueTracking.h @@ -121,6 +121,18 @@ namespace llvm { /// GetStringLength - If we can compute the length of the string pointed to by /// the specified pointer, return 'len+1'. If we can't, return 0. uint64_t GetStringLength(Value *V); + + /// GetUnderlyingObject - This method strips off any GEP address adjustments + /// and pointer casts from the specified value, returning the original object + /// being addressed. Note that the returned value has pointer type if the + /// specified value does. If the MaxLookup value is non-zero, it limits the + /// number of instructions to be stripped off. + Value *GetUnderlyingObject(Value *V, unsigned MaxLookup = 6); + static inline const Value * + GetUnderlyingObject(const Value *V, unsigned MaxLookup = 6) { + return GetUnderlyingObject(const_cast(V), MaxLookup); + } + } // end namespace llvm #endif diff --git a/include/llvm/Value.h b/include/llvm/Value.h index 8dc4105b9e4..b530287829f 100644 --- a/include/llvm/Value.h +++ b/include/llvm/Value.h @@ -285,16 +285,6 @@ public: return const_cast(this)->stripPointerCasts(); } - /// getUnderlyingObject - This method strips off any GEP address adjustments - /// and pointer casts from the specified value, returning the original object - /// being addressed. Note that the returned value has pointer type if the - /// specified value does. If the MaxLookup value is non-zero, it limits the - /// number of instructions to be stripped off. - Value *getUnderlyingObject(unsigned MaxLookup = 6); - const Value *getUnderlyingObject(unsigned MaxLookup = 6) const { - return const_cast(this)->getUnderlyingObject(MaxLookup); - } - /// isDereferenceablePointer - Test if this value is always a pointer to /// allocated and suitably aligned memory for a simple load or store. bool isDereferenceablePointer() const; diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp index 17a502e1f78..fc996fbe930 100644 --- a/lib/Analysis/BasicAliasAnalysis.cpp +++ b/lib/Analysis/BasicAliasAnalysis.cpp @@ -233,7 +233,7 @@ static Value *GetLinearExpression(Value *V, APInt &Scale, APInt &Offset, /// the gep cannot necessarily be reconstructed from its decomposed form. /// /// When TargetData is around, this function is capable of analyzing everything -/// that Value::getUnderlyingObject() can look through. When not, it just looks +/// that GetUnderlyingObject can look through. When not, it just looks /// through pointer casts. /// static const Value * @@ -528,7 +528,7 @@ BasicAliasAnalysis::pointsToConstantMemory(const Location &Loc, bool OrLocal) { SmallVector Worklist; Worklist.push_back(Loc.Ptr); do { - const Value *V = Worklist.pop_back_val()->getUnderlyingObject(); + const Value *V = GetUnderlyingObject(Worklist.pop_back_val()); if (!Visited.insert(V)) { Visited.clear(); return AliasAnalysis::pointsToConstantMemory(Loc, OrLocal); @@ -633,7 +633,7 @@ BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS, assert(notDifferentParent(CS.getInstruction(), Loc.Ptr) && "AliasAnalysis query involving multiple functions!"); - const Value *Object = Loc.Ptr->getUnderlyingObject(); + const Value *Object = GetUnderlyingObject(Loc.Ptr); // If this is a tail call and Loc.Ptr points to a stack location, we know that // the tail call cannot access or modify the local stack. @@ -761,7 +761,7 @@ BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS, /// aliasGEP - Provide a bunch of ad-hoc rules to disambiguate a GEP instruction /// against another pointer. We know that V1 is a GEP, but we don't know -/// anything about V2. UnderlyingV1 is GEP1->getUnderlyingObject(), +/// anything about V2. UnderlyingV1 is GetUnderlyingObject(GEP1), /// UnderlyingV2 is the same for V2. /// AliasAnalysis::AliasResult @@ -807,7 +807,7 @@ BasicAliasAnalysis::aliasGEP(const GEPOperator *GEP1, uint64_t V1Size, // to handle without it. if (GEP1BasePtr != UnderlyingV1 || GEP2BasePtr != UnderlyingV2) { assert(TD == 0 && - "DecomposeGEPExpression and getUnderlyingObject disagree!"); + "DecomposeGEPExpression and GetUnderlyingObject disagree!"); return MayAlias; } @@ -843,7 +843,7 @@ BasicAliasAnalysis::aliasGEP(const GEPOperator *GEP1, uint64_t V1Size, // to handle without it. if (GEP1BasePtr != UnderlyingV1) { assert(TD == 0 && - "DecomposeGEPExpression and getUnderlyingObject disagree!"); + "DecomposeGEPExpression and GetUnderlyingObject disagree!"); return MayAlias; } } @@ -1044,8 +1044,8 @@ BasicAliasAnalysis::aliasCheck(const Value *V1, uint64_t V1Size, return NoAlias; // Scalars cannot alias each other // Figure out what objects these things are pointing to if we can. - const Value *O1 = V1->getUnderlyingObject(); - const Value *O2 = V2->getUnderlyingObject(); + const Value *O1 = GetUnderlyingObject(V1); + const Value *O2 = GetUnderlyingObject(V2); // Null values in the default address space don't point to any object, so they // don't alias any other pointer. diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp index 68a55b6b94d..73ee5cd1c3b 100644 --- a/lib/Analysis/ConstantFolding.cpp +++ b/lib/Analysis/ConstantFolding.cpp @@ -467,7 +467,7 @@ Constant *llvm::ConstantFoldLoadFromConstPtr(Constant *C, // If this load comes from anywhere in a constant global, and if the global // is all undef or zero, we know what it loads. - if (GlobalVariable *GV = dyn_cast(CE->getUnderlyingObject())){ + if (GlobalVariable *GV = dyn_cast(GetUnderlyingObject(CE))){ if (GV->isConstant() && GV->hasDefinitiveInitializer()) { const Type *ResTy = cast(C->getType())->getElementType(); if (GV->getInitializer()->isNullValue()) diff --git a/lib/Analysis/IPA/GlobalsModRef.cpp b/lib/Analysis/IPA/GlobalsModRef.cpp index 456a80a972b..c18dc47406a 100644 --- a/lib/Analysis/IPA/GlobalsModRef.cpp +++ b/lib/Analysis/IPA/GlobalsModRef.cpp @@ -24,6 +24,7 @@ #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/CallGraph.h" #include "llvm/Analysis/MemoryBuiltins.h" +#include "llvm/Analysis/ValueTracking.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/InstIterator.h" #include "llvm/ADT/Statistic.h" @@ -324,7 +325,7 @@ bool GlobalsModRef::AnalyzeIndirectGlobalMemory(GlobalValue *GV) { continue; // Check the value being stored. - Value *Ptr = SI->getOperand(0)->getUnderlyingObject(); + Value *Ptr = GetUnderlyingObject(SI->getOperand(0)); if (isMalloc(Ptr)) { // Okay, easy case. @@ -489,8 +490,8 @@ AliasAnalysis::AliasResult GlobalsModRef::alias(const Location &LocA, const Location &LocB) { // Get the base object these pointers point to. - const Value *UV1 = LocA.Ptr->getUnderlyingObject(); - const Value *UV2 = LocB.Ptr->getUnderlyingObject(); + const Value *UV1 = GetUnderlyingObject(LocA.Ptr); + const Value *UV2 = GetUnderlyingObject(LocB.Ptr); // If either of the underlying values is a global, they may be non-addr-taken // globals, which we can answer queries about. @@ -549,7 +550,7 @@ GlobalsModRef::getModRefInfo(ImmutableCallSite CS, // If we are asking for mod/ref info of a direct call with a pointer to a // global we are tracking, return information if we have it. if (const GlobalValue *GV = - dyn_cast(Loc.Ptr->getUnderlyingObject())) + dyn_cast(GetUnderlyingObject(Loc.Ptr))) if (GV->hasLocalLinkage()) if (const Function *F = CS.getCalledFunction()) if (NonAddressTakenGlobals.count(GV)) diff --git a/lib/Analysis/LazyValueInfo.cpp b/lib/Analysis/LazyValueInfo.cpp index d73c504f14d..eab4ca06f07 100644 --- a/lib/Analysis/LazyValueInfo.cpp +++ b/lib/Analysis/LazyValueInfo.cpp @@ -14,6 +14,7 @@ #define DEBUG_TYPE "lazy-value-info" #include "llvm/Analysis/LazyValueInfo.h" +#include "llvm/Analysis/ValueTracking.h" #include "llvm/Constants.h" #include "llvm/Instructions.h" #include "llvm/Analysis/ConstantFolding.h" @@ -414,8 +415,8 @@ LVILatticeVal LazyValueInfoCache::getBlockValue(Value *Val, BasicBlock *BB) { for (BasicBlock::iterator BI = BB->begin(), BE = BB->end();BI != BE;++BI){ LoadInst *L = dyn_cast(BI); if (L && L->getPointerAddressSpace() == 0 && - L->getPointerOperand()->getUnderlyingObject() == - Val->getUnderlyingObject()) { + GetUnderlyingObject(L->getPointerOperand()) == + GetUnderlyingObject(Val)) { NotNull = true; break; } diff --git a/lib/Analysis/Lint.cpp b/lib/Analysis/Lint.cpp index 72ae7abd551..d68fcd22125 100644 --- a/lib/Analysis/Lint.cpp +++ b/lib/Analysis/Lint.cpp @@ -567,7 +567,7 @@ Value *Lint::findValueImpl(Value *V, bool OffsetOk, // TODO: Look through eliminable cast pairs. // TODO: Look through calls with unique return values. // TODO: Look through vector insert/extract/shuffle. - V = OffsetOk ? V->getUnderlyingObject() : V->stripPointerCasts(); + V = OffsetOk ? GetUnderlyingObject(V) : V->stripPointerCasts(); if (LoadInst *L = dyn_cast(V)) { BasicBlock::iterator BBI = L; BasicBlock *BB = L->getParent(); diff --git a/lib/Analysis/Loads.cpp b/lib/Analysis/Loads.cpp index b1f2cb41cd2..2ea27fb62fc 100644 --- a/lib/Analysis/Loads.cpp +++ b/lib/Analysis/Loads.cpp @@ -49,7 +49,7 @@ static bool AreEquivalentAddressValues(const Value *A, const Value *B) { /// getUnderlyingObjectWithOffset - Strip off up to MaxLookup GEPs and /// bitcasts to get back to the underlying object being addressed, keeping /// track of the offset in bytes from the GEPs relative to the result. -/// This is closely related to Value::getUnderlyingObject but is located +/// This is closely related to GetUnderlyingObject but is located /// here to avoid making VMCore depend on TargetData. static Value *getUnderlyingObjectWithOffset(Value *V, const TargetData *TD, uint64_t &ByteOffset, diff --git a/lib/Analysis/LoopDependenceAnalysis.cpp b/lib/Analysis/LoopDependenceAnalysis.cpp index 618c98705f8..88fc7edf42e 100644 --- a/lib/Analysis/LoopDependenceAnalysis.cpp +++ b/lib/Analysis/LoopDependenceAnalysis.cpp @@ -27,6 +27,7 @@ #include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Analysis/ScalarEvolutionExpressions.h" +#include "llvm/Analysis/ValueTracking.h" #include "llvm/Instructions.h" #include "llvm/Operator.h" #include "llvm/Support/Allocator.h" @@ -90,8 +91,8 @@ static Value *GetPointerOperand(Value *I) { static AliasAnalysis::AliasResult UnderlyingObjectsAlias(AliasAnalysis *AA, const Value *A, const Value *B) { - const Value *aObj = A->getUnderlyingObject(); - const Value *bObj = B->getUnderlyingObject(); + const Value *aObj = GetUnderlyingObject(A); + const Value *bObj = GetUnderlyingObject(B); return AA->alias(aObj, AA->getTypeStoreSize(aObj->getType()), bObj, AA->getTypeStoreSize(bObj->getType())); } diff --git a/lib/Analysis/MemoryDependenceAnalysis.cpp b/lib/Analysis/MemoryDependenceAnalysis.cpp index 1cd7dec1988..9d7bbbd6141 100644 --- a/lib/Analysis/MemoryDependenceAnalysis.cpp +++ b/lib/Analysis/MemoryDependenceAnalysis.cpp @@ -25,6 +25,7 @@ #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/PHITransAddr.h" +#include "llvm/Analysis/ValueTracking.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/PredIteratorCache.h" @@ -338,7 +339,7 @@ getPointerDependencyFrom(const AliasAnalysis::Location &MemLoc, bool isLoad, // need to continue scanning until the malloc call. if (isa(Inst) || (isa(Inst) && extractMallocCall(Inst))) { - const Value *AccessPtr = MemLoc.Ptr->getUnderlyingObject(); + const Value *AccessPtr = GetUnderlyingObject(MemLoc.Ptr); if (AccessPtr == Inst || AA->alias(Inst, 1, AccessPtr, 1) == AliasAnalysis::MustAlias) diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp index a612f130d15..d1b75c3f9fc 100644 --- a/lib/Analysis/ValueTracking.cpp +++ b/lib/Analysis/ValueTracking.cpp @@ -1426,3 +1426,23 @@ uint64_t llvm::GetStringLength(Value *V) { // an empty string as a length. return Len == ~0ULL ? 1 : Len; } + +Value *llvm::GetUnderlyingObject(Value *V, unsigned MaxLookup) { + if (!V->getType()->isPointerTy()) + return V; + for (unsigned Count = 0; MaxLookup == 0 || Count < MaxLookup; ++Count) { + if (GEPOperator *GEP = dyn_cast(V)) { + V = GEP->getPointerOperand(); + } else if (Operator::getOpcode(V) == Instruction::BitCast) { + V = cast(V)->getOperand(0); + } else if (GlobalAlias *GA = dyn_cast(V)) { + if (GA->mayBeOverridden()) + return V; + V = GA->getAliasee(); + } else { + return V; + } + assert(V->getType()->isPointerTy() && "Unexpected operand type!"); + } + return V; +} diff --git a/lib/CodeGen/ScheduleDAGInstrs.cpp b/lib/CodeGen/ScheduleDAGInstrs.cpp index e86a78c6919..5690eb4d9b3 100644 --- a/lib/CodeGen/ScheduleDAGInstrs.cpp +++ b/lib/CodeGen/ScheduleDAGInstrs.cpp @@ -16,6 +16,7 @@ #include "ScheduleDAGInstrs.h" #include "llvm/Operator.h" #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/ValueTracking.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineMemOperand.h" #include "llvm/CodeGen/MachineRegisterInfo.h" @@ -78,12 +79,12 @@ static const Value *getUnderlyingObjectFromInt(const Value *V) { } while (1); } -/// getUnderlyingObject - This is a wrapper around Value::getUnderlyingObject +/// getUnderlyingObject - This is a wrapper around GetUnderlyingObject /// and adds support for basic ptrtoint+arithmetic+inttoptr sequences. static const Value *getUnderlyingObject(const Value *V) { // First just call Value::getUnderlyingObject to let it do what it does. do { - V = V->getUnderlyingObject(); + V = GetUnderlyingObject(V); // If it found an inttoptr, use special code to continue climing. if (Operator::getOpcode(V) != Instruction::IntToPtr) break; diff --git a/lib/Transforms/Scalar/DeadStoreElimination.cpp b/lib/Transforms/Scalar/DeadStoreElimination.cpp index adb089ece60..65814a2d0d3 100644 --- a/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -324,7 +324,7 @@ static bool isCompleteOverwrite(const AliasAnalysis::Location &Later, // other store to the same object. const TargetData &TD = *AA.getTargetData(); - const Value *UO1 = P1->getUnderlyingObject(), *UO2 = P2->getUnderlyingObject(); + const Value *UO1 = GetUnderlyingObject(P1), *UO2 = GetUnderlyingObject(P2); // If we can't resolve the same pointers to the same object, then we can't // analyze them at all. @@ -542,7 +542,7 @@ bool DSE::HandleFree(CallInst *F) { return false; Value *DepPointer = - getStoredPointerOperand(Dependency)->getUnderlyingObject(); + GetUnderlyingObject(getStoredPointerOperand(Dependency)); // Check for aliasing. if (!AA->isMustAlias(F->getArgOperand(0), DepPointer)) @@ -596,7 +596,7 @@ bool DSE::handleEndBlock(BasicBlock &BB) { // If we find a store, check to see if it points into a dead stack value. if (hasMemoryWrite(BBI) && isRemovable(BBI)) { // See through pointer-to-pointer bitcasts - Value *Pointer = getStoredPointerOperand(BBI)->getUnderlyingObject(); + Value *Pointer = GetUnderlyingObject(getStoredPointerOperand(BBI)); // Stores to stack values are valid candidates for removal. if (DeadStackObjects.count(Pointer)) { @@ -703,7 +703,7 @@ bool DSE::handleEndBlock(BasicBlock &BB) { /// because the location is being loaded. void DSE::RemoveAccessedObjects(const AliasAnalysis::Location &LoadedLoc, SmallPtrSet &DeadStackObjects) { - const Value *UnderlyingPointer = LoadedLoc.Ptr->getUnderlyingObject(); + const Value *UnderlyingPointer = GetUnderlyingObject(LoadedLoc.Ptr); // A constant can't be in the dead pointer set. if (isa(UnderlyingPointer)) diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp index 6b25eb5c0c9..d8629e68b8d 100644 --- a/lib/Transforms/Scalar/GVN.cpp +++ b/lib/Transforms/Scalar/GVN.cpp @@ -1076,7 +1076,7 @@ static int AnalyzeLoadFromClobberingMemInst(const Type *LoadTy, Value *LoadPtr, Constant *Src = dyn_cast(MTI->getSource()); if (Src == 0) return -1; - GlobalVariable *GV = dyn_cast(Src->getUnderlyingObject()); + GlobalVariable *GV = dyn_cast(GetUnderlyingObject(Src)); if (GV == 0 || !GV->isConstant()) return -1; // See if the access is within the bounds of the transfer. diff --git a/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/lib/Transforms/Scalar/ScalarReplAggregates.cpp index 3b4f4439d4f..98519afa0d9 100644 --- a/lib/Transforms/Scalar/ScalarReplAggregates.cpp +++ b/lib/Transforms/Scalar/ScalarReplAggregates.cpp @@ -31,6 +31,7 @@ #include "llvm/Module.h" #include "llvm/Pass.h" #include "llvm/Analysis/Dominators.h" +#include "llvm/Analysis/ValueTracking.h" #include "llvm/Target/TargetData.h" #include "llvm/Transforms/Utils/PromoteMemToReg.h" #include "llvm/Transforms/Utils/Local.h" @@ -490,9 +491,9 @@ void ConvertToScalarInfo::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, // If the source and destination are both to the same alloca, then this is // a noop copy-to-self, just delete it. Otherwise, emit a load and store // as appropriate. - AllocaInst *OrigAI = cast(Ptr->getUnderlyingObject(0)); + AllocaInst *OrigAI = cast(GetUnderlyingObject(Ptr, 0)); - if (MTI->getSource()->getUnderlyingObject(0) != OrigAI) { + if (GetUnderlyingObject(MTI->getSource(), 0) != OrigAI) { // Dest must be OrigAI, change this to be a load from the original // pointer (bitcasted), then a store to our new alloca. assert(MTI->getRawDest() == Ptr && "Neither use is of pointer?"); @@ -502,7 +503,7 @@ void ConvertToScalarInfo::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, LoadInst *SrcVal = Builder.CreateLoad(SrcPtr, "srcval"); SrcVal->setAlignment(MTI->getAlignment()); Builder.CreateStore(SrcVal, NewAI); - } else if (MTI->getDest()->getUnderlyingObject(0) != OrigAI) { + } else if (GetUnderlyingObject(MTI->getDest(), 0) != OrigAI) { // Src must be OrigAI, change this to be a load from NewAI then a store // through the original dest pointer (bitcasted). assert(MTI->getRawSource() == Ptr && "Neither use is of pointer?"); diff --git a/lib/VMCore/Value.cpp b/lib/VMCore/Value.cpp index 9d0c2c5ae2a..76cfb9082a5 100644 --- a/lib/VMCore/Value.cpp +++ b/lib/VMCore/Value.cpp @@ -346,27 +346,6 @@ Value *Value::stripPointerCasts() { return V; } -Value *Value::getUnderlyingObject(unsigned MaxLookup) { - if (!getType()->isPointerTy()) - return this; - Value *V = this; - for (unsigned Count = 0; MaxLookup == 0 || Count < MaxLookup; ++Count) { - if (GEPOperator *GEP = dyn_cast(V)) { - V = GEP->getPointerOperand(); - } else if (Operator::getOpcode(V) == Instruction::BitCast) { - V = cast(V)->getOperand(0); - } else if (GlobalAlias *GA = dyn_cast(V)) { - if (GA->mayBeOverridden()) - return V; - V = GA->getAliasee(); - } else { - return V; - } - assert(V->getType()->isPointerTy() && "Unexpected operand type!"); - } - return V; -} - /// isDereferenceablePointer - Test if this value is always a pointer to /// allocated and suitably aligned memory for a simple load or store. bool Value::isDereferenceablePointer() const { -- 2.34.1