diff --git a/polly/include/polly/ScopInfo.h b/polly/include/polly/ScopInfo.h index e426f283ddf9..d0a1ab6d6e7d 100644 --- a/polly/include/polly/ScopInfo.h +++ b/polly/include/polly/ScopInfo.h @@ -2670,17 +2670,10 @@ public: raw_ostream &operator<<(raw_ostream &OS, const Scop &scop); class ScopInfo { -public: - using RegionToScopMapTy = MapVector>; - using reverse_iterator = RegionToScopMapTy::reverse_iterator; - using const_reverse_iterator = RegionToScopMapTy::const_reverse_iterator; - using iterator = RegionToScopMapTy::iterator; - using const_iterator = RegionToScopMapTy::const_iterator; - private: /// A map of Region to its Scop object containing /// Polly IR of static control part. - RegionToScopMapTy RegionToScopMap; + llvm::SmallDenseMap> RegionToScopMap; const DataLayout &DL; ScopDetection &SD; ScalarEvolution &SE; @@ -2701,47 +2694,12 @@ public: /// the scop object. If the given region is a subregion, return a /// nullptr. Top level region containing the entry block of a function /// is not considered in the scop creation. - Scop *getScop(Region *R) const { - auto MapIt = RegionToScopMap.find(R); - if (MapIt != RegionToScopMap.end()) - return MapIt->second.get(); - return nullptr; - } + Scop *getScop(const Region *R); /// Recompute the Scop-Information for a function. /// /// This invalidates any iterators. - void recompute(); - - /// Handle invalidation explicitly - bool invalidate(Function &F, const PreservedAnalyses &PA, - FunctionAnalysisManager::Invalidator &Inv); - - iterator begin() { return RegionToScopMap.begin(); } - iterator end() { return RegionToScopMap.end(); } - const_iterator begin() const { return RegionToScopMap.begin(); } - const_iterator end() const { return RegionToScopMap.end(); } - reverse_iterator rbegin() { return RegionToScopMap.rbegin(); } - reverse_iterator rend() { return RegionToScopMap.rend(); } - const_reverse_iterator rbegin() const { return RegionToScopMap.rbegin(); } - const_reverse_iterator rend() const { return RegionToScopMap.rend(); } - bool empty() const { return RegionToScopMap.empty(); } -}; - -struct ScopInfoAnalysis : AnalysisInfoMixin { - static AnalysisKey Key; - - using Result = ScopInfo; - - Result run(Function &, FunctionAnalysisManager &); -}; - -struct ScopInfoPrinterPass final : PassInfoMixin { - ScopInfoPrinterPass(raw_ostream &OS) : Stream(OS) {} - - PreservedAnalyses run(Function &, FunctionAnalysisManager &); - - raw_ostream &Stream; + void invalidate(); }; } // end namespace polly diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp index bf993a27dd17..d3aaa7840ae8 100644 --- a/polly/lib/Analysis/ScopInfo.cpp +++ b/polly/lib/Analysis/ScopInfo.cpp @@ -2579,73 +2579,30 @@ void updateLoopCountStatistic(ScopDetection::LoopStats Stats, ScopInfo::ScopInfo(const DataLayout &DL, ScopDetection &SD, ScalarEvolution &SE, LoopInfo &LI, AliasAnalysis &AA, DominatorTree &DT, AssumptionCache &AC, OptimizationRemarkEmitter &ORE) - : DL(DL), SD(SD), SE(SE), LI(LI), AA(AA), DT(DT), AC(AC), ORE(ORE) { - recompute(); -} + : DL(DL), SD(SD), SE(SE), LI(LI), AA(AA), DT(DT), AC(AC), ORE(ORE) {} -void ScopInfo::recompute() { - RegionToScopMap.clear(); - /// Create polyhedral description of scops for all the valid regions of a - /// function. - for (auto &It : SD) { - Region *R = const_cast(It); - if (!SD.isMaxRegionInScop(*R)) - continue; +Scop *ScopInfo::getScop(const Region *R) { + auto &&[It, Inserted] = RegionToScopMap.try_emplace(R); + if (Inserted && SD.isMaxRegionInScop(*R)) { + ScopBuilder SB(const_cast(R), AC, AA, DL, DT, LI, SD, SE, ORE); + It->second = SB.getScop(); + Scop *S = It->second.get(); - ScopBuilder SB(R, AC, AA, DL, DT, LI, SD, SE, ORE); - std::unique_ptr S = SB.getScop(); - if (!S) - continue; #if !defined(NDEBUG) || defined(LLVM_ENABLE_STATS) - ScopDetection::LoopStats Stats = - ScopDetection::countBeneficialLoops(&S->getRegion(), SE, LI, 0); - updateLoopCountStatistic(Stats, S->getStatistics()); + if (S) { + ScopDetection::LoopStats Stats = + ScopDetection::countBeneficialLoops(&S->getRegion(), SE, LI, 0); + updateLoopCountStatistic(Stats, S->getStatistics()); + } #endif - bool Inserted = RegionToScopMap.insert({R, std::move(S)}).second; - assert(Inserted && "Building Scop for the same region twice!"); - (void)Inserted; + + return S; } + + return It->second.get(); } -bool ScopInfo::invalidate(Function &F, const PreservedAnalyses &PA, - FunctionAnalysisManager::Invalidator &Inv) { - // Check whether the analysis, all analyses on functions have been preserved - // or anything we're holding references to is being invalidated - auto PAC = PA.getChecker(); - return !(PAC.preserved() || PAC.preservedSet>()) || - Inv.invalidate(F, PA) || - Inv.invalidate(F, PA) || - Inv.invalidate(F, PA) || - Inv.invalidate(F, PA) || - Inv.invalidate(F, PA) || - Inv.invalidate(F, PA); -} - -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(); - auto &ORE = FAM.getResult(F); - return {DL, SD, SE, LI, AA, DT, AC, ORE}; -} - -PreservedAnalyses ScopInfoPrinterPass::run(Function &F, - FunctionAnalysisManager &FAM) { - auto &SI = FAM.getResult(F); - // Since the legacy PM processes Scops in bottom up, we print them in reverse - // order here to keep the output persistent - for (auto &It : reverse(SI)) { - if (It.second) - It.second->print(Stream, PollyPrintInstructions); - else - Stream << "Invalid Scop!\n"; - } - return PreservedAnalyses::all(); +void ScopInfo::invalidate() { + // Recompute all SCoPs on-demand + RegionToScopMap.clear(); } diff --git a/polly/lib/Pass/PhaseManager.cpp b/polly/lib/Pass/PhaseManager.cpp index 5e716ebc91af..5944dfb4d271 100644 --- a/polly/lib/Pass/PhaseManager.cpp +++ b/polly/lib/Pass/PhaseManager.cpp @@ -156,18 +156,18 @@ public: } } - SmallPriorityWorklist Worklist; - for (auto &[R, S] : Info) - if (S) - Worklist.insert(R); + SmallPriorityWorklist Worklist; + for (const Region *R : SD) + Worklist.insert(R); TargetTransformInfo &TTI = FAM.getResult(F); while (!Worklist.empty()) { - Region *R = Worklist.pop_back_val(); + const Region *R = Worklist.pop_back_val(); Scop *S = Info.getScop(R); if (!S) { - // This can happen if codegenning of a previous SCoP made this region - // not-a-SCoP anymore. + // This can happen if the region is not maximal, is not determined a + // valid SCoP by ScopBuilder, or codegenning of a previous SCoP made + // this region not-a-SCoP anymore. POLLY_DEBUG(dbgs() << "SCoP in Region '" << *R << "' disappeared"); continue; } @@ -253,10 +253,10 @@ public: if (ModifiedByCodeGen) { ModifiedIR = true; - // For all regions, create new polly::Scop objects because the old ones - // refere to invalidated LLVM-IR. - // FIXME: Adds all SCoPs again to statistics - Info.recompute(); + // Discard old polly::Scop objects because they may refer to invalidated + // LLVM-IR instructions and SCEV expressions. ScopInfo will recreate + // them on demand. + Info.invalidate(); } }