Index: include/llvm/Analysis/AliasAnalysis.h =================================================================== --- include/llvm/Analysis/AliasAnalysis.h +++ include/llvm/Analysis/AliasAnalysis.h @@ -91,6 +91,16 @@ MustAlias, }; +enum BuffUseResult { + /// the two locations cant use the same memory block + NotSameBuff = 0, + /// The two locations may or may not use the same memory block. This is the + /// least precise result. + MayUseSameBuff, + /// The two locations precisely use the same memory block. + MustUseSameBuff + +}; /// Flags indicating whether a memory access modifies or references memory. /// /// This is no access at all, a modification, a reference, or both @@ -374,6 +384,16 @@ return pointsToConstantMemory(MemoryLocation(P), OrLocal); } + /// Checks whether the given locations points to the same buffer. + bool ModRefSameBuffer(const MemoryLocation &LocA, int64_t ptr1Offset, + const MemoryLocation &LocB, int64_t ptr2Offset); + + /// A convenience wrapper around the \c ModRefSameBuffer helper interface. + bool ModRefSameBuffer(const Value *V1, int64_t ptr1Offset, const Value *V2, + int64_t ptr2Offset) { + return ModRefSameBuffer(MemoryLocation(V1), ptr1Offset, MemoryLocation(V2), + ptr2Offset); + } /// @} //===--------------------------------------------------------------------===// /// \name Simple mod/ref information @@ -391,6 +411,17 @@ /// Return the behavior when calling the given function. FunctionModRefBehavior getModRefBehavior(const Function *F); + /// Return the Distance between 2 address. + Optional getAddressesDistance(const MemoryLocation &LocA, + int64_t ptr1Offset, + const MemoryLocation &LocB, + int64_t ptr2Offset); + + Optional getAddressesDistance(const Value *V1, int64_t ptr1Offset, + const Value *V2, int64_t ptr2Offset) { + return getAddressesDistance(MemoryLocation(V1), ptr1Offset, + MemoryLocation(V2), ptr2Offset); + } /// Checks if the specified call is known to never read or write memory. /// @@ -758,6 +789,10 @@ virtual bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal) = 0; + /// Checks whether the given locations points to the same buffer. + virtual bool ModRefSameBuffer(const MemoryLocation &LocA, int64_t ptr1Offset, + const MemoryLocation &LocB, + int64_t ptr2Offset) = 0; /// @} //===--------------------------------------------------------------------===// /// \name Simple mod/ref information @@ -788,6 +823,11 @@ virtual ModRefInfo getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2) = 0; + /// Return the Distance between 2 address. + virtual Optional getAddressesDistance(const MemoryLocation &LocA, + int64_t ptr1Offset, + const MemoryLocation &LocB, + int64_t ptr2Offset) = 0; /// @} }; @@ -817,6 +857,11 @@ bool OrLocal) override { return Result.pointsToConstantMemory(Loc, OrLocal); } + bool ModRefSameBuffer(const MemoryLocation &LocA, int64_t ptr1Offset, + const MemoryLocation &LocB, + int64_t ptr2Offset) override { + return Result.ModRefSameBuffer(LocA, ptr1Offset, LocB, ptr2Offset); + } ModRefInfo getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx) override { return Result.getArgModRefInfo(CS, ArgIdx); @@ -839,6 +884,12 @@ ImmutableCallSite CS2) override { return Result.getModRefInfo(CS1, CS2); } + Optional getAddressesDistance(const MemoryLocation &LocA, + int64_t ptr1Offset, + const MemoryLocation &LocB, + int64_t ptr2Offset) override { + return Result.getAddressesDistance(LocA, ptr1Offset, LocB, ptr2Offset); + } }; /// A CRTP-driven "mixin" base class to help implement the function alias @@ -892,6 +943,12 @@ : CurrentResult.pointsToConstantMemory(Loc, OrLocal); } + bool ModRefSameBuffer(const MemoryLocation &LocA, int64_t ptr1Offset, + const MemoryLocation &LocB, int64_t ptr2Offset) { + return AAR ? AAR->ModRefSameBuffer(LocA, ptr1Offset, LocB, ptr2Offset) + : CurrentResult.ModRefSameBuffer(LocA, ptr1Offset, LocB, + ptr2Offset); + } ModRefInfo getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx) { return AAR ? AAR->getArgModRefInfo(CS, ArgIdx) : CurrentResult.getArgModRefInfo(CS, ArgIdx); } @@ -912,6 +969,14 @@ ModRefInfo getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2) { return AAR ? AAR->getModRefInfo(CS1, CS2) : CurrentResult.getModRefInfo(CS1, CS2); } + Optional getAddressesDistance(const MemoryLocation &LocA, + int64_t ptr1Offset, + const MemoryLocation &LocB, + int64_t ptr2Offset) { + return AAR ? AAR->getAddressesDistance(LocA, ptr1Offset, LocB, ptr2Offset) + : CurrentResult.getAddressesDistance(LocA, ptr1Offset, LocB, + ptr2Offset); + } }; explicit AAResultBase() = default; @@ -941,6 +1006,10 @@ bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal) { return false; } + bool ModRefSameBuffer(const MemoryLocation &LocA, int64_t ptr1Offset, + const MemoryLocation &LocB, int64_t ptr2Offset) { + return false; + } ModRefInfo getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx) { return ModRefInfo::ModRef; @@ -961,6 +1030,12 @@ ModRefInfo getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2) { return ModRefInfo::ModRef; } + Optional getAddressesDistance(const MemoryLocation &LocA, + int64_t ptr1Offset, + const MemoryLocation &LocB, + int64_t ptr2Offset) { + return None; + } }; /// Return true if this pointer is returned by a noalias function. Index: lib/Analysis/AliasAnalysis.cpp =================================================================== --- lib/Analysis/AliasAnalysis.cpp +++ lib/Analysis/AliasAnalysis.cpp @@ -118,6 +118,29 @@ return false; } +bool AAResults::ModRefSameBuffer(const MemoryLocation &LocA, int64_t ptr1Offset, + const MemoryLocation &LocB, + int64_t ptr2Offset) { + for (const auto &AA : AAs) + if (AA->ModRefSameBuffer(LocA, ptr1Offset, LocB, ptr2Offset)) + return true; + + return false; +} + +Optional AAResults::getAddressesDistance(const MemoryLocation &LocA, + int64_t ptr1Offset, + const MemoryLocation &LocB, + int64_t ptr2Offset) { + for (const auto &AA : AAs) { + Optional res = + AA->getAddressesDistance(LocA, ptr1Offset, LocB, ptr2Offset); + if (res != None) + return res; + } + + return None; +} ModRefInfo AAResults::getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx) { ModRefInfo Result = ModRefInfo::ModRef;