[PM/AA] Remove the UnknownSize static member from AliasAnalysis.

This is now living in MemoryLocation, which is what it pertains to. It
is also an enum there rather than a static data member which is left
never defined.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239886 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chandler Carruth 2015-06-17 07:21:38 +00:00
parent 4d7ed3960c
commit 2cdca0c4e4
12 changed files with 81 additions and 79 deletions

View File

@ -18,9 +18,10 @@
//
// This API identifies memory regions with the MemoryLocation class. The pointer
// component specifies the base memory address of the region. The Size specifies
// the maximum size (in address units) of the memory region, or UnknownSize if
// the size is not known. The TBAA tag identifies the "type" of the memory
// reference; see the TypeBasedAliasAnalysis class for details.
// the maximum size (in address units) of the memory region, or
// MemoryLocation::UnknownSize if the size is not known. The TBAA tag
// identifies the "type" of the memory reference; see the
// TypeBasedAliasAnalysis class for details.
//
// Some non-obvious details include:
// - Pointers that point to two completely different objects in memory never
@ -80,11 +81,6 @@ public:
AliasAnalysis() : DL(nullptr), TLI(nullptr), AA(nullptr) {}
virtual ~AliasAnalysis(); // We want to be subclassed
/// UnknownSize - This is a special value which can be used with the
/// size arguments in alias queries to indicate that the caller does not
/// know the sizes of the potential memory references.
static uint64_t const UnknownSize = MemoryLocation::UnknownSize;
/// getTargetLibraryInfo - Return a pointer to the current TargetLibraryInfo
/// object, or null if no TargetLibraryInfo object is available.
///
@ -130,7 +126,8 @@ public:
/// alias - A convenience wrapper.
AliasResult alias(const Value *V1, const Value *V2) {
return alias(V1, UnknownSize, V2, UnknownSize);
return alias(V1, MemoryLocation::UnknownSize, V2,
MemoryLocation::UnknownSize);
}
/// isNoAlias - A trivial helper function to check to see if the specified

View File

@ -287,7 +287,7 @@ namespace llvm {
/// conflicting tags.
AAMDNodes AATags;
NonLocalPointerInfo() : Size(AliasAnalysis::UnknownSize) {}
NonLocalPointerInfo() : Size(MemoryLocation::UnknownSize) {}
};
/// CachedNonLocalPointerInfo - This map stores the cached results of doing

View File

@ -429,7 +429,7 @@ void AliasAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
/// if known, or a conservative value otherwise.
///
uint64_t AliasAnalysis::getTypeStoreSize(Type *Ty) {
return DL ? DL->getTypeStoreSize(Ty) : UnknownSize;
return DL ? DL->getTypeStoreSize(Ty) : MemoryLocation::UnknownSize;
}
/// canBasicBlockModify - Return true if it is possible for execution of the

View File

