Index: llvm/include/llvm/Analysis/AliasAnalysis.h =================================================================== --- llvm/include/llvm/Analysis/AliasAnalysis.h +++ llvm/include/llvm/Analysis/AliasAnalysis.h @@ -335,6 +335,8 @@ return ModRefInfo(FMRB & static_cast(ModRefInfo::ModRef)); } +class AAResults; + /// This class stores info we want to provide to or retain within an alias /// query. By default, the root query is stateless and starts with a freshly /// constructed info object. Specific alias analyses can use this query info to @@ -354,13 +356,16 @@ /// Whether this is a definitive (non-assumption) result. bool isDefinitive() const { return NumAssumptionUses < 0; } }; + + AAResults &AAR; + using AliasCacheT = SmallDenseMap; AliasCacheT AliasCache; using IsCapturedCacheT = SmallDenseMap; IsCapturedCacheT IsCapturedCache; - AAQueryInfo() : AliasCache(), IsCapturedCache() {} + AAQueryInfo(AAResults &AAR) : AAR(AAR), AliasCache(), IsCapturedCache() {} }; class BatchAAResults; @@ -682,7 +687,7 @@ /// helpers above. ModRefInfo getModRefInfo(const Instruction *I, const Optional &OptLoc) { - AAQueryInfo AAQIP; + AAQueryInfo AAQIP(*this); return getModRefInfo(I, OptLoc, AAQIP); } @@ -746,7 +751,6 @@ return canInstructionRangeModRef(I1, I2, MemoryLocation(Ptr, Size), Mode); } -private: AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB, AAQueryInfo &AAQI); bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI, @@ -777,6 +781,7 @@ const Optional &OptLoc, AAQueryInfo &AAQIP); +private: class Concept; template class Model; @@ -806,7 +811,7 @@ AAQueryInfo AAQI; public: - BatchAAResults(AAResults &AAR) : AA(AAR), AAQI() {} + BatchAAResults(AAResults &AAR) : AA(AAR), AAQI(AAR) {} AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB) { return AA.alias(LocA, LocB, AAQI); } @@ -858,10 +863,6 @@ public: virtual ~Concept() = 0; - /// An update API used internally by the AAResults to provide - /// a handle back to the top level aggregation. - virtual void setAAResults(AAResults *NewAAR) = 0; - //===--------------------------------------------------------------------===// /// \name Alias Queries /// @{ @@ -922,13 +923,9 @@ AAResultT &Result; public: - explicit Model(AAResultT &Result, AAResults &AAR) : Result(Result) { - Result.setAAResults(&AAR); - } + explicit Model(AAResultT &Result, AAResults &AAR) : Result(Result) {} ~Model() override = default; - void setAAResults(AAResults *NewAAR) override { Result.setAAResults(NewAAR); } - AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB, AAQueryInfo &AAQI) override { return Result.alias(LocA, LocB, AAQI); @@ -976,73 +973,7 @@ /// use virtual anywhere, the CRTP base class does static dispatch to the /// derived type passed into it. template class AAResultBase { - // Expose some parts of the interface only to the AAResults::Model - // for wrapping. Specifically, this allows the model to call our - // setAAResults method without exposing it as a fully public API. - friend class AAResults::Model; - - /// A pointer to the AAResults object that this AAResult is - /// aggregated within. May be null if not aggregated. - AAResults *AAR = nullptr; - - /// Helper to dispatch calls back through the derived type. - DerivedT &derived() { return static_cast(*this); } - - /// A setter for the AAResults pointer, which is used to satisfy the - /// AAResults::Model contract. - void setAAResults(AAResults *NewAAR) { AAR = NewAAR; } - protected: - /// This proxy class models a common pattern where we delegate to either the - /// top-level \c AAResults aggregation if one is registered, or to the - /// current result if none are registered. - class AAResultsProxy { - AAResults *AAR; - DerivedT &CurrentResult; - - public: - AAResultsProxy(AAResults *AAR, DerivedT &CurrentResult) - : AAR(AAR), CurrentResult(CurrentResult) {} - - AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB, - AAQueryInfo &AAQI) { - return AAR ? AAR->alias(LocA, LocB, AAQI) - : CurrentResult.alias(LocA, LocB, AAQI); - } - - bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI, - bool OrLocal) { - return AAR ? AAR->pointsToConstantMemory(Loc, AAQI, OrLocal) - : CurrentResult.pointsToConstantMemory(Loc, AAQI, OrLocal); - } - - ModRefInfo getArgModRefInfo(const CallBase *Call, unsigned ArgIdx) { - return AAR ? AAR->getArgModRefInfo(Call, ArgIdx) - : CurrentResult.getArgModRefInfo(Call, ArgIdx); - } - - FunctionModRefBehavior getModRefBehavior(const CallBase *Call) { - return AAR ? AAR->getModRefBehavior(Call) - : CurrentResult.getModRefBehavior(Call); - } - - FunctionModRefBehavior getModRefBehavior(const Function *F) { - return AAR ? AAR->getModRefBehavior(F) : CurrentResult.getModRefBehavior(F); - } - - ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc, - AAQueryInfo &AAQI) { - return AAR ? AAR->getModRefInfo(Call, Loc, AAQI) - : CurrentResult.getModRefInfo(Call, Loc, AAQI); - } - - ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2, - AAQueryInfo &AAQI) { - return AAR ? AAR->getModRefInfo(Call1, Call2, AAQI) - : CurrentResult.getModRefInfo(Call1, Call2, AAQI); - } - }; - explicit AAResultBase() = default; // Provide all the copy and move constructors so that derived types aren't @@ -1050,18 +981,6 @@ AAResultBase(const AAResultBase &Arg) {} AAResultBase(AAResultBase &&Arg) {} - /// Get a proxy for the best AA result set to query at this time. - /// - /// When this result is part of a larger aggregation, this will proxy to that - /// aggregation. When this result is used in isolation, it will just delegate - /// back to the derived class's implementation. - /// - /// Note that callers of this need to take considerable care to not cause - /// performance problems when they use this routine, in the case of a large - /// number of alias analyses being aggregated, it can be expensive to walk - /// back across the chain. - AAResultsProxy getBestAAResults() { return AAResultsProxy(AAR, derived()); } - public: AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB, AAQueryInfo &AAQI) { Index: llvm/lib/Analysis/AliasAnalysis.cpp =================================================================== --- llvm/lib/Analysis/AliasAnalysis.cpp +++ llvm/lib/Analysis/AliasAnalysis.cpp @@ -69,20 +69,9 @@ AAResults::AAResults(AAResults &&Arg) : TLI(Arg.TLI), AAs(std::move(Arg.AAs)), AADeps(std::move(Arg.AADeps)) { - for (auto &AA : AAs) - AA->setAAResults(this); } -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) { @@ -110,7 +99,7 @@ AliasResult AAResults::alias(const MemoryLocation &LocA, const MemoryLocation &LocB) { - AAQueryInfo AAQIP; + AAQueryInfo AAQIP(*this); return alias(LocA, LocB, AAQIP); } @@ -139,7 +128,7 @@ bool AAResults::pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal) { - AAQueryInfo AAQIP; + AAQueryInfo AAQIP(*this); return pointsToConstantMemory(Loc, AAQIP, OrLocal); } @@ -167,7 +156,7 @@ } ModRefInfo AAResults::getModRefInfo(Instruction *I, const CallBase *Call2) { - AAQueryInfo AAQIP; + AAQueryInfo AAQIP(*this); return getModRefInfo(I, Call2, AAQIP); } @@ -195,7 +184,7 @@ ModRefInfo AAResults::getModRefInfo(const CallBase *Call, const MemoryLocation &Loc) { - AAQueryInfo AAQIP; + AAQueryInfo AAQIP(*this); return getModRefInfo(Call, Loc, AAQIP); } @@ -262,7 +251,7 @@ ModRefInfo AAResults::getModRefInfo(const CallBase *Call1, const CallBase *Call2) { - AAQueryInfo AAQIP; + AAQueryInfo AAQIP(*this); return getModRefInfo(Call1, Call2, AAQIP); } @@ -450,7 +439,7 @@ ModRefInfo AAResults::getModRefInfo(const LoadInst *L, const MemoryLocation &Loc) { - AAQueryInfo AAQIP; + AAQueryInfo AAQIP(*this); return getModRefInfo(L, Loc, AAQIP); } ModRefInfo AAResults::getModRefInfo(const LoadInst *L, @@ -475,7 +464,7 @@ ModRefInfo AAResults::getModRefInfo(const StoreInst *S, const MemoryLocation &Loc) { - AAQueryInfo AAQIP; + AAQueryInfo AAQIP(*this); return getModRefInfo(S, Loc, AAQIP); } ModRefInfo AAResults::getModRefInfo(const StoreInst *S, @@ -507,7 +496,7 @@ } ModRefInfo AAResults::getModRefInfo(const FenceInst *S, const MemoryLocation &Loc) { - AAQueryInfo AAQIP; + AAQueryInfo AAQIP(*this); return getModRefInfo(S, Loc, AAQIP); } @@ -523,7 +512,7 @@ ModRefInfo AAResults::getModRefInfo(const VAArgInst *V, const MemoryLocation &Loc) { - AAQueryInfo AAQIP; + AAQueryInfo AAQIP(*this); return getModRefInfo(V, Loc, AAQIP); } @@ -553,7 +542,7 @@ ModRefInfo AAResults::getModRefInfo(const CatchPadInst *CatchPad, const MemoryLocation &Loc) { - AAQueryInfo AAQIP; + AAQueryInfo AAQIP(*this); return getModRefInfo(CatchPad, Loc, AAQIP); } @@ -573,7 +562,7 @@ ModRefInfo AAResults::getModRefInfo(const CatchReturnInst *CatchRet, const MemoryLocation &Loc) { - AAQueryInfo AAQIP; + AAQueryInfo AAQIP(*this); return getModRefInfo(CatchRet, Loc, AAQIP); } @@ -593,7 +582,7 @@ ModRefInfo AAResults::getModRefInfo(const AtomicCmpXchgInst *CX, const MemoryLocation &Loc) { - AAQueryInfo AAQIP; + AAQueryInfo AAQIP(*this); return getModRefInfo(CX, Loc, AAQIP); } @@ -621,7 +610,7 @@ ModRefInfo AAResults::getModRefInfo(const AtomicRMWInst *RMW, const MemoryLocation &Loc) { - AAQueryInfo AAQIP; + AAQueryInfo AAQIP(*this); return getModRefInfo(RMW, Loc, AAQIP); } Index: llvm/lib/Analysis/BasicAliasAnalysis.cpp =================================================================== --- llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -691,10 +691,12 @@ // If the call has operand bundles then aliasing attributes from the function // it calls do not directly apply to the call. This can be made more precise // in the future. +#if 0 if (!Call->hasOperandBundles()) if (const Function *F = Call->getCalledFunction()) Min = FunctionModRefBehavior(Min & getBestAAResults().getModRefBehavior(F)); +#endif return Min; } @@ -881,7 +883,7 @@ // If this is a no-capture pointer argument, see if we can tell that it // is impossible to alias the pointer we're checking. - AliasResult AR = getBestAAResults().alias( + AliasResult AR = AAQI.AAR.alias( MemoryLocation::getBeforeOrAfter(*CI), MemoryLocation::getBeforeOrAfter(Object), AAQI); if (AR != MustAlias) @@ -929,8 +931,8 @@ if (isMallocOrCallocLikeFn(Call, &TLI)) { // Be conservative if the accessed pointer may alias the allocation - // fallback to the generic handling below. - if (getBestAAResults().alias(MemoryLocation::getBeforeOrAfter(Call), - Loc, AAQI) == NoAlias) + if (AAQI.AAR.alias(MemoryLocation::getBeforeOrAfter(Call), + Loc, AAQI) == NoAlias) return ModRefInfo::NoModRef; } @@ -939,9 +941,9 @@ // no-alias or must-alias. if (auto *Inst = dyn_cast(Call)) { AliasResult SrcAA = - getBestAAResults().alias(MemoryLocation::getForSource(Inst), Loc, AAQI); + AAQI.AAR.alias(MemoryLocation::getForSource(Inst), Loc, AAQI); AliasResult DestAA = - getBestAAResults().alias(MemoryLocation::getForDest(Inst), Loc, AAQI); + AAQI.AAR.alias(MemoryLocation::getForDest(Inst), Loc, AAQI); // It's also possible for Loc to alias both src and dest, or neither. ModRefInfo rv = ModRefInfo::NoModRef; if (SrcAA != NoAlias) @@ -1470,7 +1472,7 @@ // If we inserted a block into VisitedPhiBBs, alias analysis results that // have been cached earlier may no longer be valid. Perform recursive queries // with a new AAQueryInfo. - AAQueryInfo NewAAQI; + AAQueryInfo NewAAQI(AAQI.AAR); AAQueryInfo *UseAAQI = BlockInserted ? &NewAAQI : &AAQI; AliasResult Alias = aliasCheck(V2, V2Size, V2AAInfo, V1Srcs[0], PNSize, @@ -1710,8 +1712,8 @@ // Recurse back into the best AA results we have, potentially with refined // memory locations. We have already ensured that BasicAA has a MayAlias // cache result for these, so any recursion back into BasicAA won't loop. - return getBestAAResults().alias(MemoryLocation(V1, V1Size, V1AAInfo), - MemoryLocation(V2, V2Size, V2AAInfo), AAQI); + return AAQI.AAR.alias(MemoryLocation(V1, V1Size, V1AAInfo), + MemoryLocation(V2, V2Size, V2AAInfo), AAQI); } /// Check whether two Values can be considered equivalent. Index: llvm/unittests/Analysis/BasicAliasAnalysisTest.cpp =================================================================== --- llvm/unittests/Analysis/BasicAliasAnalysisTest.cpp +++ llvm/unittests/Analysis/BasicAliasAnalysisTest.cpp @@ -46,11 +46,14 @@ DominatorTree DT; AssumptionCache AC; BasicAAResult BAA; + AAResults AAR; AAQueryInfo AAQI; TestAnalyses(BasicAATest &Test) : DT(*Test.F), AC(*Test.F), BAA(Test.DL, *Test.F, Test.TLI, AC, &DT), - AAQI() {} + AAR(Test.TLI), AAQI(AAR) { + AAR.addAAResult(BAA); + } }; llvm::Optional Analyses;