Index: include/polly/ScopInfo.h =================================================================== --- include/polly/ScopInfo.h +++ include/polly/ScopInfo.h @@ -22,7 +22,7 @@ #include "polly/ScopDetection.h" -#include "llvm/Analysis/RegionPass.h" +#include "llvm/Pass.h" #include "isl/ctx.h" @@ -740,11 +740,6 @@ /// group to ensure the SCoP is executed in an alias free environment. MinMaxVectorVectorTy MinMaxAliasGroups; - /// Create the static control part with a region, max loop depth of this - /// region and parameters used in this region. - Scop(TempScop &TempScop, LoopInfo &LI, ScalarEvolution &SE, ScopDetection &SD, - isl_ctx *ctx); - /// @brief Check if a basic block is trivial. /// /// A trivial basic block does not contain any useful calculation. Therefore, @@ -799,6 +794,22 @@ friend class ScopInfo; public: + /// Create the static control part with a region, max loop depth of this + /// region and parameters used in this region. + Scop(TempScop &TempScop, LoopInfo &LI, ScalarEvolution &SE, ScopDetection &SD, + isl_ctx *ctx); + + /// @brief Create a SCoP from @p Other by moving all its members over. + Scop(Scop &&Other) + : SE(Other.SE), R(Other.R), IsOptimized(Other.IsOptimized), + MaxLoopDepth(Other.MaxLoopDepth), Stmts(std::move(Other.Stmts)), + Parameters(std::move(Other.Parameters)), + ParameterIds(std::move(Other.ParameterIds)), IslCtx(Other.IslCtx), + StmtMap(std::move(Other.StmtMap)), Context(Other.Context), + ScopArrayInfoMap(std::move(Other.ScopArrayInfoMap)), + AssumedContext(Other.AssumedContext), + MinMaxAliasGroups(std::move(Other.MinMaxAliasGroups)){}; + ~Scop(); ScalarEvolution *getSE() const; @@ -1005,47 +1016,42 @@ ///===---------------------------------------------------------------------===// /// @brief Build the Polly IR (Scop and ScopStmt) on a Region. /// -class ScopInfo : public RegionPass { - //===-------------------------------------------------------------------===// +class ScopInfo : public FunctionPass { +public: + /// @brief Type for a vector of SCoPs. + using ScopVectorTy = SmallVector; + + /// @brief Iterator type for a SCoP vector. + using iterator = ScopVectorTy::iterator; + +private: ScopInfo(const ScopInfo &) = delete; const ScopInfo &operator=(const ScopInfo &) = delete; - // The Scop - Scop *scop; - isl_ctx *ctx; + /// @brief The SCoPs build in this function. + ScopVectorTy Scops; - void clear() { - if (scop) { - delete scop; - scop = 0; - } - } + /// @brief The isl context used to alloca __all__ isl objects in the SCoP. + isl_ctx *ctx; public: static char ID; explicit ScopInfo(); ~ScopInfo(); - /// @brief Try to build the Polly IR of static control part on the current - /// SESE-Region. + /// @brief Iterator interface to access all SCoPs in this function. /// - /// @return If the current region is a valid for a static control part, - /// return the Polly IR representing this static control part, - /// return null otherwise. - Scop *getScop() { return scop; } - const Scop *getScop() const { return scop; } + ///{ + iterator begin() { return Scops.begin(); } + iterator end() { return Scops.end(); } + ///} - /// @name RegionPass interface + /// @name FunctionPass interface //@{ - virtual bool runOnRegion(Region *R, RGPassManager &RGM); - virtual void getAnalysisUsage(AnalysisUsage &AU) const; - virtual void releaseMemory() { clear(); } - virtual void print(raw_ostream &OS, const Module *) const { - if (scop) - scop->print(OS); - else - OS << "Invalid Scop!\n"; - } + virtual bool runOnFunction(Function &F) override; + virtual void getAnalysisUsage(AnalysisUsage &AU) const override; + virtual void releaseMemory() override; + virtual void print(raw_ostream &OS, const Module *) const override; //@} }; Index: include/polly/ScopPass.h =================================================================== --- include/polly/ScopPass.h +++ include/polly/ScopPass.h @@ -18,7 +18,7 @@ #ifndef POLLY_SCOP_PASS_H #define POLLY_SCOP_PASS_H -#include "llvm/Analysis/RegionPass.h" +#include "llvm/Pass.h" using namespace llvm; @@ -26,19 +26,20 @@ namespace polly { class Scop; +class ScopInfo; -/// ScopPass - This class adapts the RegionPass interface to allow convenient +/// ScopPass - This class adapts the FunctionPass interface to allow convenient /// creation of passes that operate on the Polly IR. Instead of overriding -/// runOnRegion, subclasses override runOnScop. -class ScopPass : public RegionPass { - Scop *S; +/// runOnFunction, subclasses override runOnScop. +class ScopPass : public FunctionPass { + + /// @brief The ScopInfo class that builds the SCoPs. + ScopInfo *SI; protected: - explicit ScopPass(char &ID) : RegionPass(ID), S(0) {} + explicit ScopPass(char &ID) : FunctionPass(ID) {} - /// runOnScop - This method must be overloaded to perform the - /// desired Polyhedral transformation or analysis. - /// + /// @brief Run method for all ScopPass subclasses. Called for each SCoP once. virtual bool runOnScop(Scop &S) = 0; /// @brief Print method for SCoPs. @@ -50,7 +51,7 @@ virtual void getAnalysisUsage(AnalysisUsage &AU) const override; private: - bool runOnRegion(Region *R, RGPassManager &RGM) override; + bool runOnFunction(Function &F) override; void print(raw_ostream &OS, const Module *) const override; }; Index: lib/Analysis/ScopInfo.cpp =================================================================== --- lib/Analysis/ScopInfo.cpp +++ lib/Analysis/ScopInfo.cpp @@ -1969,19 +1969,16 @@ } //===----------------------------------------------------------------------===// -ScopInfo::ScopInfo() : RegionPass(ID), scop(0) { +ScopInfo::ScopInfo() : FunctionPass(ID) { ctx = isl_ctx_alloc(); isl_options_set_on_error(ctx, ISL_ON_ERROR_ABORT); } -ScopInfo::~ScopInfo() { - clear(); - isl_ctx_free(ctx); -} +ScopInfo::~ScopInfo() { isl_ctx_free(ctx); } void ScopInfo::getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequiredTransitive(); AU.addRequired(); - AU.addRequired(); AU.addRequired(); AU.addRequired(); AU.addRequired(); @@ -1989,53 +1986,53 @@ AU.setPreservesAll(); } -bool ScopInfo::runOnRegion(Region *R, RGPassManager &RGM) { +bool ScopInfo::runOnFunction(Function &F) { LoopInfo &LI = getAnalysis().getLoopInfo(); AliasAnalysis &AA = getAnalysis(); ScopDetection &SD = getAnalysis(); ScalarEvolution &SE = getAnalysis(); - TempScop *tempScop = getAnalysis().getTempScop(R); + for (ScopDetection::iterator I = SD.begin(), E = SD.end(); I != E; ++I) { + const Region *R = *I; + if (!SD.isMaxRegionInScop(*R)) + continue; - // This region is no Scop. - if (!tempScop) { - scop = nullptr; - return false; - } + TempScop *tempScop = getAnalysis().getTempScop(R); + assert(tempScop && "A valid region should have a TempScop"); - scop = new Scop(*tempScop, LI, SE, SD, ctx); + Scops.emplace_back(*tempScop, LI, SE, SD, ctx); + Scop &S = Scops.back(); - if (!PollyUseRuntimeAliasChecks) { - // Statistics. - ++ScopFound; - if (scop->getMaxLoopDepth() > 0) - ++RichScopFound; - return false; - } + if (PollyUseRuntimeAliasChecks && !S.buildAliasGroups(AA)) { + DEBUG(dbgs() << "\n\nNOTE: Run time checks for " << S.getNameStr() + << " could not be created as the number of parameters " + "involved is too high. The SCoP will be " + "dismissed.\nUse:\n\t--polly-rtc-max-parameters=X\nto " + "adjust the maximal number of parameters but be advised " + "that the compile time might increase " + "exponentially.\n\n"); - // If a problem occurs while building the alias groups we need to delete - // this SCoP and pretend it wasn't valid in the first place. - if (scop->buildAliasGroups(AA)) { + Scops.pop_back(); + continue; + } + + // If a problem occurs while building the alias groups we need to delete + // this SCoP and pretend it wasn't valid in the first place. // Statistics. ++ScopFound; - if (scop->getMaxLoopDepth() > 0) + if (S.getMaxLoopDepth() > 0) ++RichScopFound; - return false; } - DEBUG(dbgs() - << "\n\nNOTE: Run time checks for " << scop->getNameStr() - << " could not be created as the number of parameters involved is too " - "high. The SCoP will be " - "dismissed.\nUse:\n\t--polly-rtc-max-parameters=X\nto adjust the " - "maximal number of parameters but be advised that the compile time " - "might increase exponentially.\n\n"); - - delete scop; - scop = nullptr; return false; } +void ScopInfo::print(raw_ostream &OS, const Module *) const { + OS << "ScopInfo: Build " << Scops.size() << " SCoPs\n"; +} + +void ScopInfo::releaseMemory() { Scops.clear(); } + char ScopInfo::ID = 0; Pass *polly::createScopInfoPass() { return new ScopInfo(); } Index: lib/Analysis/ScopPass.cpp =================================================================== --- lib/Analysis/ScopPass.cpp +++ lib/Analysis/ScopPass.cpp @@ -17,18 +17,18 @@ using namespace llvm; using namespace polly; -bool ScopPass::runOnRegion(Region *R, RGPassManager &RGM) { - S = nullptr; +bool ScopPass::runOnFunction(Function &F) { + SI = &getAnalysis(); - if ((S = getAnalysis().getScop())) - return runOnScop(*S); + for (Scop &S : *SI) + runOnScop(S); return false; } void ScopPass::print(raw_ostream &OS, const Module *M) const { - if (S) - printScop(OS, *S); + for (Scop &S : *SI) + printScop(OS, S); } void ScopPass::getAnalysisUsage(AnalysisUsage &AU) const { Index: lib/Transform/ScheduleOptimizer.cpp =================================================================== --- lib/Transform/ScheduleOptimizer.cpp +++ lib/Transform/ScheduleOptimizer.cpp @@ -204,7 +204,7 @@ using llvm::Pass::doFinalization; - virtual bool doFinalization() override { + virtual bool doFinalization(Module &) override { isl_schedule_free(LastSchedule); LastSchedule = nullptr; return true;