@ -186,12 +186,12 @@ bool AAEval::runOnFunction(Function &F) {
// iterate over the worklist, and run the full (n^2)/2 disambiguations
for (SetVector<Value *>::iterator I1 = Pointers.begin(), E = Pointers.end();
I1 != E; ++I1) {
uint64_t I1Size = AliasAnalysis::UnknownSize;
uint64_t I1Size = MemoryLocation::UnknownSize;
Type *I1ElTy = cast<PointerType>((*I1)->getType())->getElementType();
if (I1ElTy->isSized()) I1Size = AA.getTypeStoreSize(I1ElTy);
for (SetVector<Value *>::iterator I2 = Pointers.begin(); I2 != I1; ++I2) {
uint64_t I2Size = AliasAnalysis::UnknownSize;
uint64_t I2Size = MemoryLocation::UnknownSize;
Type *I2ElTy =cast<PointerType>((*I2)->getType())->getElementType();
if (I2ElTy->isSized()) I2Size = AA.getTypeStoreSize(I2ElTy);
@ -275,7 +275,7 @@ bool AAEval::runOnFunction(Function &F) {
for (SetVector<Value *>::iterator V = Pointers.begin(), Ve = Pointers.end();
V != Ve; ++V) {
uint64_t Size = AliasAnalysis::UnknownSize;
uint64_t Size = MemoryLocation::UnknownSize;
Type *ElTy = cast<PointerType>((*V)->getType())->getElementType();
if (ElTy->isSized()) Size = AA.getTypeStoreSize(ElTy);

View File

@ -337,8 +337,8 @@ bool AliasSetTracker::add(VAArgInst *VAAI) {
VAAI->getAAMetadata(AAInfo);
bool NewPtr;
addPointer(VAAI->getOperand(0), AliasAnalysis::UnknownSize,
AAInfo, AliasSet::ModRef, NewPtr);
addPointer(VAAI->getOperand(0), MemoryLocation::UnknownSize, AAInfo,
AliasSet::ModRef, NewPtr);
return NewPtr;
}
@ -471,7 +471,7 @@ bool AliasSetTracker::remove(VAArgInst *VAAI) {
VAAI->getAAMetadata(AAInfo);
AliasSet *AS = findAliasSetForPointer(VAAI->getOperand(0),
AliasAnalysis::UnknownSize, AAInfo);
MemoryLocation::UnknownSize, AAInfo);
if (!AS) return false;
remove(*AS);
return true;

View File

@ -105,7 +105,7 @@ static uint64_t getObjectSize(const Value *V, const DataLayout &DL,
uint64_t Size;
if (getObjectSize(V, Size, DL, &TLI, RoundToAlign))
return Size;
return AliasAnalysis::UnknownSize;
return MemoryLocation::UnknownSize;
}
/// isObjectSmallerThan - Return true if we can prove that the object specified
@ -146,7 +146,7 @@ static bool isObjectSmallerThan(const Value *V, uint64_t Size,
// reads a bit past the end given sufficient alignment.
uint64_t ObjectSize = getObjectSize(V, DL, TLI, /*RoundToAlign*/true);
return ObjectSize != AliasAnalysis::UnknownSize && ObjectSize < Size;
return ObjectSize != MemoryLocation::UnknownSize && ObjectSize < Size;
}
/// isObjectSize - Return true if we can prove that the object specified
@ -154,7 +154,7 @@ static bool isObjectSmallerThan(const Value *V, uint64_t Size,
static bool isObjectSize(const Value *V, uint64_t Size,
const DataLayout &DL, const TargetLibraryInfo &TLI) {
uint64_t ObjectSize = getObjectSize(V, DL, TLI);
return ObjectSize != AliasAnalysis::UnknownSize && ObjectSize == Size;
return ObjectSize != MemoryLocation::UnknownSize && ObjectSize == Size;
}
//===----------------------------------------------------------------------===//
@ -855,8 +855,8 @@ aliasSameBasePointerGEPs(const GEPOperator *GEP1, uint64_t V1Size,
// If we don't know the size of the accesses through both GEPs, we can't
// determine whether the struct fields accessed can't alias.
if (V1Size == AliasAnalysis::UnknownSize ||
V2Size == AliasAnalysis::UnknownSize)
if (V1Size == MemoryLocation::UnknownSize ||
V2Size == MemoryLocation::UnknownSize)
return AliasAnalysis::MayAlias;
ConstantInt *C1 =
@ -970,8 +970,9 @@ BasicAliasAnalysis::aliasGEP(const GEPOperator *GEP1, uint64_t V1Size,
// derived pointer.
if (const GEPOperator *GEP2 = dyn_cast<GEPOperator>(V2)) {
// Do the base pointers alias?
AliasResult BaseAlias = aliasCheck(UnderlyingV1, UnknownSize, AAMDNodes(),
UnderlyingV2, UnknownSize, AAMDNodes());
AliasResult BaseAlias =
aliasCheck(UnderlyingV1, MemoryLocation::UnknownSize, AAMDNodes(),
UnderlyingV2, MemoryLocation::UnknownSize, AAMDNodes());
// Check for geps of non-aliasing underlying pointers where the offsets are
// identical.
@ -1062,11 +1063,12 @@ BasicAliasAnalysis::aliasGEP(const GEPOperator *GEP1, uint64_t V1Size,
// pointer, we know they cannot alias.
// If both accesses are unknown size, we can't do anything useful here.
if (V1Size == UnknownSize && V2Size == UnknownSize)
if (V1Size == MemoryLocation::UnknownSize &&
V2Size == MemoryLocation::UnknownSize)
return MayAlias;
AliasResult R = aliasCheck(UnderlyingV1, UnknownSize, AAMDNodes(),
V2, V2Size, V2AAInfo);
AliasResult R = aliasCheck(UnderlyingV1, MemoryLocation::UnknownSize,
AAMDNodes(), V2, V2Size, V2AAInfo);
if (R != MustAlias)
// If V2 may alias GEP base pointer, conservatively returns MayAlias.
// If V2 is known not to alias GEP base pointer, then the two values
@ -1106,7 +1108,7 @@ BasicAliasAnalysis::aliasGEP(const GEPOperator *GEP1, uint64_t V1Size,
// greater, we know they do not overlap.
if (GEP1BaseOffset != 0 && GEP1VariableIndices.empty()) {
if (GEP1BaseOffset >= 0) {
if (V2Size != UnknownSize) {
if (V2Size != MemoryLocation::UnknownSize) {
if ((uint64_t)GEP1BaseOffset < V2Size)
return PartialAlias;
return NoAlias;
@ -1120,7 +1122,8 @@ BasicAliasAnalysis::aliasGEP(const GEPOperator *GEP1, uint64_t V1Size,
// GEP1 V2
// We need to know that V2Size is not unknown, otherwise we might have
// stripped a gep with negative index ('gep <ptr>, -1, ...).
if (V1Size != UnknownSize && V2Size != UnknownSize) {
if (V1Size != MemoryLocation::UnknownSize &&
V2Size != MemoryLocation::UnknownSize) {
if (-(uint64_t)GEP1BaseOffset < V1Size)
return PartialAlias;
return NoAlias;
@ -1171,8 +1174,9 @@ BasicAliasAnalysis::aliasGEP(const GEPOperator *GEP1, uint64_t V1Size,
// mod Modulo. Check whether that difference guarantees that the
// two locations do not alias.
uint64_t ModOffset = (uint64_t)GEP1BaseOffset & (Modulo - 1);
if (V1Size != UnknownSize && V2Size != UnknownSize &&
ModOffset >= V2Size && V1Size <= Modulo - ModOffset)
if (V1Size != MemoryLocation::UnknownSize &&
V2Size != MemoryLocation::UnknownSize && ModOffset >= V2Size &&
V1Size <= Modulo - ModOffset)
return NoAlias;
// If we know all the variables are positive, then GEP1 >= GEP1BasePtr.
@ -1410,8 +1414,10 @@ BasicAliasAnalysis::aliasCheck(const Value *V1, uint64_t V1Size,
// If the size of one access is larger than the entire object on the other
// side, then we know such behavior is undefined and can assume no alias.
if (DL)
if ((V1Size != UnknownSize && isObjectSmallerThan(O2, V1Size, *DL, *TLI)) ||
(V2Size != UnknownSize && isObjectSmallerThan(O1, V2Size, *DL, *TLI)))
if ((V1Size != MemoryLocation::UnknownSize &&
isObjectSmallerThan(O2, V1Size, *DL, *TLI)) ||
(V2Size != MemoryLocation::UnknownSize &&
isObjectSmallerThan(O1, V2Size, *DL, *TLI)))
return NoAlias;
// Check the cache before climbing up use-def chains. This also terminates
@ -1464,8 +1470,10 @@ BasicAliasAnalysis::aliasCheck(const Value *V1, uint64_t V1Size,
// accesses is accessing the entire object, then the accesses must
// overlap in some way.
if (DL && O1 == O2)
if ((V1Size != UnknownSize && isObjectSize(O1, V1Size, *DL, *TLI)) ||
(V2Size != UnknownSize && isObjectSize(O2, V2Size, *DL, *TLI)))
if ((V1Size != MemoryLocation::UnknownSize &&
isObjectSize(O1, V1Size, *DL, *TLI)) ||
(V2Size != MemoryLocation::UnknownSize &&
isObjectSize(O2, V2Size, *DL, *TLI)))
return AliasCache[Locs] = PartialAlias;
AliasResult Result =

View File

@ -202,8 +202,8 @@ void Lint::visitCallSite(CallSite CS) {
Value *Callee = CS.getCalledValue();
const DataLayout &DL = CS->getModule()->getDataLayout();
visitMemoryReference(I, Callee, AliasAnalysis::UnknownSize,
0, nullptr, MemRef::Callee);
visitMemoryReference(I, Callee, MemoryLocation::UnknownSize, 0, nullptr,
MemRef::Callee);
if (Function *F = dyn_cast<Function>(findValue(Callee, DL,
/*OffsetOk=*/false))) {
@ -282,12 +282,10 @@ void Lint::visitCallSite(CallSite CS) {
case Intrinsic::memcpy: {
MemCpyInst *MCI = cast<MemCpyInst>(&I);
// TODO: If the size is known, use it.
visitMemoryReference(I, MCI->getDest(), AliasAnalysis::UnknownSize,
MCI->getAlignment(), nullptr,
MemRef::Write);
visitMemoryReference(I, MCI->getSource(), AliasAnalysis::UnknownSize,
MCI->getAlignment(), nullptr,
MemRef::Read);
visitMemoryReference(I, MCI->getDest(), MemoryLocation::UnknownSize,
MCI->getAlignment(), nullptr, MemRef::Write);
visitMemoryReference(I, MCI->getSource(), MemoryLocation::UnknownSize,
MCI->getAlignment(), nullptr, MemRef::Read);
// Check that the memcpy arguments don't overlap. The AliasAnalysis API
// isn't expressive enough for what we really want to do. Known partial
@ -306,20 +304,17 @@ void Lint::visitCallSite(CallSite CS) {
case Intrinsic::memmove: {
MemMoveInst *MMI = cast<MemMoveInst>(&I);
// TODO: If the size is known, use it.
visitMemoryReference(I, MMI->getDest(), AliasAnalysis::UnknownSize,
MMI->getAlignment(), nullptr,
MemRef::Write);
visitMemoryReference(I, MMI->getSource(), AliasAnalysis::UnknownSize,
MMI->getAlignment(), nullptr,
MemRef::Read);
visitMemoryReference(I, MMI->getDest(), MemoryLocation::UnknownSize,
MMI->getAlignment(), nullptr, MemRef::Write);
visitMemoryReference(I, MMI->getSource(), MemoryLocation::UnknownSize,
MMI->getAlignment(), nullptr, MemRef::Read);
break;
}
case Intrinsic::memset: {
MemSetInst *MSI = cast<MemSetInst>(&I);
// TODO: If the size is known, use it.
visitMemoryReference(I, MSI->getDest(), AliasAnalysis::UnknownSize,
MSI->getAlignment(), nullptr,
MemRef::Write);
visitMemoryReference(I, MSI->getDest(), MemoryLocation::UnknownSize,
MSI->getAlignment(), nullptr, MemRef::Write);
break;
}
@ -328,26 +323,26 @@ void Lint::visitCallSite(CallSite CS) {
"Undefined behavior: va_start called in a non-varargs function",
&I);
visitMemoryReference(I, CS.getArgument(0), AliasAnalysis::UnknownSize,
0, nullptr, MemRef::Read | MemRef::Write);
visitMemoryReference(I, CS.getArgument(0), MemoryLocation::UnknownSize, 0,
nullptr, MemRef::Read | MemRef::Write);
break;
case Intrinsic::vacopy:
visitMemoryReference(I, CS.getArgument(0), AliasAnalysis::UnknownSize,
0, nullptr, MemRef::Write);
visitMemoryReference(I, CS.getArgument(1), AliasAnalysis::UnknownSize,
0, nullptr, MemRef::Read);
visitMemoryReference(I, CS.getArgument(0), MemoryLocation::UnknownSize, 0,
nullptr, MemRef::Write);
visitMemoryReference(I, CS.getArgument(1), MemoryLocation::UnknownSize, 0,
nullptr, MemRef::Read);
break;
case Intrinsic::vaend:
visitMemoryReference(I, CS.getArgument(0), AliasAnalysis::UnknownSize,
0, nullptr, MemRef::Read | MemRef::Write);
visitMemoryReference(I, CS.getArgument(0), MemoryLocation::UnknownSize, 0,
nullptr, MemRef::Read | MemRef::Write);
break;
case Intrinsic::stackrestore:
// Stackrestore doesn't read or write memory, but it sets the
// stack pointer, which the compiler may read from or write to
// at any time, so check it for both readability and writeability.
visitMemoryReference(I, CS.getArgument(0), AliasAnalysis::UnknownSize,
0, nullptr, MemRef::Read | MemRef::Write);
visitMemoryReference(I, CS.getArgument(0), MemoryLocation::UnknownSize, 0,
nullptr, MemRef::Read | MemRef::Write);
break;
case Intrinsic::eh_begincatch:
@ -435,7 +430,7 @@ void Lint::visitMemoryReference(Instruction &I,
// OK, so the access is to a constant offset from Ptr. Check that Ptr is
// something we can handle and if so extract the size of this base object
// along with its alignment.
uint64_t BaseSize = AliasAnalysis::UnknownSize;
uint64_t BaseSize = MemoryLocation::UnknownSize;
unsigned BaseAlign = 0;
if (AllocaInst *AI = dyn_cast<AllocaInst>(Base)) {
@ -460,8 +455,8 @@ void Lint::visitMemoryReference(Instruction &I,
// Accesses from before the start or after the end of the object are not
// defined.
Assert(Size == AliasAnalysis::UnknownSize ||
BaseSize == AliasAnalysis::UnknownSize ||
Assert(Size == MemoryLocation::UnknownSize ||
BaseSize == MemoryLocation::UnknownSize ||
(Offset >= 0 && Offset + Size <= BaseSize),
"Undefined behavior: Buffer overflow", &I);
@ -770,12 +765,12 @@ void Lint::visitAllocaInst(AllocaInst &I) {
}
void Lint::visitVAArgInst(VAArgInst &I) {
visitMemoryReference(I, I.getOperand(0), AliasAnalysis::UnknownSize, 0,
visitMemoryReference(I, I.getOperand(0), MemoryLocation::UnknownSize, 0,
nullptr, MemRef::Read | MemRef::Write);
}
void Lint::visitIndirectBrInst(IndirectBrInst &I) {
visitMemoryReference(I, I.getAddress(), AliasAnalysis::UnknownSize, 0,
visitMemoryReference(I, I.getAddress(), MemoryLocation::UnknownSize, 0,
nullptr, MemRef::Branchee);
Assert(I.getNumDestinations() != 0,

View File

@ -212,7 +212,7 @@ public:
/// \brief Register a load and whether it is only read from.
void addLoad(MemoryLocation &Loc, bool IsReadOnly) {
Value *Ptr = const_cast<Value*>(Loc.Ptr);
AST.add(Ptr, AliasAnalysis::UnknownSize, Loc.AATags);
AST.add(Ptr, MemoryLocation::UnknownSize, Loc.AATags);
Accesses.insert(MemAccessInfo(Ptr, false));
if (IsReadOnly)
ReadOnlyPtr.insert(Ptr);
@ -221,7 +221,7 @@ public:
/// \brief Register a store.
void addStore(MemoryLocation &Loc) {
Value *Ptr = const_cast<Value*>(Loc.Ptr);
AST.add(Ptr, AliasAnalysis::UnknownSize, Loc.AATags);
AST.add(Ptr, MemoryLocation::UnknownSize, Loc.AATags);
Accesses.insert(MemAccessInfo(Ptr, true));
}

View File

@ -162,9 +162,11 @@ ScalarEvolutionAliasAnalysis::alias(const MemoryLocation &LocA,
Value *AO = GetBaseValue(AS);
Value *BO = GetBaseValue(BS);
if ((AO && AO != LocA.Ptr) || (BO && BO != LocB.Ptr))
if (alias(MemoryLocation(AO ? AO : LocA.Ptr, AO ? +UnknownSize : LocA.Size,
if (alias(MemoryLocation(AO ? AO : LocA.Ptr,
AO ? +MemoryLocation::UnknownSize : LocA.Size,
AO ? AAMDNodes() : LocA.AATags),
MemoryLocation(BO ? BO : LocB.Ptr, BO ? +UnknownSize : LocB.Size,
MemoryLocation(BO ? BO : LocB.Ptr,
BO ? +MemoryLocation::UnknownSize : LocB.Size,
BO ? AAMDNodes() : LocB.AATags)) == NoAlias)
return NoAlias;

View File

@ -208,7 +208,7 @@ bool FunctionAttrs::AddReadAttrs(const CallGraphSCC &SCC) {
AAMDNodes AAInfo;
I->getAAMetadata(AAInfo);
MemoryLocation Loc(Arg, AliasAnalysis::UnknownSize, AAInfo);
MemoryLocation Loc(Arg, MemoryLocation::UnknownSize, AAInfo);
if (!AA->pointsToConstantMemory(Loc, /*OrLocal=*/true)) {
if (MRB & AliasAnalysis::Mod)
// Writes non-local memory. Give up.

View File

@ -317,7 +317,7 @@ static uint64_t getPointerSize(const Value *V, const DataLayout &DL,
uint64_t Size;
if (getObjectSize(V, Size, DL, TLI))
return Size;
return AliasAnalysis::UnknownSize;
return MemoryLocation::UnknownSize;
}
namespace {
@ -346,8 +346,8 @@ static OverwriteResult isOverwrite(const MemoryLocation &Later,
if (P1 == P2) {
// If we don't know the sizes of either access, then we can't do a
// comparison.
if (Later.Size == AliasAnalysis::UnknownSize ||
Earlier.Size == AliasAnalysis::UnknownSize)
if (Later.Size == MemoryLocation::UnknownSize ||
Earlier.Size == MemoryLocation::UnknownSize)
return OverwriteUnknown;
// Make sure that the Later size is >= the Earlier size.
@ -357,8 +357,8 @@ static OverwriteResult isOverwrite(const MemoryLocation &Later,
// Otherwise, we have to have size information, and the later store has to be
// larger than the earlier one.
if (Later.Size == AliasAnalysis::UnknownSize ||
Earlier.Size == AliasAnalysis::UnknownSize)
if (Later.Size == MemoryLocation::UnknownSize ||
Earlier.Size == MemoryLocation::UnknownSize)
return OverwriteUnknown;
// Check to see if the later store is to the entire object (either a global,
@ -374,7 +374,7 @@ static OverwriteResult isOverwrite(const MemoryLocation &Later,
// If the "Later" store is to a recognizable object, get its size.
uint64_t ObjectSize = getPointerSize(UO2, DL, TLI);
if (ObjectSize != AliasAnalysis::UnknownSize)
if (ObjectSize != MemoryLocation::UnknownSize)
if (ObjectSize == Later.Size && ObjectSize >= Earlier.Size)
return OverwriteComplete;

View File

@ -833,7 +833,7 @@ static bool mayLoopAccessLocation(Value *Ptr,AliasAnalysis::ModRefResult Access,
// Get the location that may be stored across the loop. Since the access is
// strided positively through memory, we say that the modified location starts
// at the pointer and has infinite size.
uint64_t AccessSize = AliasAnalysis::UnknownSize;
uint64_t AccessSize = MemoryLocation::UnknownSize;
// If the loop iterates a fixed number of times, we can refine the access size
// to be exactly the size of the memset, which is (BECount+1)*StoreSize