mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-12 18:33:22 +00:00
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
This commit is contained in:
parent
d5f4bc2c33
commit
5034dd318a
@ -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<Value *>(V), MaxLookup);
|
||||
}
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
|
@ -285,16 +285,6 @@ public:
|
||||
return const_cast<Value*>(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<Value*>(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;
|
||||
|
@ -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<const Value *, 16> 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.
|
||||
|
@ -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<GlobalVariable>(CE->getUnderlyingObject())){
|
||||
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(GetUnderlyingObject(CE))){
|
||||
if (GV->isConstant() && GV->hasDefinitiveInitializer()) {
|
||||
const Type *ResTy = cast<PointerType>(C->getType())->getElementType();
|
||||
if (GV->getInitializer()->isNullValue())
|
||||
|
@ -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<GlobalValue>(Loc.Ptr->getUnderlyingObject()))
|
||||
dyn_cast<GlobalValue>(GetUnderlyingObject(Loc.Ptr)))
|
||||
if (GV->hasLocalLinkage())
|
||||
if (const Function *F = CS.getCalledFunction())
|
||||
if (NonAddressTakenGlobals.count(GV))
|
||||
|
@ -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<LoadInst>(BI);
|
||||
if (L && L->getPointerAddressSpace() == 0 &&
|
||||
L->getPointerOperand()->getUnderlyingObject() ==
|
||||
Val->getUnderlyingObject()) {
|
||||
GetUnderlyingObject(L->getPointerOperand()) ==
|
||||
GetUnderlyingObject(Val)) {
|
||||
NotNull = true;
|
||||
break;
|
||||
}
|
||||
|
@ -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<LoadInst>(V)) {
|
||||
BasicBlock::iterator BBI = L;
|
||||
BasicBlock *BB = L->getParent();
|
||||
|
@ -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,
|
||||
|
@ -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()));
|
||||
}
|
||||
|
@ -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<AllocaInst>(Inst) ||
|
||||
(isa<CallInst>(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)
|
||||
|
@ -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<GEPOperator>(V)) {
|
||||
V = GEP->getPointerOperand();
|
||||
} else if (Operator::getOpcode(V) == Instruction::BitCast) {
|
||||
V = cast<Operator>(V)->getOperand(0);
|
||||
} else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V)) {
|
||||
if (GA->mayBeOverridden())
|
||||
return V;
|
||||
V = GA->getAliasee();
|
||||
} else {
|
||||
return V;
|
||||
}
|
||||
assert(V->getType()->isPointerTy() && "Unexpected operand type!");
|
||||
}
|
||||
return V;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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<Value*, 16> &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<Constant>(UnderlyingPointer))
|
||||
|
@ -1076,7 +1076,7 @@ static int AnalyzeLoadFromClobberingMemInst(const Type *LoadTy, Value *LoadPtr,
|
||||
Constant *Src = dyn_cast<Constant>(MTI->getSource());
|
||||
if (Src == 0) return -1;
|
||||
|
||||
GlobalVariable *GV = dyn_cast<GlobalVariable>(Src->getUnderlyingObject());
|
||||
GlobalVariable *GV = dyn_cast<GlobalVariable>(GetUnderlyingObject(Src));
|
||||
if (GV == 0 || !GV->isConstant()) return -1;
|
||||
|
||||
// See if the access is within the bounds of the transfer.
|
||||
|
@ -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<AllocaInst>(Ptr->getUnderlyingObject(0));
|
||||
AllocaInst *OrigAI = cast<AllocaInst>(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?");
|
||||
|
@ -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<GEPOperator>(V)) {
|
||||
V = GEP->getPointerOperand();
|
||||
} else if (Operator::getOpcode(V) == Instruction::BitCast) {
|
||||
V = cast<Operator>(V)->getOperand(0);
|
||||
} else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user