Index: include/polly/DependenceInfo.h =================================================================== --- include/polly/DependenceInfo.h +++ include/polly/DependenceInfo.h @@ -146,6 +146,7 @@ /// To restrict access to the internal state, only the DependenceInfo class /// is able to call or modify a Dependences struct. friend class DependenceInfo; + friend class DependenceInfoWrapperPass; /// @brief Destructor that will free internal objects. ~Dependences() { releaseMemory(); } @@ -192,6 +193,7 @@ const AnalyisLevel Level; }; +//===----------------------------------------------------------------------===// class DependenceInfo : public ScopPass { public: static char ID; @@ -232,11 +234,52 @@ std::unique_ptr D[Dependences::NumAnalysisLevels]; }; +//===----------------------------------------------------------------------===// +/// @brief Construct a new DependenceInfoWrapper pass. +class DependenceInfoWrapperPass : public FunctionPass { +public: + static char ID; + + using ScopToDepsMapTy = DenseMap>; + + /// @brief Construct a new DependenceInfoWrapper pass. + DependenceInfoWrapperPass() : FunctionPass(ID) {} + + /// @brief Return the dependence information for the current SCoP. + /// + /// @param Level The granularity of dependence analysis result. + /// + /// @return The dependence analysis result + /// + const Dependences &getDependences(Scop *S, Dependences::AnalyisLevel Level); + + /// @brief Recompute dependences from schedule and memory accesses. + const Dependences &recomputeDependences(Scop *S, + Dependences::AnalyisLevel Level); + + /// @brief Compute the dependence information on-the-fly for the function. + bool runOnFunction(Function &F) override; + + /// @brief Print the dependences for the current function to @p OS. + void print(raw_ostream &OS, const Module *M = nullptr) const override; + + /// @brief Release the internal memory. + void releaseMemory() override { ScopToDepsMap.clear(); } + + /// @brief Register all analyses and transformation required. + void getAnalysisUsage(AnalysisUsage &AU) const override; + +private: + /// @brief Scop to Dependence map for the current function. + ScopToDepsMapTy ScopToDepsMap; +}; + } // End polly namespace. namespace llvm { class PassRegistry; void initializeDependenceInfoPass(llvm::PassRegistry &); +void initializeDependenceInfoWrapperPassPass(llvm::PassRegistry &); } #endif Index: include/polly/LinkAllPasses.h =================================================================== --- include/polly/LinkAllPasses.h +++ include/polly/LinkAllPasses.h @@ -29,6 +29,7 @@ llvm::Pass *createCodePreparationPass(); llvm::Pass *createDeadCodeElimPass(); llvm::Pass *createDependenceInfoPass(); +llvm::Pass *createDependenceInfoWrapperPassPass(); llvm::Pass *createDOTOnlyPrinterPass(); llvm::Pass *createDOTOnlyViewerPass(); llvm::Pass *createDOTPrinterPass(); Index: lib/Analysis/DependenceInfo.cpp =================================================================== --- lib/Analysis/DependenceInfo.cpp +++ lib/Analysis/DependenceInfo.cpp @@ -804,3 +804,61 @@ INITIALIZE_PASS_DEPENDENCY(ScopInfoRegionPass); INITIALIZE_PASS_END(DependenceInfo, "polly-dependences", "Polly - Calculate dependences", false, false) + +//===----------------------------------------------------------------------===// +const Dependences & +DependenceInfoWrapperPass::getDependences(Scop *S, + Dependences::AnalyisLevel Level) { + auto It = ScopToDepsMap.find(S); + if (It != ScopToDepsMap.end()) + if (It->second) + return *It->second.get(); + + return recomputeDependences(S, Level); +} + +const Dependences &DependenceInfoWrapperPass::recomputeDependences( + Scop *S, Dependences::AnalyisLevel Level) { + std::unique_ptr D(new Dependences(S->getSharedIslCtx(), Level)); + D->calculateDependences(*S); + auto Inserted = ScopToDepsMap.insert(std::make_pair(S, std::move(D))); + assert(Inserted.second && "Recomputing Scop for the same scop twice!"); + return *Inserted.first->second; +} + +bool DependenceInfoWrapperPass::runOnFunction(Function &F) { + auto &SI = getAnalysis(); + for (auto &It : SI) + recomputeDependences(It.second.get(), Dependences::AL_Access); + return false; +} + +/// @brief Print the dependences for the given SCoP to @p OS. + +void DependenceInfoWrapperPass::print(raw_ostream &OS, const Module *M) const { + for (auto &It : ScopToDepsMap) { + assert((It.first || It.second) && "Invalid Scop or Dependence object!\n"); + It.second->print(OS); + } +} + +void DependenceInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequiredTransitive(); + AU.setPreservesAll(); +} + +char DependenceInfoWrapperPass::ID = 0; + +Pass *polly::createDependenceInfoWrapperPassPass() { + return new DependenceInfoWrapperPass(); +} + +INITIALIZE_PASS_BEGIN( + DependenceInfoWrapperPass, "polly-function-dependences", + "Polly - Calculate dependences for all the SCoPs of a function", false, + false) +INITIALIZE_PASS_DEPENDENCY(ScopInfoWrapperPass); +INITIALIZE_PASS_END( + DependenceInfoWrapperPass, "polly-function-dependences", + "Polly - Calculate dependences for all the SCoPs of a function", false, + false) Index: lib/Support/RegisterPasses.cpp =================================================================== --- lib/Support/RegisterPasses.cpp +++ lib/Support/RegisterPasses.cpp @@ -148,6 +148,7 @@ initializeCodePreparationPass(Registry); initializeDeadCodeElimPass(Registry); initializeDependenceInfoPass(Registry); + initializeDependenceInfoWrapperPassPass(Registry); initializeJSONExporterPass(Registry); initializeJSONImporterPass(Registry); initializeIslAstInfoPass(Registry);