summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Analysis/AliasAnalysis.cpp40
-rw-r--r--llvm/lib/Analysis/BasicAliasAnalysis.cpp220
-rw-r--r--llvm/lib/Analysis/NoAliasAnalysis.cpp8
3 files changed, 126 insertions, 142 deletions
diff --git a/llvm/lib/Analysis/AliasAnalysis.cpp b/llvm/lib/Analysis/AliasAnalysis.cpp
index 5cde979ae1f..57237e59e82 100644
--- a/llvm/lib/Analysis/AliasAnalysis.cpp
+++ b/llvm/lib/Analysis/AliasAnalysis.cpp
@@ -60,13 +60,6 @@ bool AliasAnalysis::pointsToConstantMemory(const Location &Loc,
return AA->pointsToConstantMemory(Loc, OrLocal);
}
-AliasAnalysis::Location
-AliasAnalysis::getArgLocation(ImmutableCallSite CS, unsigned ArgIdx,
- AliasAnalysis::ModRefResult &Mask) {
- assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
- return AA->getArgLocation(CS, ArgIdx, Mask);
-}
-
void AliasAnalysis::deleteValue(Value *V) {
assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
AA->deleteValue(V);
@@ -98,26 +91,22 @@ AliasAnalysis::getModRefInfo(ImmutableCallSite CS,
if (onlyAccessesArgPointees(MRB)) {
bool doesAlias = false;
- ModRefResult AllArgsMask = NoModRef;
if (doesAccessArgPointees(MRB)) {
+ MDNode *CSTag = CS.getInstruction()->getMetadata(LLVMContext::MD_tbaa);
for (ImmutableCallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end();
AI != AE; ++AI) {
const Value *Arg = *AI;
if (!Arg->getType()->isPointerTy())
continue;
- ModRefResult ArgMask;
- Location CSLoc =
- getArgLocation(CS, (unsigned) std::distance(CS.arg_begin(), AI),
- ArgMask);
+ Location CSLoc(Arg, UnknownSize, CSTag);
if (!isNoAlias(CSLoc, Loc)) {
doesAlias = true;
- AllArgsMask = ModRefResult(AllArgsMask | ArgMask);
+ break;
}
}
}
if (!doesAlias)
return NoModRef;
- Mask = ModRefResult(Mask & AllArgsMask);
}
// If Loc is a constant memory location, the call definitely could not
@@ -161,23 +150,14 @@ AliasAnalysis::getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2) {
if (onlyAccessesArgPointees(CS2B)) {
AliasAnalysis::ModRefResult R = NoModRef;
if (doesAccessArgPointees(CS2B)) {
+ MDNode *CS2Tag = CS2.getInstruction()->getMetadata(LLVMContext::MD_tbaa);
for (ImmutableCallSite::arg_iterator
I = CS2.arg_begin(), E = CS2.arg_end(); I != E; ++I) {
const Value *Arg = *I;
if (!Arg->getType()->isPointerTy())
continue;
- ModRefResult ArgMask;
- Location CS2Loc =
- getArgLocation(CS2, (unsigned) std::distance(CS2.arg_begin(), I),
- ArgMask);
- // ArgMask indicates what CS2 might do to CS2Loc, and the dependence of
- // CS1 on that location is the inverse.
- if (ArgMask == Mod)
- ArgMask = ModRef;
- else if (ArgMask == Ref)
- ArgMask = Mod;
-
- R = ModRefResult((R | (getModRefInfo(CS1, CS2Loc) & ArgMask)) & Mask);
+ Location CS2Loc(Arg, UnknownSize, CS2Tag);
+ R = ModRefResult((R | getModRefInfo(CS1, CS2Loc)) & Mask);
if (R == Mask)
break;
}
@@ -190,16 +170,14 @@ AliasAnalysis::getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2) {
if (onlyAccessesArgPointees(CS1B)) {
AliasAnalysis::ModRefResult R = NoModRef;
if (doesAccessArgPointees(CS1B)) {
+ MDNode *CS1Tag = CS1.getInstruction()->getMetadata(LLVMContext::MD_tbaa);
for (ImmutableCallSite::arg_iterator
I = CS1.arg_begin(), E = CS1.arg_end(); I != E; ++I) {
const Value *Arg = *I;
if (!Arg->getType()->isPointerTy())
continue;
- ModRefResult ArgMask;
- Location CS1Loc =
- getArgLocation(CS1, (unsigned) std::distance(CS1.arg_begin(), I),
- ArgMask);
- if ((getModRefInfo(CS2, CS1Loc) & ArgMask) != NoModRef) {
+ Location CS1Loc(Arg, UnknownSize, CS1Tag);
+ if (getModRefInfo(CS2, CS1Loc) != NoModRef) {
R = Mask;
break;
}
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index c50dd4a691a..fe90b84533d 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -490,10 +490,6 @@ namespace {
/// global) or not.
bool pointsToConstantMemory(const Location &Loc, bool OrLocal) override;
- /// Get the location associated with a pointer argument of a callsite.
- Location getArgLocation(ImmutableCallSite CS, unsigned ArgIdx,
- ModRefResult &Mask) override;
-
/// getModRefBehavior - Return the behavior when calling the given
/// call site.
ModRefBehavior getModRefBehavior(ImmutableCallSite CS) override;
@@ -657,21 +653,6 @@ BasicAliasAnalysis::pointsToConstantMemory(const Location &Loc, bool OrLocal) {
return Worklist.empty();
}
-static bool isMemsetPattern16(const Function *MS,
- const TargetLibraryInfo &TLI) {
- if (TLI.has(LibFunc::memset_pattern16) &&
- MS->getName() == "memset_pattern16") {
- FunctionType *MemsetType = MS->getFunctionType();
- if (!MemsetType->isVarArg() && MemsetType->getNumParams() == 3 &&
- isa<PointerType>(MemsetType->getParamType(0)) &&
- isa<PointerType>(MemsetType->getParamType(1)) &&
- isa<IntegerType>(MemsetType->getParamType(2)))
- return true;
- }
-
- return false;
-}
-
/// getModRefBehavior - Return the behavior when calling the given call site.
AliasAnalysis::ModRefBehavior
BasicAliasAnalysis::getModRefBehavior(ImmutableCallSite CS) {
@@ -711,93 +692,10 @@ BasicAliasAnalysis::getModRefBehavior(const Function *F) {
if (F->onlyReadsMemory())
Min = OnlyReadsMemory;
- const TargetLibraryInfo &TLI = getAnalysis<TargetLibraryInfo>();
- if (isMemsetPattern16(F, TLI))
- Min = OnlyAccessesArgumentPointees;
-
// Otherwise be conservative.
return ModRefBehavior(AliasAnalysis::getModRefBehavior(F) & Min);
}
-AliasAnalysis::Location
-BasicAliasAnalysis::getArgLocation(ImmutableCallSite CS, unsigned ArgIdx,
- ModRefResult &Mask) {
- Location Loc = AliasAnalysis::getArgLocation(CS, ArgIdx, Mask);
- const TargetLibraryInfo &TLI = getAnalysis<TargetLibraryInfo>();
- const IntrinsicInst *II = dyn_cast<IntrinsicInst>(CS.getInstruction());
- if (II != nullptr)
- switch (II->getIntrinsicID()) {
- default: break;
- case Intrinsic::memset:
- case Intrinsic::memcpy:
- case Intrinsic::memmove: {
- assert((ArgIdx == 0 || ArgIdx == 1) &&
- "Invalid argument index for memory intrinsic");
- if (ConstantInt *LenCI = dyn_cast<ConstantInt>(II->getArgOperand(2)))
- Loc.Size = LenCI->getZExtValue();
- assert(Loc.Ptr == II->getArgOperand(ArgIdx) &&
- "Memory intrinsic location pointer not argument?");
- Mask = ArgIdx ? Ref : Mod;
- break;
- }
- case Intrinsic::lifetime_start:
- case Intrinsic::lifetime_end:
- case Intrinsic::invariant_start: {
- assert(ArgIdx == 1 && "Invalid argument index");
- assert(Loc.Ptr == II->getArgOperand(ArgIdx) &&
- "Intrinsic location pointer not argument?");
- Loc.Size = cast<ConstantInt>(II->getArgOperand(0))->getZExtValue();
- break;
- }
- case Intrinsic::invariant_end: {
- assert(ArgIdx == 2 && "Invalid argument index");
- assert(Loc.Ptr == II->getArgOperand(ArgIdx) &&
- "Intrinsic location pointer not argument?");
- Loc.Size = cast<ConstantInt>(II->getArgOperand(1))->getZExtValue();
- break;
- }
- case Intrinsic::arm_neon_vld1: {
- assert(ArgIdx == 0 && "Invalid argument index");
- assert(Loc.Ptr == II->getArgOperand(ArgIdx) &&
- "Intrinsic location pointer not argument?");
- // LLVM's vld1 and vst1 intrinsics currently only support a single
- // vector register.
- if (DL)
- Loc.Size = DL->getTypeStoreSize(II->getType());
- break;
- }
- case Intrinsic::arm_neon_vst1: {
- assert(ArgIdx == 0 && "Invalid argument index");
- assert(Loc.Ptr == II->getArgOperand(ArgIdx) &&
- "Intrinsic location pointer not argument?");
- if (DL)
- Loc.Size = DL->getTypeStoreSize(II->getArgOperand(1)->getType());
- break;
- }
- }
-
- // We can bound the aliasing properties of memset_pattern16 just as we can
- // for memcpy/memset. This is particularly important because the
- // LoopIdiomRecognizer likes to turn loops into calls to memset_pattern16
- // whenever possible.
- else if (CS.getCalledFunction() &&
- isMemsetPattern16(CS.getCalledFunction(), TLI)) {
- assert((ArgIdx == 0 || ArgIdx == 1) &&
- "Invalid argument index for memset_pattern16");
- if (ArgIdx == 1)
- Loc.Size = 16;
- else if (const ConstantInt *LenCI =
- dyn_cast<ConstantInt>(CS.getArgument(2)))
- Loc.Size = LenCI->getZExtValue();
- assert(Loc.Ptr == CS.getArgument(ArgIdx) &&
- "memset_pattern16 location pointer not argument?");
- Mask = ArgIdx ? Ref : Mod;
- }
- // FIXME: Handle memset_pattern4 and memset_pattern8 also.
-
- return Loc;
-}
-
/// getModRefInfo - Check to see if the specified callsite can clobber the
/// specified memory object. Since we only look at local properties of this
/// function, we really can't say much about this query. We do, however, use
@@ -850,8 +748,124 @@ BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS,
return NoModRef;
}
+ const TargetLibraryInfo &TLI = getAnalysis<TargetLibraryInfo>();
+ ModRefResult Min = ModRef;
+
+ // Finally, handle specific knowledge of intrinsics.
+ const IntrinsicInst *II = dyn_cast<IntrinsicInst>(CS.getInstruction());
+ if (II != nullptr)
+ switch (II->getIntrinsicID()) {
+ default: break;
+ case Intrinsic::memcpy:
+ case Intrinsic::memmove: {
+ uint64_t Len = UnknownSize;
+ if (ConstantInt *LenCI = dyn_cast<ConstantInt>(II->getArgOperand(2)))
+ Len = LenCI->getZExtValue();
+ Value *Dest = II->getArgOperand(0);
+ Value *Src = II->getArgOperand(1);
+ // If it can't overlap the source dest, then it doesn't modref the loc.
+ if (isNoAlias(Location(Dest, Len), Loc)) {
+ if (isNoAlias(Location(Src, Len), Loc))
+ return NoModRef;
+ // If it can't overlap the dest, then worst case it reads the loc.
+ Min = Ref;
+ } else if (isNoAlias(Location(Src, Len), Loc)) {
+ // If it can't overlap the source, then worst case it mutates the loc.
+ Min = Mod;
+ }
+ break;
+ }
+ case Intrinsic::memset:
+ // Since memset is 'accesses arguments' only, the AliasAnalysis base class
+ // will handle it for the variable length case.
+ if (ConstantInt *LenCI = dyn_cast<ConstantInt>(II->getArgOperand(2))) {
+ uint64_t Len = LenCI->getZExtValue();
+ Value *Dest = II->getArgOperand(0);
+ if (isNoAlias(Location(Dest, Len), Loc))
+ return NoModRef;
+ }
+ // We know that memset doesn't load anything.
+ Min = Mod;
+ break;
+ case Intrinsic::lifetime_start:
+ case Intrinsic::lifetime_end:
+ case Intrinsic::invariant_start: {
+ uint64_t PtrSize =
+ cast<ConstantInt>(II->getArgOperand(0))->getZExtValue();
+ if (isNoAlias(Location(II->getArgOperand(1),
+ PtrSize,
+ II->getMetadata(LLVMContext::MD_tbaa)),
+ Loc))
+ return NoModRef;
+ break;
+ }
+ case Intrinsic::invariant_end: {
+ uint64_t PtrSize =
+ cast<ConstantInt>(II->getArgOperand(1))->getZExtValue();
+ if (isNoAlias(Location(II->getArgOperand(2),
+ PtrSize,
+ II->getMetadata(LLVMContext::MD_tbaa)),
+ Loc))
+ return NoModRef;
+ break;
+ }
+ case Intrinsic::arm_neon_vld1: {
+ // LLVM's vld1 and vst1 intrinsics currently only support a single
+ // vector register.
+ uint64_t Size =
+ DL ? DL->getTypeStoreSize(II->getType()) : UnknownSize;
+ if (isNoAlias(Location(II->getArgOperand(0), Size,
+ II->getMetadata(LLVMContext::MD_tbaa)),
+ Loc))
+ return NoModRef;
+ break;
+ }
+ case Intrinsic::arm_neon_vst1: {
+ uint64_t Size =
+ DL ? DL->getTypeStoreSize(II->getArgOperand(1)->getType()) : UnknownSize;
+ if (isNoAlias(Location(II->getArgOperand(0), Size,
+ II->getMetadata(LLVMContext::MD_tbaa)),
+ Loc))
+ return NoModRef;
+ break;
+ }
+ }
+
+ // We can bound the aliasing properties of memset_pattern16 just as we can
+ // for memcpy/memset. This is particularly important because the
+ // LoopIdiomRecognizer likes to turn loops into calls to memset_pattern16
+ // whenever possible.
+ else if (TLI.has(LibFunc::memset_pattern16) &&
+ CS.getCalledFunction() &&
+ CS.getCalledFunction()->getName() == "memset_pattern16") {
+ const Function *MS = CS.getCalledFunction();
+ FunctionType *MemsetType = MS->getFunctionType();
+ if (!MemsetType->isVarArg() && MemsetType->getNumParams() == 3 &&
+ isa<PointerType>(MemsetType->getParamType(0)) &&
+ isa<PointerType>(MemsetType->getParamType(1)) &&
+ isa<IntegerType>(MemsetType->getParamType(2))) {
+ uint64_t Len = UnknownSize;
+ if (const ConstantInt *LenCI = dyn_cast<ConstantInt>(CS.getArgument(2)))
+ Len = LenCI->getZExtValue();
+ const Value *Dest = CS.getArgument(0);
+ const Value *Src = CS.getArgument(1);
+ // If it can't overlap the source dest, then it doesn't modref the loc.
+ if (isNoAlias(Location(Dest, Len), Loc)) {
+ // Always reads 16 bytes of the source.
+ if (isNoAlias(Location(Src, 16), Loc))
+ return NoModRef;
+ // If it can't overlap the dest, then worst case it reads the loc.
+ Min = Ref;
+ // Always reads 16 bytes of the source.
+ } else if (isNoAlias(Location(Src, 16), Loc)) {
+ // If it can't overlap the source, then worst case it mutates the loc.
+ Min = Mod;
+ }
+ }
+ }
+
// The AliasAnalysis base class has some smarts, lets use them.
- return AliasAnalysis::getModRefInfo(CS, Loc);
+ return ModRefResult(AliasAnalysis::getModRefInfo(CS, Loc) & Min);
}
/// aliasGEP - Provide a bunch of ad-hoc rules to disambiguate a GEP instruction
diff --git a/llvm/lib/Analysis/NoAliasAnalysis.cpp b/llvm/lib/Analysis/NoAliasAnalysis.cpp
index 139fa38b8a9..4e11e50e289 100644
--- a/llvm/lib/Analysis/NoAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/NoAliasAnalysis.cpp
@@ -15,7 +15,6 @@
#include "llvm/Analysis/Passes.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/LLVMContext.h"
#include "llvm/Pass.h"
using namespace llvm;
@@ -54,13 +53,6 @@ namespace {
bool pointsToConstantMemory(const Location &Loc, bool OrLocal) override {
return false;
}
- Location getArgLocation(ImmutableCallSite CS, unsigned ArgIdx,
- ModRefResult &Mask) override {
- Mask = ModRef;
- return Location(CS.getArgument(ArgIdx), UnknownSize,
- CS.getInstruction()->getMetadata(LLVMContext::MD_tbaa));
- }
-
ModRefResult getModRefInfo(ImmutableCallSite CS,
const Location &Loc) override {
return ModRef;
OpenPOWER on IntegriCloud