Index: include/llvm/Analysis/LoopAccessAnalysis.h =================================================================== --- include/llvm/Analysis/LoopAccessAnalysis.h +++ include/llvm/Analysis/LoopAccessAnalysis.h @@ -670,10 +670,49 @@ bool Assume = false); /// \brief Returns true if the memory operations \p A and \p B are consecutive. -/// This is a simple API that does not depend on the analysis pass. +/// This is a simple API that does not depend on the analysis pass. bool isConsecutiveAccess(Value *A, Value *B, const DataLayout &DL, ScalarEvolution &SE, bool CheckType = true); +class LoopAccessFuncInfo { +public: + LoopAccessFuncInfo() + : LoopAccessInfoMap(), AAR(nullptr), DT(nullptr), LI(nullptr), + SCEV(nullptr), TLI(nullptr) {} + void setDepAnalyses(AliasAnalysis *AAR_, DominatorTree *DT_, LoopInfo *LI_, + ScalarEvolution *SCEV_, TargetLibraryInfo *TLI_) { + AAR = AAR_; + DT = DT_; + LI = LI_; + SCEV = SCEV_; + TLI = TLI_; + } + /// \brief Query the result of the loop access information for the loop \p L. + /// + /// If the client speculates (and then issues run-time checks) for the values + /// of symbolic strides, \p Strides provides the mapping (see + /// replaceSymbolicStrideSCEV). If there is no cached result available run + /// the analysis. + const LoopAccessInfo &getInfo(Loop *L, const ValueToValueMap &Strides); + + void print(raw_ostream &OS, const Module *M = nullptr) const; + + void releaseMemory() { + // Invalidate the cache when the pass is freed. + LoopAccessInfoMap.clear(); + } + +private: + /// \brief The cache. + DenseMap> LoopAccessInfoMap; + + AliasAnalysis *AAR; + DominatorTree *DT; + LoopInfo *LI; + ScalarEvolution *SCEV; + TargetLibraryInfo *TLI; +}; + /// \brief This analysis provides dependence information for the memory accesses /// of a loop. /// @@ -685,7 +724,7 @@ public: static char ID; - LoopAccessAnalysis() : FunctionPass(ID) { + LoopAccessAnalysis() : FunctionPass(ID), LAFI() { initializeLoopAccessAnalysisPass(*PassRegistry::getPassRegistry()); } @@ -693,32 +732,20 @@ void getAnalysisUsage(AnalysisUsage &AU) const override; - /// \brief Query the result of the loop access information for the loop \p L. - /// - /// If the client speculates (and then issues run-time checks) for the values - /// of symbolic strides, \p Strides provides the mapping (see - /// replaceSymbolicStrideSCEV). If there is no cached result available run - /// the analysis. - const LoopAccessInfo &getInfo(Loop *L, const ValueToValueMap &Strides); + LoopAccessFuncInfo &getInfo() { return LAFI; } void releaseMemory() override { // Invalidate the cache when the pass is freed. - LoopAccessInfoMap.clear(); + LAFI.releaseMemory(); } /// \brief Print the result of the analysis when invoked with -analyze. - void print(raw_ostream &OS, const Module *M = nullptr) const override; + void print(raw_ostream &OS, const Module *M = nullptr) const override { + LAFI.print(OS, M); + } private: - /// \brief The cache. - DenseMap> LoopAccessInfoMap; - - // The used analysis passes. - ScalarEvolution *SE; - const TargetLibraryInfo *TLI; - AliasAnalysis *AA; - DominatorTree *DT; - LoopInfo *LI; + LoopAccessFuncInfo LAFI; }; inline Instruction *MemoryDepChecker::Dependence::getSource( Index: lib/Analysis/LoopAccessAnalysis.cpp =================================================================== --- lib/Analysis/LoopAccessAnalysis.cpp +++ lib/Analysis/LoopAccessAnalysis.cpp @@ -1926,7 +1926,7 @@ } const LoopAccessInfo & -LoopAccessAnalysis::getInfo(Loop *L, const ValueToValueMap &Strides) { +LoopAccessFuncInfo::getInfo(Loop *L, const ValueToValueMap &Strides) { auto &LAI = LoopAccessInfoMap[L]; #ifndef NDEBUG @@ -1936,8 +1936,8 @@ if (!LAI) { const DataLayout &DL = L->getHeader()->getModule()->getDataLayout(); - LAI = - llvm::make_unique(L, SE, DL, TLI, AA, DT, LI, Strides); + LAI = llvm::make_unique(L, SCEV, DL, TLI, AAR, DT, LI, + Strides); #ifndef NDEBUG LAI->NumSymbolicStrides = Strides.size(); #endif @@ -1945,26 +1945,25 @@ return *LAI.get(); } -void LoopAccessAnalysis::print(raw_ostream &OS, const Module *M) const { - LoopAccessAnalysis &LAA = *const_cast(this); - +void LoopAccessFuncInfo::print(raw_ostream &OS, const Module *M) const { ValueToValueMap NoSymbolicStrides; for (Loop *TopLevelLoop : *LI) for (Loop *L : depth_first(TopLevelLoop)) { OS.indent(2) << L->getHeader()->getName() << ":\n"; - auto &LAI = LAA.getInfo(L, NoSymbolicStrides); + auto &LAI = + const_cast(this)->getInfo(L, NoSymbolicStrides); LAI.print(OS, 4); } } bool LoopAccessAnalysis::runOnFunction(Function &F) { - SE = &getAnalysis().getSE(); auto *TLIP = getAnalysisIfAvailable(); - TLI = TLIP ? &TLIP->getTLI() : nullptr; - AA = &getAnalysis().getAAResults(); - DT = &getAnalysis().getDomTree(); - LI = &getAnalysis().getLoopInfo(); + TargetLibraryInfo *TLI = TLIP ? &TLIP->getTLI() : nullptr; + LAFI.setDepAnalyses(&getAnalysis().getAAResults(), + &getAnalysis().getDomTree(), + &getAnalysis().getLoopInfo(), + &getAnalysis().getSE(), TLI); return false; } Index: lib/Transforms/Scalar/LoopDistribute.cpp =================================================================== --- lib/Transforms/Scalar/LoopDistribute.cpp +++ lib/Transforms/Scalar/LoopDistribute.cpp @@ -608,7 +608,7 @@ return fail("multiple exit blocks"); // LAA will check that we only have a single exiting block. - LAI = &LAA->getInfo(L, ValueToValueMap()); + LAI = &LAA->getInfo().getInfo(L, ValueToValueMap()); // Currently, we only distribute to isolate the part of the loop with // dependence cycles to enable partial vectorization. Index: lib/Transforms/Scalar/LoopLoadElimination.cpp =================================================================== --- lib/Transforms/Scalar/LoopLoadElimination.cpp +++ lib/Transforms/Scalar/LoopLoadElimination.cpp @@ -552,7 +552,7 @@ // Now walk the identified inner loops. bool Changed = false; for (Loop *L : Worklist) { - const LoopAccessInfo &LAI = LAA->getInfo(L, ValueToValueMap()); + const LoopAccessInfo &LAI = LAA->getInfo().getInfo(L, ValueToValueMap()); // The actual work is performed by LoadEliminationForLoop. LoadEliminationForLoop LEL(L, LI, LAI, DT); Changed |= LEL.processLoop(); Index: lib/Transforms/Scalar/LoopVersioningLICM.cpp =================================================================== --- lib/Transforms/Scalar/LoopVersioningLICM.cpp +++ lib/Transforms/Scalar/LoopVersioningLICM.cpp @@ -411,7 +411,7 @@ return false; } // Get LoopAccessInfo from current loop. - LAI = &LAA->getInfo(CurLoop, Strides); + LAI = &LAA->getInfo().getInfo(CurLoop, Strides); // Check LoopAccessInfo for need of runtime check. if (LAI->getRuntimePointerChecking()->getChecks().empty()) { DEBUG(dbgs() << " LAA: Runtime check not found !!\n"); Index: lib/Transforms/Utils/LoopVersioning.cpp =================================================================== --- lib/Transforms/Utils/LoopVersioning.cpp +++ lib/Transforms/Utils/LoopVersioning.cpp @@ -268,7 +268,7 @@ // Now walk the identified inner loops. bool Changed = false; for (Loop *L : Worklist) { - const LoopAccessInfo &LAI = LAA->getInfo(L, ValueToValueMap()); + const LoopAccessInfo &LAI = LAA->getInfo().getInfo(L, ValueToValueMap()); if (LAI.getNumRuntimePointerChecks() || !LAI.PSE.getUnionPredicate().isAlwaysTrue()) { LoopVersioning LVer(LAI, L, LI, DT, SE); Index: lib/Transforms/Vectorize/LoopVectorize.cpp =================================================================== --- lib/Transforms/Vectorize/LoopVectorize.cpp +++ lib/Transforms/Vectorize/LoopVectorize.cpp @@ -4931,7 +4931,7 @@ } bool LoopVectorizationLegality::canVectorizeMemory() { - LAI = &LAA->getInfo(TheLoop, Strides); + LAI = &LAA->getInfo().getInfo(TheLoop, Strides); auto &OptionalReport = LAI->getReport(); if (OptionalReport) emitAnalysis(VectorizationReport(*OptionalReport));