Index: include/polly/LinkAllPasses.h =================================================================== --- include/polly/LinkAllPasses.h +++ include/polly/LinkAllPasses.h @@ -38,6 +38,7 @@ llvm::Pass *createPollyCanonicalizePass(); llvm::Pass *createScopDetectionPass(); llvm::Pass *createScopInfoRegionPassPass(); +llvm::Pass *createScopInfoWrapperPassPass(); llvm::Pass *createIslAstInfoPass(); llvm::Pass *createCodeGenerationPass(); llvm::Pass *createIslScheduleOptimizerPass(); Index: include/polly/ScopInfo.h =================================================================== --- include/polly/ScopInfo.h +++ include/polly/ScopInfo.h @@ -2509,11 +2509,74 @@ void getAnalysisUsage(AnalysisUsage &AU) const override; }; +//===----------------------------------------------------------------------===// +/// @brief The legacy pass manager's analysis pass to compute scop information +/// for the whole function. +/// +/// This pass will maintain a map of Region to its Scop object for all the +/// top level regions present in the function. +/// This pass is designed to be used by other larger passes such as +/// PolyhedralInfo function pass as currently it is not feasible to schedula a +/// region pass from a function pass in LLVM. +class ScopInfoWrapperPass : public FunctionPass { + +public: + using RegionToScopMapTy = DenseMap>; + using iterator = RegionToScopMapTy::iterator; + using const_iterator = RegionToScopMapTy::const_iterator; + +private: + /// @brief A map of Region to its Scop object containing + /// Polly IR of static control part + RegionToScopMapTy regionToScopMap; + +public: + static char ID; // Pass identification, replacement for typeid + + ScopInfoWrapperPass() : FunctionPass(ID) {} + ~ScopInfoWrapperPass() {} + + /// @brief Get the ScopInfo object for the given Region + Scop *getScop(Region *R) { + auto it = regionToScopMap.find(R); + if (it != regionToScopMap.end()) + return it->second.get(); + else + return nullptr; + } + + const Scop *getScop(Region *R) const { + auto it = regionToScopMap.find(R); + if (it != regionToScopMap.end()) + return it->second.get(); + else + return nullptr; + } + + iterator begin() { return regionToScopMap.begin(); } + iterator end() { return regionToScopMap.end(); } + + /// @brief Calculate all the polyhedral scops for a given function. + bool runOnFunction(Function &F) override; + + void releaseMemory() override { + for (auto &it : regionToScopMap) { + it.second.reset(); + } + regionToScopMap.clear(); + } + + void print(raw_ostream &O, const Module *M = nullptr) const override; + + void getAnalysisUsage(AnalysisUsage &AU) const override; +}; + } // end namespace polly namespace llvm { class PassRegistry; void initializeScopInfoRegionPassPass(llvm::PassRegistry &); +void initializeScopInfoWrapperPassPass(llvm::PassRegistry &); } #endif Index: lib/Analysis/ScopInfo.cpp =================================================================== --- lib/Analysis/ScopInfo.cpp +++ lib/Analysis/ScopInfo.cpp @@ -4872,6 +4872,8 @@ } //===----------------------------------------------------------------------===// +/// Implementation of ScopInfoRegionPass begins here. +// void ScopInfoRegionPass::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); AU.addRequired(); @@ -4926,3 +4928,73 @@ INITIALIZE_PASS_END(ScopInfoRegionPass, "polly-scops", "Polly - Create polyhedral description of Scops", false, false) + +//===----------------------------------------------------------------------===// +/// Implementation of ScopInfoRegion pass ends here. + +//===----------------------------------------------------------------------===// +/// Implementation of ScopInfoWrapperPass begins here. +// +void ScopInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + AU.addRequired(); + AU.addRequired(); + AU.addRequiredTransitive(); + AU.addRequiredTransitive(); + AU.addRequired(); + AU.addRequired(); + AU.setPreservesAll(); +} + +bool ScopInfoWrapperPass::runOnFunction(Function &F) { + auto &SD = getAnalysis(); + Region *R; + + auto &SE = getAnalysis().getSE(); + auto &LI = getAnalysis().getLoopInfo(); + auto &AA = getAnalysis().getAAResults(); + auto const &DL = F.getParent()->getDataLayout(); + auto &DT = getAnalysis().getDomTree(); + auto &AC = getAnalysis().getAssumptionCache(F); + + /// Create polyhedral descripton of scops for all the valid regions of a + /// function. + for (ScopDetection::iterator I = SD.begin(), E = SD.end(); I != E; ++I) { + R = const_cast(*I); + if (!SD.isMaxRegionInScop(*R)) + continue; + + ScopBuilder SB(R, AC, AA, DL, DT, LI, SD, SE); + regionToScopMap.insert(std::make_pair(R, SB.getScop())); + } + return false; +} + +void ScopInfoWrapperPass::print(raw_ostream &OS, const Module *) const { + for (auto &it : regionToScopMap) { + if (it.second) + it.second->print(OS); + } +} + +char ScopInfoWrapperPass::ID = 0; + +Pass *polly::createScopInfoWrapperPassPass() { + return new ScopInfoWrapperPass(); +} + +INITIALIZE_PASS_BEGIN( + ScopInfoWrapperPass, "polly-scops-all", + "Polly - Create polyhedral description of all Scops of a function", false, + false); +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass); +INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker); +INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass); +INITIALIZE_PASS_DEPENDENCY(RegionInfoPass); +INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass); +INITIALIZE_PASS_DEPENDENCY(ScopDetection); +INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass); +INITIALIZE_PASS_END( + ScopInfoWrapperPass, "polly-scops-all", + "Polly - Create polyhedral description of all Scops of a function", false, + false)