diff options
author | Dan Gohman <gohman@apple.com> | 2011-01-18 21:16:06 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2011-01-18 21:16:06 +0000 |
commit | 615da1a9bcca05de06fab5f48ee9110267312974 (patch) | |
tree | a8e2dddced58cfc75aaeb446556195e678b8b50b /lib/Analysis | |
parent | b5fa9333431673aac2ced8dea80152349a85cf6f (diff) |
Teach BasicAA to return PartialAlias in cases where both pointers
are pointing to the same object, one pointer is accessing the entire
object, and the other is access has a non-zero size. This prevents
TBAA from kicking in and saying NoAlias in such cases.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123775 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis')
-rw-r--r-- | lib/Analysis/BasicAliasAnalysis.cpp | 47 |
1 files changed, 35 insertions, 12 deletions
diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp index 8e0637a49b..f3695929d1 100644 --- a/lib/Analysis/BasicAliasAnalysis.cpp +++ b/lib/Analysis/BasicAliasAnalysis.cpp @@ -97,38 +97,53 @@ static bool isEscapeSource(const Value *V) { return false; } -/// isObjectSmallerThan - Return true if we can prove that the object specified -/// by V is smaller than Size. -static bool isObjectSmallerThan(const Value *V, uint64_t Size, - const TargetData &TD) { +/// getObjectSize - Return the size of the object specified by V, or +/// UnknownSize if unknown. +static uint64_t getObjectSize(const Value *V, const TargetData &TD) { const Type *AccessTy; if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) { if (!GV->hasDefinitiveInitializer()) - return false; + return AliasAnalysis::UnknownSize; AccessTy = GV->getType()->getElementType(); } else if (const AllocaInst *AI = dyn_cast<AllocaInst>(V)) { if (!AI->isArrayAllocation()) AccessTy = AI->getType()->getElementType(); else - return false; + return AliasAnalysis::UnknownSize; } else if (const CallInst* CI = extractMallocCall(V)) { if (!isArrayMalloc(V, &TD)) // The size is the argument to the malloc call. if (const ConstantInt* C = dyn_cast<ConstantInt>(CI->getArgOperand(0))) - return (C->getZExtValue() < Size); - return false; + return C->getZExtValue(); + return AliasAnalysis::UnknownSize; } else if (const Argument *A = dyn_cast<Argument>(V)) { if (A->hasByValAttr()) AccessTy = cast<PointerType>(A->getType())->getElementType(); else - return false; + return AliasAnalysis::UnknownSize; } else { - return false; + return AliasAnalysis::UnknownSize; } if (AccessTy->isSized()) - return TD.getTypeAllocSize(AccessTy) < Size; - return false; + return TD.getTypeAllocSize(AccessTy); + return AliasAnalysis::UnknownSize; +} + +/// isObjectSmallerThan - Return true if we can prove that the object specified +/// by V is smaller than Size. +static bool isObjectSmallerThan(const Value *V, uint64_t Size, + const TargetData &TD) { + uint64_t ObjectSize = getObjectSize(V, TD); + return ObjectSize != AliasAnalysis::UnknownSize && ObjectSize < Size; +} + +/// isObjectSize - Return true if we can prove that the object specified +/// by V has size Size. +static bool isObjectSize(const Value *V, uint64_t Size, + const TargetData &TD) { + uint64_t ObjectSize = getObjectSize(V, TD); + return ObjectSize != AliasAnalysis::UnknownSize && ObjectSize == Size; } //===----------------------------------------------------------------------===// @@ -1142,6 +1157,14 @@ BasicAliasAnalysis::aliasCheck(const Value *V1, uint64_t V1Size, if (Result != MayAlias) return Result; } + // If both pointers are pointing into the same object and one of them + // accesses is accessing the entire object, then the accesses must + // overlap in some way. + if (TD && O1 == O2) + if ((V1Size != UnknownSize && isObjectSize(O1, V1Size, *TD)) || + (V2Size != UnknownSize && isObjectSize(O2, V2Size, *TD))) + return PartialAlias; + return AliasAnalysis::alias(Location(V1, V1Size, V1TBAAInfo), Location(V2, V2Size, V2TBAAInfo)); } |