diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Analysis/AliasAnalysis.cpp | 40 | ||||
-rw-r--r-- | llvm/lib/Analysis/BasicAliasAnalysis.cpp | 220 | ||||
-rw-r--r-- | llvm/lib/Analysis/NoAliasAnalysis.cpp | 8 |
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; |