aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2011-01-18 21:16:06 +0000
committerDan Gohman <gohman@apple.com>2011-01-18 21:16:06 +0000
commit615da1a9bcca05de06fab5f48ee9110267312974 (patch)
treea8e2dddced58cfc75aaeb446556195e678b8b50b /lib/Analysis
parentb5fa9333431673aac2ced8dea80152349a85cf6f (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.cpp47
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));
}