diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2023-04-14 21:41:27 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-06-22 18:20:56 +0000 |
commit | bdd1243df58e60e85101c09001d9812a789b6bc4 (patch) | |
tree | a1ce621c7301dd47ba2ddc3b8eaa63b441389481 /contrib/llvm-project/llvm/lib/Analysis/AliasAnalysis.cpp | |
parent | 781624ca2d054430052c828ba8d2c2eaf2d733e7 (diff) | |
parent | e3b557809604d036af6e00c60f012c2025b59a5e (diff) |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Analysis/AliasAnalysis.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Analysis/AliasAnalysis.cpp | 417 |
1 files changed, 159 insertions, 258 deletions
diff --git a/contrib/llvm-project/llvm/lib/Analysis/AliasAnalysis.cpp b/contrib/llvm-project/llvm/lib/Analysis/AliasAnalysis.cpp index e249c38ecd34..9e24f6b87bdb 100644 --- a/contrib/llvm-project/llvm/lib/Analysis/AliasAnalysis.cpp +++ b/contrib/llvm-project/llvm/lib/Analysis/AliasAnalysis.cpp @@ -26,8 +26,6 @@ #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/BasicAliasAnalysis.h" -#include "llvm/Analysis/CFLAndersAliasAnalysis.h" -#include "llvm/Analysis/CFLSteensAliasAnalysis.h" #include "llvm/Analysis/CaptureTracking.h" #include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/MemoryLocation.h" @@ -76,21 +74,9 @@ static const bool EnableAATrace = false; #endif AAResults::AAResults(AAResults &&Arg) - : TLI(Arg.TLI), AAs(std::move(Arg.AAs)), AADeps(std::move(Arg.AADeps)) { - for (auto &AA : AAs) - AA->setAAResults(this); -} + : TLI(Arg.TLI), AAs(std::move(Arg.AAs)), AADeps(std::move(Arg.AADeps)) {} -AAResults::~AAResults() { -// FIXME; It would be nice to at least clear out the pointers back to this -// aggregation here, but we end up with non-nesting lifetimes in the legacy -// pass manager that prevent this from working. In the legacy pass manager -// we'll end up with dangling references here in some cases. -#if 0 - for (auto &AA : AAs) - AA->setAAResults(nullptr); -#endif -} +AAResults::~AAResults() {} bool AAResults::invalidate(Function &F, const PreservedAnalyses &PA, FunctionAnalysisManager::Invalidator &Inv) { @@ -118,12 +104,13 @@ bool AAResults::invalidate(Function &F, const PreservedAnalyses &PA, AliasResult AAResults::alias(const MemoryLocation &LocA, const MemoryLocation &LocB) { - SimpleAAQueryInfo AAQIP; - return alias(LocA, LocB, AAQIP); + SimpleAAQueryInfo AAQIP(*this); + return alias(LocA, LocB, AAQIP, nullptr); } AliasResult AAResults::alias(const MemoryLocation &LocA, - const MemoryLocation &LocB, AAQueryInfo &AAQI) { + const MemoryLocation &LocB, AAQueryInfo &AAQI, + const Instruction *CtxI) { AliasResult Result = AliasResult::MayAlias; if (EnableAATrace) { @@ -135,7 +122,7 @@ AliasResult AAResults::alias(const MemoryLocation &LocA, AAQI.Depth++; for (const auto &AA : AAs) { - Result = AA->alias(LocA, LocB, AAQI); + Result = AA->alias(LocA, LocB, AAQI, CtxI); if (Result != AliasResult::MayAlias) break; } @@ -159,26 +146,32 @@ AliasResult AAResults::alias(const MemoryLocation &LocA, return Result; } -bool AAResults::pointsToConstantMemory(const MemoryLocation &Loc, - bool OrLocal) { - SimpleAAQueryInfo AAQIP; - return pointsToConstantMemory(Loc, AAQIP, OrLocal); +ModRefInfo AAResults::getModRefInfoMask(const MemoryLocation &Loc, + bool IgnoreLocals) { + SimpleAAQueryInfo AAQIP(*this); + return getModRefInfoMask(Loc, AAQIP, IgnoreLocals); } -bool AAResults::pointsToConstantMemory(const MemoryLocation &Loc, - AAQueryInfo &AAQI, bool OrLocal) { - for (const auto &AA : AAs) - if (AA->pointsToConstantMemory(Loc, AAQI, OrLocal)) - return true; +ModRefInfo AAResults::getModRefInfoMask(const MemoryLocation &Loc, + AAQueryInfo &AAQI, bool IgnoreLocals) { + ModRefInfo Result = ModRefInfo::ModRef; - return false; + for (const auto &AA : AAs) { + Result &= AA->getModRefInfoMask(Loc, AAQI, IgnoreLocals); + + // Early-exit the moment we reach the bottom of the lattice. + if (isNoModRef(Result)) + return ModRefInfo::NoModRef; + } + + return Result; } ModRefInfo AAResults::getArgModRefInfo(const CallBase *Call, unsigned ArgIdx) { ModRefInfo Result = ModRefInfo::ModRef; for (const auto &AA : AAs) { - Result = intersectModRef(Result, AA->getArgModRefInfo(Call, ArgIdx)); + Result &= AA->getArgModRefInfo(Call, ArgIdx); // Early-exit the moment we reach the bottom of the lattice. if (isNoModRef(Result)) @@ -188,12 +181,13 @@ ModRefInfo AAResults::getArgModRefInfo(const CallBase *Call, unsigned ArgIdx) { return Result; } -ModRefInfo AAResults::getModRefInfo(Instruction *I, const CallBase *Call2) { - SimpleAAQueryInfo AAQIP; +ModRefInfo AAResults::getModRefInfo(const Instruction *I, + const CallBase *Call2) { + SimpleAAQueryInfo AAQIP(*this); return getModRefInfo(I, Call2, AAQIP); } -ModRefInfo AAResults::getModRefInfo(Instruction *I, const CallBase *Call2, +ModRefInfo AAResults::getModRefInfo(const Instruction *I, const CallBase *Call2, AAQueryInfo &AAQI) { // We may have two calls. if (const auto *Call1 = dyn_cast<CallBase>(I)) { @@ -210,23 +204,17 @@ ModRefInfo AAResults::getModRefInfo(Instruction *I, const CallBase *Call2, const MemoryLocation DefLoc = MemoryLocation::get(I); ModRefInfo MR = getModRefInfo(Call2, DefLoc, AAQI); if (isModOrRefSet(MR)) - return setModAndRef(MR); + return ModRefInfo::ModRef; return ModRefInfo::NoModRef; } ModRefInfo AAResults::getModRefInfo(const CallBase *Call, - const MemoryLocation &Loc) { - SimpleAAQueryInfo AAQIP; - return getModRefInfo(Call, Loc, AAQIP); -} - -ModRefInfo AAResults::getModRefInfo(const CallBase *Call, const MemoryLocation &Loc, AAQueryInfo &AAQI) { ModRefInfo Result = ModRefInfo::ModRef; for (const auto &AA : AAs) { - Result = intersectModRef(Result, AA->getModRefInfo(Call, Loc, AAQI)); + Result &= AA->getModRefInfo(Call, Loc, AAQI); // Early-exit the moment we reach the bottom of the lattice. if (isNoModRef(Result)) @@ -235,64 +223,51 @@ ModRefInfo AAResults::getModRefInfo(const CallBase *Call, // Try to refine the mod-ref info further using other API entry points to the // aggregate set of AA results. - auto MRB = getModRefBehavior(Call); - if (onlyAccessesInaccessibleMem(MRB)) - return ModRefInfo::NoModRef; - if (onlyReadsMemory(MRB)) - Result = clearMod(Result); - else if (onlyWritesMemory(MRB)) - Result = clearRef(Result); + // We can completely ignore inaccessible memory here, because MemoryLocations + // can only reference accessible memory. + auto ME = getMemoryEffects(Call, AAQI) + .getWithoutLoc(MemoryEffects::InaccessibleMem); + if (ME.doesNotAccessMemory()) + return ModRefInfo::NoModRef; - if (onlyAccessesArgPointees(MRB) || onlyAccessesInaccessibleOrArgMem(MRB)) { - bool IsMustAlias = true; + ModRefInfo ArgMR = ME.getModRef(MemoryEffects::ArgMem); + ModRefInfo OtherMR = ME.getWithoutLoc(MemoryEffects::ArgMem).getModRef(); + if ((ArgMR | OtherMR) != OtherMR) { + // Refine the modref info for argument memory. We only bother to do this + // if ArgMR is not a subset of OtherMR, otherwise this won't have an impact + // on the final result. ModRefInfo AllArgsMask = ModRefInfo::NoModRef; - if (doesAccessArgPointees(MRB)) { - for (const auto &I : llvm::enumerate(Call->args())) { - const Value *Arg = I.value(); - if (!Arg->getType()->isPointerTy()) - continue; - unsigned ArgIdx = I.index(); - MemoryLocation ArgLoc = - MemoryLocation::getForArgument(Call, ArgIdx, TLI); - AliasResult ArgAlias = alias(ArgLoc, Loc, AAQI); - if (ArgAlias != AliasResult::NoAlias) { - ModRefInfo ArgMask = getArgModRefInfo(Call, ArgIdx); - AllArgsMask = unionModRef(AllArgsMask, ArgMask); - } - // Conservatively clear IsMustAlias unless only MustAlias is found. - IsMustAlias &= (ArgAlias == AliasResult::MustAlias); - } + for (const auto &I : llvm::enumerate(Call->args())) { + const Value *Arg = I.value(); + if (!Arg->getType()->isPointerTy()) + continue; + unsigned ArgIdx = I.index(); + MemoryLocation ArgLoc = MemoryLocation::getForArgument(Call, ArgIdx, TLI); + AliasResult ArgAlias = alias(ArgLoc, Loc, AAQI, Call); + if (ArgAlias != AliasResult::NoAlias) + AllArgsMask |= getArgModRefInfo(Call, ArgIdx); } - // Return NoModRef if no alias found with any argument. - if (isNoModRef(AllArgsMask)) - return ModRefInfo::NoModRef; - // Logical & between other AA analyses and argument analysis. - Result = intersectModRef(Result, AllArgsMask); - // If only MustAlias found above, set Must bit. - Result = IsMustAlias ? setMust(Result) : clearMust(Result); + ArgMR &= AllArgsMask; } - // If Loc is a constant memory location, the call definitely could not + Result &= ArgMR | OtherMR; + + // Apply the ModRef mask. This ensures that if Loc is a constant memory + // location, we take into account the fact that the call definitely could not // modify the memory location. - if (isModSet(Result) && pointsToConstantMemory(Loc, AAQI, /*OrLocal*/ false)) - Result = clearMod(Result); + if (!isNoModRef(Result)) + Result &= getModRefInfoMask(Loc); return Result; } ModRefInfo AAResults::getModRefInfo(const CallBase *Call1, - const CallBase *Call2) { - SimpleAAQueryInfo AAQIP; - return getModRefInfo(Call1, Call2, AAQIP); -} - -ModRefInfo AAResults::getModRefInfo(const CallBase *Call1, const CallBase *Call2, AAQueryInfo &AAQI) { ModRefInfo Result = ModRefInfo::ModRef; for (const auto &AA : AAs) { - Result = intersectModRef(Result, AA->getModRefInfo(Call1, Call2, AAQI)); + Result &= AA->getModRefInfo(Call1, Call2, AAQI); // Early-exit the moment we reach the bottom of the lattice. if (isNoModRef(Result)) @@ -303,33 +278,32 @@ ModRefInfo AAResults::getModRefInfo(const CallBase *Call1, // aggregate set of AA results. // If Call1 or Call2 are readnone, they don't interact. - auto Call1B = getModRefBehavior(Call1); - if (Call1B == FMRB_DoesNotAccessMemory) + auto Call1B = getMemoryEffects(Call1, AAQI); + if (Call1B.doesNotAccessMemory()) return ModRefInfo::NoModRef; - auto Call2B = getModRefBehavior(Call2); - if (Call2B == FMRB_DoesNotAccessMemory) + auto Call2B = getMemoryEffects(Call2, AAQI); + if (Call2B.doesNotAccessMemory()) return ModRefInfo::NoModRef; // If they both only read from memory, there is no dependence. - if (onlyReadsMemory(Call1B) && onlyReadsMemory(Call2B)) + if (Call1B.onlyReadsMemory() && Call2B.onlyReadsMemory()) return ModRefInfo::NoModRef; // If Call1 only reads memory, the only dependence on Call2 can be // from Call1 reading memory written by Call2. - if (onlyReadsMemory(Call1B)) - Result = clearMod(Result); - else if (onlyWritesMemory(Call1B)) - Result = clearRef(Result); + if (Call1B.onlyReadsMemory()) + Result &= ModRefInfo::Ref; + else if (Call1B.onlyWritesMemory()) + Result &= ModRefInfo::Mod; // If Call2 only access memory through arguments, accumulate the mod/ref // information from Call1's references to the memory referenced by // Call2's arguments. - if (onlyAccessesArgPointees(Call2B)) { - if (!doesAccessArgPointees(Call2B)) + if (Call2B.onlyAccessesArgPointees()) { + if (!Call2B.doesAccessArgPointees()) return ModRefInfo::NoModRef; ModRefInfo R = ModRefInfo::NoModRef; - bool IsMustAlias = true; for (auto I = Call2->arg_begin(), E = Call2->arg_end(); I != E; ++I) { const Value *Arg = *I; if (!Arg->getType()->isPointerTy()) @@ -352,35 +326,22 @@ ModRefInfo AAResults::getModRefInfo(const CallBase *Call1, // ModRefC1 indicates what Call1 might do to Call2ArgLoc, and we use // above ArgMask to update dependence info. - ModRefInfo ModRefC1 = getModRefInfo(Call1, Call2ArgLoc, AAQI); - ArgMask = intersectModRef(ArgMask, ModRefC1); - - // Conservatively clear IsMustAlias unless only MustAlias is found. - IsMustAlias &= isMustSet(ModRefC1); + ArgMask &= getModRefInfo(Call1, Call2ArgLoc, AAQI); - R = intersectModRef(unionModRef(R, ArgMask), Result); - if (R == Result) { - // On early exit, not all args were checked, cannot set Must. - if (I + 1 != E) - IsMustAlias = false; + R = (R | ArgMask) & Result; + if (R == Result) break; - } } - if (isNoModRef(R)) - return ModRefInfo::NoModRef; - - // If MustAlias found above, set Must bit. - return IsMustAlias ? setMust(R) : clearMust(R); + return R; } // If Call1 only accesses memory through arguments, check if Call2 references // any of the memory referenced by Call1's arguments. If not, return NoModRef. - if (onlyAccessesArgPointees(Call1B)) { - if (!doesAccessArgPointees(Call1B)) + if (Call1B.onlyAccessesArgPointees()) { + if (!Call1B.doesAccessArgPointees()) return ModRefInfo::NoModRef; ModRefInfo R = ModRefInfo::NoModRef; - bool IsMustAlias = true; for (auto I = Call1->arg_begin(), E = Call1->arg_end(); I != E; ++I) { const Value *Arg = *I; if (!Arg->getType()->isPointerTy()) @@ -396,51 +357,46 @@ ModRefInfo AAResults::getModRefInfo(const CallBase *Call1, ModRefInfo ModRefC2 = getModRefInfo(Call2, Call1ArgLoc, AAQI); if ((isModSet(ArgModRefC1) && isModOrRefSet(ModRefC2)) || (isRefSet(ArgModRefC1) && isModSet(ModRefC2))) - R = intersectModRef(unionModRef(R, ArgModRefC1), Result); - - // Conservatively clear IsMustAlias unless only MustAlias is found. - IsMustAlias &= isMustSet(ModRefC2); + R = (R | ArgModRefC1) & Result; - if (R == Result) { - // On early exit, not all args were checked, cannot set Must. - if (I + 1 != E) - IsMustAlias = false; + if (R == Result) break; - } } - if (isNoModRef(R)) - return ModRefInfo::NoModRef; - - // If MustAlias found above, set Must bit. - return IsMustAlias ? setMust(R) : clearMust(R); + return R; } return Result; } -FunctionModRefBehavior AAResults::getModRefBehavior(const CallBase *Call) { - FunctionModRefBehavior Result = FMRB_UnknownModRefBehavior; +MemoryEffects AAResults::getMemoryEffects(const CallBase *Call, + AAQueryInfo &AAQI) { + MemoryEffects Result = MemoryEffects::unknown(); for (const auto &AA : AAs) { - Result = FunctionModRefBehavior(Result & AA->getModRefBehavior(Call)); + Result &= AA->getMemoryEffects(Call, AAQI); // Early-exit the moment we reach the bottom of the lattice. - if (Result == FMRB_DoesNotAccessMemory) + if (Result.doesNotAccessMemory()) return Result; } return Result; } -FunctionModRefBehavior AAResults::getModRefBehavior(const Function *F) { - FunctionModRefBehavior Result = FMRB_UnknownModRefBehavior; +MemoryEffects AAResults::getMemoryEffects(const CallBase *Call) { + SimpleAAQueryInfo AAQI(*this); + return getMemoryEffects(Call, AAQI); +} + +MemoryEffects AAResults::getMemoryEffects(const Function *F) { + MemoryEffects Result = MemoryEffects::unknown(); for (const auto &AA : AAs) { - Result = FunctionModRefBehavior(Result & AA->getModRefBehavior(F)); + Result &= AA->getMemoryEffects(F); // Early-exit the moment we reach the bottom of the lattice. - if (Result == FMRB_DoesNotAccessMemory) + if (Result.doesNotAccessMemory()) return Result; } @@ -467,16 +423,47 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, AliasResult AR) { return OS; } +raw_ostream &llvm::operator<<(raw_ostream &OS, ModRefInfo MR) { + switch (MR) { + case ModRefInfo::NoModRef: + OS << "NoModRef"; + break; + case ModRefInfo::Ref: + OS << "Ref"; + break; + case ModRefInfo::Mod: + OS << "Mod"; + break; + case ModRefInfo::ModRef: + OS << "ModRef"; + break; + } + return OS; +} + +raw_ostream &llvm::operator<<(raw_ostream &OS, MemoryEffects ME) { + for (MemoryEffects::Location Loc : MemoryEffects::locations()) { + switch (Loc) { + case MemoryEffects::ArgMem: + OS << "ArgMem: "; + break; + case MemoryEffects::InaccessibleMem: + OS << "InaccessibleMem: "; + break; + case MemoryEffects::Other: + OS << "Other: "; + break; + } + OS << ME.getModRef(Loc) << ", "; + } + return OS; +} + //===----------------------------------------------------------------------===// // Helper method implementation //===----------------------------------------------------------------------===// ModRefInfo AAResults::getModRefInfo(const LoadInst *L, - const MemoryLocation &Loc) { - SimpleAAQueryInfo AAQIP; - return getModRefInfo(L, Loc, AAQIP); -} -ModRefInfo AAResults::getModRefInfo(const LoadInst *L, const MemoryLocation &Loc, AAQueryInfo &AAQI) { // Be conservative in the face of atomic. @@ -486,22 +473,15 @@ ModRefInfo AAResults::getModRefInfo(const LoadInst *L, // If the load address doesn't alias the given address, it doesn't read // or write the specified memory. if (Loc.Ptr) { - AliasResult AR = alias(MemoryLocation::get(L), Loc, AAQI); + AliasResult AR = alias(MemoryLocation::get(L), Loc, AAQI, L); if (AR == AliasResult::NoAlias) return ModRefInfo::NoModRef; - if (AR == AliasResult::MustAlias) - return ModRefInfo::MustRef; } // Otherwise, a load just reads. return ModRefInfo::Ref; } ModRefInfo AAResults::getModRefInfo(const StoreInst *S, - const MemoryLocation &Loc) { - SimpleAAQueryInfo AAQIP; - return getModRefInfo(S, Loc, AAQIP); -} -ModRefInfo AAResults::getModRefInfo(const StoreInst *S, const MemoryLocation &Loc, AAQueryInfo &AAQI) { // Be conservative in the face of atomic. @@ -509,65 +489,48 @@ ModRefInfo AAResults::getModRefInfo(const StoreInst *S, return ModRefInfo::ModRef; if (Loc.Ptr) { - AliasResult AR = alias(MemoryLocation::get(S), Loc, AAQI); + AliasResult AR = alias(MemoryLocation::get(S), Loc, AAQI, S); // If the store address cannot alias the pointer in question, then the // specified memory cannot be modified by the store. if (AR == AliasResult::NoAlias) return ModRefInfo::NoModRef; - // If the pointer is a pointer to constant memory, then it could not have - // been modified by this store. - if (pointsToConstantMemory(Loc, AAQI)) + // Examine the ModRef mask. If Mod isn't present, then return NoModRef. + // This ensures that if Loc is a constant memory location, we take into + // account the fact that the store definitely could not modify the memory + // location. + if (!isModSet(getModRefInfoMask(Loc))) return ModRefInfo::NoModRef; - - // If the store address aliases the pointer as must alias, set Must. - if (AR == AliasResult::MustAlias) - return ModRefInfo::MustMod; } // Otherwise, a store just writes. return ModRefInfo::Mod; } -ModRefInfo AAResults::getModRefInfo(const FenceInst *S, const MemoryLocation &Loc) { - SimpleAAQueryInfo AAQIP; - return getModRefInfo(S, Loc, AAQIP); -} - ModRefInfo AAResults::getModRefInfo(const FenceInst *S, const MemoryLocation &Loc, AAQueryInfo &AAQI) { - // If we know that the location is a constant memory location, the fence - // cannot modify this location. - if (Loc.Ptr && pointsToConstantMemory(Loc, AAQI)) - return ModRefInfo::Ref; + // All we know about a fence instruction is what we get from the ModRef + // mask: if Loc is a constant memory location, the fence definitely could + // not modify it. + if (Loc.Ptr) + return getModRefInfoMask(Loc); return ModRefInfo::ModRef; } ModRefInfo AAResults::getModRefInfo(const VAArgInst *V, - const MemoryLocation &Loc) { - SimpleAAQueryInfo AAQIP; - return getModRefInfo(V, Loc, AAQIP); -} - -ModRefInfo AAResults::getModRefInfo(const VAArgInst *V, const MemoryLocation &Loc, AAQueryInfo &AAQI) { if (Loc.Ptr) { - AliasResult AR = alias(MemoryLocation::get(V), Loc, AAQI); + AliasResult AR = alias(MemoryLocation::get(V), Loc, AAQI, V); // If the va_arg address cannot alias the pointer in question, then the // specified memory cannot be accessed by the va_arg. if (AR == AliasResult::NoAlias) return ModRefInfo::NoModRef; - // If the pointer is a pointer to constant memory, then it could not have + // If the pointer is a pointer to invariant memory, then it could not have // been modified by this va_arg. - if (pointsToConstantMemory(Loc, AAQI)) - return ModRefInfo::NoModRef; - - // If the va_arg aliases the pointer as must alias, set Must. - if (AR == AliasResult::MustAlias) - return ModRefInfo::MustModRef; + return getModRefInfoMask(Loc, AAQI); } // Otherwise, a va_arg reads and writes. @@ -575,19 +538,12 @@ ModRefInfo AAResults::getModRefInfo(const VAArgInst *V, } ModRefInfo AAResults::getModRefInfo(const CatchPadInst *CatchPad, - const MemoryLocation &Loc) { - SimpleAAQueryInfo AAQIP; - return getModRefInfo(CatchPad, Loc, AAQIP); -} - -ModRefInfo AAResults::getModRefInfo(const CatchPadInst *CatchPad, const MemoryLocation &Loc, AAQueryInfo &AAQI) { if (Loc.Ptr) { - // If the pointer is a pointer to constant memory, + // If the pointer is a pointer to invariant memory, // then it could not have been modified by this catchpad. - if (pointsToConstantMemory(Loc, AAQI)) - return ModRefInfo::NoModRef; + return getModRefInfoMask(Loc, AAQI); } // Otherwise, a catchpad reads and writes. @@ -595,19 +551,12 @@ ModRefInfo AAResults::getModRefInfo(const CatchPadInst *CatchPad, } ModRefInfo AAResults::getModRefInfo(const CatchReturnInst *CatchRet, - const MemoryLocation &Loc) { - SimpleAAQueryInfo AAQIP; - return getModRefInfo(CatchRet, Loc, AAQIP); -} - -ModRefInfo AAResults::getModRefInfo(const CatchReturnInst *CatchRet, const MemoryLocation &Loc, AAQueryInfo &AAQI) { if (Loc.Ptr) { - // If the pointer is a pointer to constant memory, + // If the pointer is a pointer to invariant memory, // then it could not have been modified by this catchpad. - if (pointsToConstantMemory(Loc, AAQI)) - return ModRefInfo::NoModRef; + return getModRefInfoMask(Loc, AAQI); } // Otherwise, a catchret reads and writes. @@ -615,12 +564,6 @@ ModRefInfo AAResults::getModRefInfo(const CatchReturnInst *CatchRet, } ModRefInfo AAResults::getModRefInfo(const AtomicCmpXchgInst *CX, - const MemoryLocation &Loc) { - SimpleAAQueryInfo AAQIP; - return getModRefInfo(CX, Loc, AAQIP); -} - -ModRefInfo AAResults::getModRefInfo(const AtomicCmpXchgInst *CX, const MemoryLocation &Loc, AAQueryInfo &AAQI) { // Acquire/Release cmpxchg has properties that matter for arbitrary addresses. @@ -628,27 +571,17 @@ ModRefInfo AAResults::getModRefInfo(const AtomicCmpXchgInst *CX, return ModRefInfo::ModRef; if (Loc.Ptr) { - AliasResult AR = alias(MemoryLocation::get(CX), Loc, AAQI); + AliasResult AR = alias(MemoryLocation::get(CX), Loc, AAQI, CX); // If the cmpxchg address does not alias the location, it does not access // it. if (AR == AliasResult::NoAlias) return ModRefInfo::NoModRef; - - // If the cmpxchg address aliases the pointer as must alias, set Must. - if (AR == AliasResult::MustAlias) - return ModRefInfo::MustModRef; } return ModRefInfo::ModRef; } ModRefInfo AAResults::getModRefInfo(const AtomicRMWInst *RMW, - const MemoryLocation &Loc) { - SimpleAAQueryInfo AAQIP; - return getModRefInfo(RMW, Loc, AAQIP); -} - -ModRefInfo AAResults::getModRefInfo(const AtomicRMWInst *RMW, const MemoryLocation &Loc, AAQueryInfo &AAQI) { // Acquire/Release atomicrmw has properties that matter for arbitrary addresses. @@ -656,27 +589,22 @@ ModRefInfo AAResults::getModRefInfo(const AtomicRMWInst *RMW, return ModRefInfo::ModRef; if (Loc.Ptr) { - AliasResult AR = alias(MemoryLocation::get(RMW), Loc, AAQI); + AliasResult AR = alias(MemoryLocation::get(RMW), Loc, AAQI, RMW); // If the atomicrmw address does not alias the location, it does not access // it. if (AR == AliasResult::NoAlias) return ModRefInfo::NoModRef; - - // If the atomicrmw address aliases the pointer as must alias, set Must. - if (AR == AliasResult::MustAlias) - return ModRefInfo::MustModRef; } return ModRefInfo::ModRef; } ModRefInfo AAResults::getModRefInfo(const Instruction *I, - const Optional<MemoryLocation> &OptLoc, + const std::optional<MemoryLocation> &OptLoc, AAQueryInfo &AAQIP) { - if (OptLoc == None) { - if (const auto *Call = dyn_cast<CallBase>(I)) { - return createModRefInfo(getModRefBehavior(Call)); - } + if (OptLoc == std::nullopt) { + if (const auto *Call = dyn_cast<CallBase>(I)) + return getMemoryEffects(Call, AAQIP).getModRef(); } const MemoryLocation &Loc = OptLoc.value_or(MemoryLocation()); @@ -738,7 +666,6 @@ ModRefInfo AAResults::callCapturesBefore(const Instruction *I, unsigned ArgNo = 0; ModRefInfo R = ModRefInfo::NoModRef; - bool IsMustAlias = true; // Set flag only if no May found and all operands processed. for (auto CI = Call->data_operands_begin(), CE = Call->data_operands_end(); CI != CE; ++CI, ++ArgNo) { @@ -750,15 +677,13 @@ ModRefInfo AAResults::callCapturesBefore(const Instruction *I, !Call->isByValArgument(ArgNo))) continue; - AliasResult AR = alias( - MemoryLocation::getBeforeOrAfter(*CI), - MemoryLocation::getBeforeOrAfter(Object), AAQI); + AliasResult AR = + alias(MemoryLocation::getBeforeOrAfter(*CI), + MemoryLocation::getBeforeOrAfter(Object), AAQI, Call); // If this is a no-capture pointer argument, see if we can tell that it // is impossible to alias the pointer we're checking. If not, we have to // assume that the call could touch the pointer, even though it doesn't // escape. - if (AR != AliasResult::MustAlias) - IsMustAlias = false; if (AR == AliasResult::NoAlias) continue; if (Call->doesNotAccessMemory(ArgNo)) @@ -767,10 +692,9 @@ ModRefInfo AAResults::callCapturesBefore(const Instruction *I, R = ModRefInfo::Ref; continue; } - // Not returning MustModRef since we have not seen all the arguments. return ModRefInfo::ModRef; } - return IsMustAlias ? setMust(R) : clearMust(R); + return R; } /// canBasicBlockModify - Return true if it is possible for execution of the @@ -797,7 +721,7 @@ bool AAResults::canInstructionRangeModRef(const Instruction &I1, ++E; // Convert from inclusive to exclusive range. for (; I != E; ++I) // Check every instruction in range - if (isModOrRefSet(intersectModRef(getModRefInfo(&*I, Loc), Mode))) + if (isModOrRefSet(getModRefInfo(&*I, Loc) & Mode)) return true; return false; } @@ -836,11 +760,8 @@ char AAResultsWrapperPass::ID = 0; INITIALIZE_PASS_BEGIN(AAResultsWrapperPass, "aa", "Function Alias Analysis Results", false, true) INITIALIZE_PASS_DEPENDENCY(BasicAAWrapperPass) -INITIALIZE_PASS_DEPENDENCY(CFLAndersAAWrapperPass) -INITIALIZE_PASS_DEPENDENCY(CFLSteensAAWrapperPass) INITIALIZE_PASS_DEPENDENCY(ExternalAAWrapperPass) INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass) -INITIALIZE_PASS_DEPENDENCY(ObjCARCAAWrapperPass) INITIALIZE_PASS_DEPENDENCY(SCEVAAWrapperPass) INITIALIZE_PASS_DEPENDENCY(ScopedNoAliasAAWrapperPass) INITIALIZE_PASS_DEPENDENCY(TypeBasedAAWrapperPass) @@ -881,17 +802,10 @@ bool AAResultsWrapperPass::runOnFunction(Function &F) { AAR->addAAResult(WrapperPass->getResult()); if (auto *WrapperPass = getAnalysisIfAvailable<TypeBasedAAWrapperPass>()) AAR->addAAResult(WrapperPass->getResult()); - if (auto *WrapperPass = - getAnalysisIfAvailable<objcarc::ObjCARCAAWrapperPass>()) - AAR->addAAResult(WrapperPass->getResult()); if (auto *WrapperPass = getAnalysisIfAvailable<GlobalsAAWrapperPass>()) AAR->addAAResult(WrapperPass->getResult()); if (auto *WrapperPass = getAnalysisIfAvailable<SCEVAAWrapperPass>()) AAR->addAAResult(WrapperPass->getResult()); - if (auto *WrapperPass = getAnalysisIfAvailable<CFLAndersAAWrapperPass>()) - AAR->addAAResult(WrapperPass->getResult()); - if (auto *WrapperPass = getAnalysisIfAvailable<CFLSteensAAWrapperPass>()) - AAR->addAAResult(WrapperPass->getResult()); // If available, run an external AA providing callback over the results as // well. @@ -914,11 +828,8 @@ void AAResultsWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { // the legacy pass manager. AU.addUsedIfAvailable<ScopedNoAliasAAWrapperPass>(); AU.addUsedIfAvailable<TypeBasedAAWrapperPass>(); - AU.addUsedIfAvailable<objcarc::ObjCARCAAWrapperPass>(); AU.addUsedIfAvailable<GlobalsAAWrapperPass>(); AU.addUsedIfAvailable<SCEVAAWrapperPass>(); - AU.addUsedIfAvailable<CFLAndersAAWrapperPass>(); - AU.addUsedIfAvailable<CFLSteensAAWrapperPass>(); AU.addUsedIfAvailable<ExternalAAWrapperPass>(); } @@ -943,15 +854,8 @@ AAResults llvm::createLegacyPMAAResults(Pass &P, Function &F, AAR.addAAResult(WrapperPass->getResult()); if (auto *WrapperPass = P.getAnalysisIfAvailable<TypeBasedAAWrapperPass>()) AAR.addAAResult(WrapperPass->getResult()); - if (auto *WrapperPass = - P.getAnalysisIfAvailable<objcarc::ObjCARCAAWrapperPass>()) - AAR.addAAResult(WrapperPass->getResult()); if (auto *WrapperPass = P.getAnalysisIfAvailable<GlobalsAAWrapperPass>()) AAR.addAAResult(WrapperPass->getResult()); - if (auto *WrapperPass = P.getAnalysisIfAvailable<CFLAndersAAWrapperPass>()) - AAR.addAAResult(WrapperPass->getResult()); - if (auto *WrapperPass = P.getAnalysisIfAvailable<CFLSteensAAWrapperPass>()) - AAR.addAAResult(WrapperPass->getResult()); if (auto *WrapperPass = P.getAnalysisIfAvailable<ExternalAAWrapperPass>()) if (WrapperPass->CB) WrapperPass->CB(P, F, AAR); @@ -1039,9 +943,6 @@ void llvm::getAAResultsAnalysisUsage(AnalysisUsage &AU) { AU.addRequired<TargetLibraryInfoWrapperPass>(); AU.addUsedIfAvailable<ScopedNoAliasAAWrapperPass>(); AU.addUsedIfAvailable<TypeBasedAAWrapperPass>(); - AU.addUsedIfAvailable<objcarc::ObjCARCAAWrapperPass>(); AU.addUsedIfAvailable<GlobalsAAWrapperPass>(); - AU.addUsedIfAvailable<CFLAndersAAWrapperPass>(); - AU.addUsedIfAvailable<CFLSteensAAWrapperPass>(); AU.addUsedIfAvailable<ExternalAAWrapperPass>(); } |