Index: include/llvm/Analysis/LoopAccessAnalysis.h =================================================================== --- include/llvm/Analysis/LoopAccessAnalysis.h +++ include/llvm/Analysis/LoopAccessAnalysis.h @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_ANALYSIS_LOOPACCESSANALYSIS_H -#define LLVM_ANALYSIS_LOOPACCESSANALYSIS_H +#ifndef LLVM_ANALYSIS_LOOPACCESSINFO_H +#define LLVM_ANALYSIS_LOOPACCESSINFO_H #include "llvm/ADT/EquivalenceClasses.h" #include "llvm/ADT/Optional.h" @@ -22,7 +22,6 @@ #include "llvm/Analysis/AliasSetTracker.h" #include "llvm/Analysis/ScalarEvolutionExpressions.h" #include "llvm/IR/ValueHandle.h" -#include "llvm/Pass.h" #include "llvm/Support/raw_ostream.h" namespace llvm { @@ -670,59 +669,12 @@ 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); -/// \brief This analysis provides dependence information for the memory accesses -/// of a loop. -/// -/// It runs the analysis for a loop on demand. This can be initiated by -/// querying the loop access info via LAA::getInfo. getInfo return a -/// LoopAccessInfo object. See this class for the specifics of what information -/// is provided. -class LoopAccessAnalysis : public FunctionPass { -public: - static char ID; - - LoopAccessAnalysis() : FunctionPass(ID) { - initializeLoopAccessAnalysisPass(*PassRegistry::getPassRegistry()); - } - - bool runOnFunction(Function &F) override; - - 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); - - void releaseMemory() override { - // Invalidate the cache when the pass is freed. - LoopAccessInfoMap.clear(); - } - - /// \brief Print the result of the analysis when invoked with -analyze. - void print(raw_ostream &OS, const Module *M = nullptr) const override; - -private: - /// \brief The cache. - DenseMap> LoopAccessInfoMap; - - // The used analysis passes. - ScalarEvolution *SE; - const TargetLibraryInfo *TLI; - AliasAnalysis *AA; - DominatorTree *DT; - LoopInfo *LI; -}; - -inline Instruction *MemoryDepChecker::Dependence::getSource( - const LoopAccessInfo &LAI) const { +inline Instruction * +MemoryDepChecker::Dependence::getSource(const LoopAccessInfo &LAI) const { return LAI.getDepChecker().getMemoryInstructions()[Source]; } Index: include/llvm/Analysis/LoopAccessInfoAnalysis.h =================================================================== --- include/llvm/Analysis/LoopAccessInfoAnalysis.h +++ include/llvm/Analysis/LoopAccessInfoAnalysis.h @@ -0,0 +1,110 @@ +//===- llvm/Analysis/LoopAccessInfoAnalysis.h -------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the interface for the loop memory dependence framework that +// was originally developed for the Loop Vectorizer. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_LOOPACCESSINFOANALYSIS_H +#define LLVM_ANALYSIS_LOOPACCESSINFOANALYSIS_H + +#include "llvm/ADT/DenseMap.h" +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/IR/PassManager.h" +#include "llvm/InitializePasses.h" +#include "llvm/Pass.h" + +namespace llvm { + +class DominatorTree; +class Loop; +class LoopAccessInfo; +class LoopInfo; +class ScalarEvolution; +class TargetLibraryInfo; +class Value; + +typedef DenseMap ValueToValueMap; + +// Analysis manager base +class LoopAccessAMBase { +public: + virtual TargetLibraryInfo *getTLI() = 0; + virtual AliasAnalysis *getAAResults() = 0; + virtual DominatorTree *getDominatorTree() = 0; + virtual LoopInfo *getLoopInfo() = 0; + virtual ScalarEvolution *getSCEV() = 0; + virtual ~LoopAccessAMBase() {} +}; + +class LoopAccessFuncInfo { +public: + LoopAccessFuncInfo() : LoopAccessInfoMap(), AM(nullptr) {} + /// \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(); + } + + void setAM(LoopAccessAMBase *AM_) { AM.reset(AM_); } + +private: + /// \brief The cache. + DenseMap> LoopAccessInfoMap; + std::unique_ptr AM; +}; + +/// \brief This analysis provides dependence information for the memory accesses +/// of a loop. +/// +/// It runs the analysis for a loop on demand. This can be initiated by +/// querying the loop access info via LAA::getInfo. getInfo return a +/// LoopAccessInfo object. See this class for the specifics of what information +/// is provided. +class LoopAccessAnalysis : public FunctionPass { +public: + static char ID; + + LoopAccessAnalysis() : FunctionPass(ID), LAFI() { + initializeLoopAccessAnalysisPass(*PassRegistry::getPassRegistry()); + } + + bool runOnFunction(Function &F) override; + + void getAnalysisUsage(AnalysisUsage &AU) const override; + + LoopAccessFuncInfo &getInfo() { return LAFI; } + + void releaseMemory() override { + // Invalidate the cache when the pass is freed. + LAFI.releaseMemory(); + } + + /// \brief Print the result of the analysis when invoked with -analyze. + void print(raw_ostream &OS, const Module *M = nullptr) const override { + LAFI.print(OS, M); + } + +private: + LoopAccessFuncInfo LAFI; +}; + +} // End llvm namespace + +#endif Index: include/llvm/Transforms/Utils/LoopVersioning.h =================================================================== --- include/llvm/Transforms/Utils/LoopVersioning.h +++ include/llvm/Transforms/Utils/LoopVersioning.h @@ -17,9 +17,10 @@ #define LLVM_TRANSFORMS_UTILS_LOOPVERSIONING_H #include "llvm/Analysis/LoopAccessAnalysis.h" +#include "llvm/Analysis/LoopAccessInfoAnalysis.h" #include "llvm/Analysis/ScalarEvolution.h" -#include "llvm/Transforms/Utils/ValueMapper.h" #include "llvm/Transforms/Utils/LoopUtils.h" +#include "llvm/Transforms/Utils/ValueMapper.h" namespace llvm { Index: lib/Analysis/LoopAccessAnalysis.cpp =================================================================== --- lib/Analysis/LoopAccessAnalysis.cpp +++ lib/Analysis/LoopAccessAnalysis.cpp @@ -13,16 +13,17 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/LoopAccessAnalysis.h" +#include "llvm/Analysis/LoopAccessInfoAnalysis.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/ScalarEvolutionExpander.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/ValueTracking.h" +#include "llvm/Analysis/VectorUtils.h" #include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/IRBuilder.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Analysis/VectorUtils.h" using namespace llvm; #define DEBUG_TYPE "loop-accesses" @@ -1926,7 +1927,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 +1937,9 @@ 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, AM->getSCEV(), DL, AM->getTLI(), AM->getAAResults(), + AM->getDominatorTree(), AM->getLoopInfo(), Strides); #ifndef NDEBUG LAI->NumSymbolicStrides = Strides.size(); #endif @@ -1945,27 +1947,46 @@ 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 { + LoopInfo *LI = AM->getLoopInfo(); 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(); +class LoopAccessAMLegacy : public LoopAccessAMBase { +public: + LoopAccessAMLegacy(LoopAccessAnalysis &LAA) { + SE = &LAA.getAnalysis().getSE(); + auto *TLIP = LAA.getAnalysisIfAvailable(); + TLI = TLIP ? &TLIP->getTLI() : nullptr; + AA = &LAA.getAnalysis().getAAResults(); + DT = &LAA.getAnalysis().getDomTree(); + LI = &LAA.getAnalysis().getLoopInfo(); + } + TargetLibraryInfo *getTLI() override { return TLI; } + AliasAnalysis *getAAResults() override { return AA; } + DominatorTree *getDominatorTree() override { return DT; } + LoopInfo *getLoopInfo() override { return LI; } + ScalarEvolution *getSCEV() override { return SE; } +private: + ScalarEvolution *SE; + TargetLibraryInfo *TLI; + AliasAnalysis *AA; + DominatorTree *DT; + LoopInfo *LI; +}; + +bool LoopAccessAnalysis::runOnFunction(Function &F) { + LAFI.setAM(new LoopAccessAMLegacy(*this)); 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/LoopIdiomRecognize.cpp =================================================================== --- lib/Transforms/Scalar/LoopIdiomRecognize.cpp +++ lib/Transforms/Scalar/LoopIdiomRecognize.cpp @@ -31,15 +31,15 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Transforms/Scalar.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/BasicAliasAnalysis.h" #include "llvm/Analysis/GlobalsModRef.h" -#include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/LoopAccessAnalysis.h" +#include "llvm/Analysis/LoopAccessInfoAnalysis.h" +#include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" #include "llvm/Analysis/ScalarEvolutionExpander.h" #include "llvm/Analysis/ScalarEvolutionExpressions.h" @@ -53,6 +53,7 @@ #include "llvm/IR/Module.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/BuildLibCalls.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/LoopUtils.h" 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)); Index: lib/Transforms/Vectorize/SLPVectorizer.cpp =================================================================== --- lib/Transforms/Vectorize/SLPVectorizer.cpp +++ lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -26,7 +26,7 @@ #include "llvm/Analysis/DemandedBits.h" #include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/LoopAccessAnalysis.h" -#include "llvm/Analysis/LoopAccessAnalysis.h" +#include "llvm/Analysis/LoopAccessInfoAnalysis.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Analysis/ScalarEvolutionExpressions.h"