Index: include/polly/PolyhedralInfo.h =================================================================== --- include/polly/PolyhedralInfo.h +++ include/polly/PolyhedralInfo.h @@ -27,7 +27,7 @@ namespace polly { class Scop; -class ScopInfoWrapperPass; +class ScopInfo; class DependenceInfoWrapperPass; class PolyhedralInfo : public llvm::FunctionPass { @@ -87,7 +87,7 @@ bool checkParallel(llvm::Loop *L, __isl_give isl_pw_aff **MinDepDistPtr = nullptr) const; - ScopInfoWrapperPass *SI; + ScopInfo *SI; DependenceInfoWrapperPass *DI; }; Index: include/polly/ScopInfo.h =================================================================== --- include/polly/ScopInfo.h +++ include/polly/ScopInfo.h @@ -2661,16 +2661,7 @@ void getAnalysisUsage(AnalysisUsage &AU) const override; }; -//===----------------------------------------------------------------------===// -/// The legacy pass manager's analysis pass to compute scop information -/// for the whole function. -/// -/// This pass will maintain a map of the maximal region within a scop to its -/// scop object for all the feasible scops present in a function. -/// This pass is an alternative to the ScopInfoRegionPass in order to avoid a -/// region pass manager. -class ScopInfoWrapperPass : public FunctionPass { - +class ScopInfo { public: using RegionToScopMapTy = DenseMap>; using iterator = RegionToScopMapTy::iterator; @@ -2682,10 +2673,9 @@ RegionToScopMapTy RegionToScopMap; public: - static char ID; // Pass identification, replacement for typeid - - ScopInfoWrapperPass() : FunctionPass(ID) {} - ~ScopInfoWrapperPass() {} + ScopInfo(const DataLayout &DL, ScopDetection &SD, ScalarEvolution &SE, + LoopInfo &LI, AliasAnalysis &AA, DominatorTree &DT, + AssumptionCache &AC); /// Get the Scop object for the given Region /// @@ -2704,11 +2694,44 @@ iterator end() { return RegionToScopMap.end(); } const_iterator begin() const { return RegionToScopMap.begin(); } const_iterator end() const { return RegionToScopMap.end(); } +}; + +struct ScopInfoAnalysis : public AnalysisInfoMixin { + static AnalysisKey Key; + using Result = ScopInfo; + Result run(Function &, FunctionAnalysisManager &); +}; + +struct ScopInfoPrinterPass : public PassInfoMixin { + ScopInfoPrinterPass(raw_ostream &O) : Stream(O) {} + PreservedAnalyses run(Function &, FunctionAnalysisManager &); + raw_ostream &Stream; +}; + +//===----------------------------------------------------------------------===// +/// The legacy pass manager's analysis pass to compute scop information +/// for the whole function. +/// +/// This pass will maintain a map of the maximal region within a scop to its +/// scop object for all the feasible scops present in a function. +/// This pass is an alternative to the ScopInfoRegionPass in order to avoid a +/// region pass manager. +class ScopInfoWrapperPass : public FunctionPass { + std::unique_ptr Result; + +public: + ScopInfoWrapperPass() : FunctionPass(ID) {} + ~ScopInfoWrapperPass() = default; + + static char ID; // Pass identification, replacement for typeid + + ScopInfo *getSI() { return Result.get(); } + const ScopInfo *getSI() const { return Result.get(); } /// Calculate all the polyhedral scops for a given function. bool runOnFunction(Function &F) override; - void releaseMemory() override { RegionToScopMap.clear(); } + void releaseMemory() override { Result.reset(); } void print(raw_ostream &O, const Module *M = nullptr) const override; Index: lib/Analysis/DependenceInfo.cpp =================================================================== --- lib/Analysis/DependenceInfo.cpp +++ lib/Analysis/DependenceInfo.cpp @@ -908,7 +908,7 @@ } bool DependenceInfoWrapperPass::runOnFunction(Function &F) { - auto &SI = getAnalysis(); + auto &SI = *getAnalysis().getSI(); for (auto &It : SI) { assert(It.second && "Invalid SCoP object!"); recomputeDependences(It.second.get(), Dependences::AL_Access); Index: lib/Analysis/PolyhedralInfo.cpp =================================================================== --- lib/Analysis/PolyhedralInfo.cpp +++ lib/Analysis/PolyhedralInfo.cpp @@ -53,7 +53,7 @@ bool PolyhedralInfo::runOnFunction(Function &F) { DI = &getAnalysis(); - SI = &getAnalysis(); + SI = getAnalysis().getSI(); return false; } Index: lib/Analysis/ScopInfo.cpp =================================================================== --- lib/Analysis/ScopInfo.cpp +++ lib/Analysis/ScopInfo.cpp @@ -17,10 +17,10 @@ // //===----------------------------------------------------------------------===// -#include "polly/ScopInfo.h" #include "polly/LinkAllPasses.h" #include "polly/Options.h" #include "polly/ScopBuilder.h" +#include "polly/ScopInfo.h" #include "polly/Support/GICHelper.h" #include "polly/Support/SCEVValidator.h" #include "polly/Support/ScopHelper.h" @@ -4719,6 +4719,52 @@ false) //===----------------------------------------------------------------------===// +ScopInfo::ScopInfo(const DataLayout &DL, ScopDetection &SD, ScalarEvolution &SE, + LoopInfo &LI, AliasAnalysis &AA, DominatorTree &DT, + AssumptionCache &AC) { + /// Create polyhedral descripton of scops for all the valid regions of a + /// function. + for (auto &It : SD) { + Region *R = const_cast(It); + if (!SD.isMaxRegionInScop(*R)) + continue; + + ScopBuilder SB(R, AC, AA, DL, DT, LI, SD, SE); + std::unique_ptr S = SB.getScop(); + if (!S) + continue; + bool Inserted = RegionToScopMap.insert({R, std::move(S)}).second; + assert(Inserted && "Building Scop for the same region twice!"); + (void)Inserted; + } +} + +AnalysisKey ScopInfoAnalysis::Key; + +ScopInfoAnalysis::Result ScopInfoAnalysis::run(Function &F, + FunctionAnalysisManager &FAM) { + auto &SD = FAM.getResult(F); + auto &SE = FAM.getResult(F); + auto &LI = FAM.getResult(F); + auto &AA = FAM.getResult(F); + auto &DT = FAM.getResult(F); + auto &AC = FAM.getResult(F); + auto &DL = F.getParent()->getDataLayout(); + return {DL, SD, SE, LI, AA, DT, AC}; +} + +PreservedAnalyses ScopInfoPrinterPass::run(Function &F, + FunctionAnalysisManager &FAM) { + auto &SI = FAM.getResult(F); + for (auto &It : SI) { + if (It.second) + It.second->print(Stream); + else + Stream << "Invalid Scop!\n"; + } + return PreservedAnalyses::all(); +} + void ScopInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); AU.addRequired(); @@ -4732,7 +4778,6 @@ bool ScopInfoWrapperPass::runOnFunction(Function &F) { auto &SD = getAnalysis().getSD(); - auto &SE = getAnalysis().getSE(); auto &LI = getAnalysis().getLoopInfo(); auto &AA = getAnalysis().getAAResults(); @@ -4740,27 +4785,12 @@ auto &DT = getAnalysis().getDomTree(); auto &AC = getAnalysis().getAssumptionCache(F); - /// Create polyhedral descripton of scops for all the valid regions of a - /// function. - for (auto &It : SD) { - Region *R = const_cast(It); - if (!SD.isMaxRegionInScop(*R)) - continue; - - ScopBuilder SB(R, AC, AA, DL, DT, LI, SD, SE); - std::unique_ptr S = SB.getScop(); - if (!S) - continue; - bool Inserted = - RegionToScopMap.insert(std::make_pair(R, std::move(S))).second; - assert(Inserted && "Building Scop for the same region twice!"); - (void)Inserted; - } + Result.reset(new ScopInfo{DL, SD, SE, LI, AA, DT, AC}); return false; } void ScopInfoWrapperPass::print(raw_ostream &OS, const Module *) const { - for (auto &It : RegionToScopMap) { + for (auto &It : *Result) { if (It.second) It.second->print(OS); else