Index: polly/trunk/include/polly/ScopInfo.h =================================================================== --- polly/trunk/include/polly/ScopInfo.h +++ polly/trunk/include/polly/ScopInfo.h @@ -63,7 +63,6 @@ class Scop; class ScopStmt; class ScopInfo; -class TempScop; class Comparison; class SCEVAffFunc; @@ -589,10 +588,10 @@ const ScopStmt &operator=(const ScopStmt &) = delete; /// Create the ScopStmt from a BasicBlock. - ScopStmt(Scop &parent, TempScop &tempScop, BasicBlock &bb); + ScopStmt(Scop &parent, BasicBlock &bb); /// Create an overapproximating ScopStmt for the region @p R. - ScopStmt(Scop &parent, TempScop &tempScop, Region &R); + ScopStmt(Scop &parent, Region &R); private: /// Polyhedral description @@ -664,14 +663,12 @@ /// @brief Create the accesses for instructions in @p Block. /// - /// @param tempScop The template SCoP. /// @param Block The basic block for which accesses should be /// created. /// @param isApproximated Flag to indicate blocks that might not be executed, /// hence for which write accesses need to be modeled as /// may-write accesses. - void buildAccesses(TempScop &tempScop, BasicBlock *Block, - bool isApproximated = false); + void buildAccesses(BasicBlock *Block, bool isApproximated = false); /// @brief Detect and mark reductions in the ScopStmt void checkForReductions(); @@ -896,6 +893,9 @@ /// The underlying Region. Region &R; + // Access function of bbs. + AccFuncMapType &AccFuncMap; + /// Flag to indicate that the scheduler actually optimized the SCoP. bool IsOptimized; @@ -1001,20 +1001,12 @@ /// group to ensure the SCoP is executed in an alias free environment. MinMaxVectorPairVectorTy MinMaxAliasGroups; - /// @brief Scop constructor; used by static createFromTempScop - Scop(Region &R, ScalarEvolution &SE, DominatorTree &DT, isl_ctx *ctx, - unsigned MaxLoopDepth); - - /// @brief Initialize this ScopInfo using a TempScop object. - void initFromTempScop(TempScop &TempScop, LoopInfo &LI, ScopDetection &SD, - AliasAnalysis &AA); - - /// Create the static control part with a region, max loop depth of this - /// region and parameters used in this region. - static Scop *createFromTempScop(TempScop &TempScop, LoopInfo &LI, - ScalarEvolution &SE, ScopDetection &SD, - AliasAnalysis &AA, DominatorTree &DT, - isl_ctx *ctx); + /// @brief Scop constructor; invoked from ScopInfo::buildScop. + Scop(Region &R, AccFuncMapType &AccFuncMap, ScalarEvolution &SE, + DominatorTree &DT, isl_ctx *ctx, unsigned MaxLoopDepth); + + /// @brief Initialize this ScopInfo . + void init(LoopInfo &LI, ScopDetection &SD, AliasAnalysis &AA); /// @brief Add loop carried constraints to the header blocks of loops. /// @@ -1057,10 +1049,9 @@ /// it does not need to be represented as a polyhedral statement. /// /// @param BB The basic block to check - /// @param tempScop TempScop returning further information regarding the Scop. /// /// @return True if the basic block is trivial, otherwise false. - static bool isTrivialBB(BasicBlock *BB, TempScop &tempScop); + bool isTrivialBB(BasicBlock *BB); /// @brief Add parameter constraints to @p C that imply a non-empty domain. __isl_give isl_set *addNonEmptyDomainConstraints(__isl_take isl_set *C) const; @@ -1084,17 +1075,15 @@ /// /// @param BB The basic block we build the statement for (or null) /// @param R The region we build the statement for (or null). - /// @param tempScop The temp SCoP we use as model. - ScopStmt *addScopStmt(BasicBlock *BB, Region *R, TempScop &tempScop); + ScopStmt *addScopStmt(BasicBlock *BB, Region *R); - /// @brief Build Schedule and ScopStmts from a given TempScop. + /// @brief Build Schedule and ScopStmts. /// /// @param R The current region traversed. - /// @param TS The temporary scop that is translated into an actual scop. /// @param LI The LoopInfo object. /// @param SD The ScopDetection object. void buildSchedule( - Region *R, TempScop &TS, LoopInfo &LI, ScopDetection &SD, + Region *R, LoopInfo &LI, ScopDetection &SD, DenseMap> &LoopSchedules); /// @name Helper function for printing the Scop. @@ -1111,6 +1100,34 @@ public: ~Scop(); + /// @brief Get all access functions in a BasicBlock + /// + /// @param BB The BasicBlock that containing the access functions. + /// + /// @return All access functions in BB + /// + AccFuncSetType *getAccessFunctions(const BasicBlock *BB) { + AccFuncMapType::iterator at = AccFuncMap.find(BB); + return at != AccFuncMap.end() ? &(at->second) : 0; + } + //@} + + /// @brief Print data access information. + /// + /// @param OS The output stream the access functions is printed to. + /// @param SE The ScalarEvolution to help printing more details. + /// @param LI The LoopInfo that help printing the access functions. + void printIRAccesses(raw_ostream &OS, ScalarEvolution *SE, + LoopInfo *LI) const; + + /// @brief Print the access functions and loop bounds in this Scop. + /// + /// @param OS The output stream the access functions is printed to. + /// @param SE The ScalarEvolution that help printing the access functions. + /// @param LI The LoopInfo that help printing the access functions. + void printIRAccessesDetail(raw_ostream &OS, ScalarEvolution *SE, LoopInfo *LI, + const Region *Reg, unsigned ind) const; + ScalarEvolution *getSE() const; /// @brief Get the count of parameters used in this Scop. @@ -1370,62 +1387,6 @@ return O; } -//===---------------------------------------------------------------------===// -/// @brief Scop represent with llvm objects. -/// -/// A helper class for remembering the parameter number and the max depth in -/// this Scop, and others context. -class TempScop { - // The Region. - Region &R; - - // Access function of bbs. - AccFuncMapType &AccFuncMap; - - friend class ScopInfo; - - explicit TempScop(Region &r, AccFuncMapType &accFuncMap) - : R(r), AccFuncMap(accFuncMap) {} - -public: - ~TempScop(); - - /// @brief Get the maximum Region contained by this Scop. - /// - /// @return The maximum Region contained by this Scop. - Region &getMaxRegion() const { return R; } - - /// @brief Get all access functions in a BasicBlock - /// - /// @param BB The BasicBlock that containing the access functions. - /// - /// @return All access functions in BB - /// - AccFuncSetType *getAccessFunctions(const BasicBlock *BB) { - AccFuncMapType::iterator at = AccFuncMap.find(BB); - return at != AccFuncMap.end() ? &(at->second) : 0; - } - //@} - - /// @brief Print the Temporary Scop information. - /// - /// @param OS The output stream the access functions is printed to. - /// @param SE The ScalarEvolution that help printing Temporary Scop - /// information. - /// @param LI The LoopInfo that help printing the access functions. - void print(raw_ostream &OS, ScalarEvolution *SE, LoopInfo *LI) const; - - /// @brief Print the access functions and loop bounds in this Scop. - /// - /// @param OS The output stream the access functions is printed to. - /// @param SE The ScalarEvolution that help printing the access functions. - /// @param LI The LoopInfo that help printing the access functions. - void printDetail(raw_ostream &OS, ScalarEvolution *SE, LoopInfo *LI, - const Region *Reg, unsigned ind) const; -}; - -typedef std::map TempScopMapType; - ///===---------------------------------------------------------------------===// /// @brief Build the Polly IR (Scop and ScopStmt) on a Region. /// @@ -1456,9 +1417,6 @@ // zero scev every time when we need it. const SCEV *ZeroOffset; - // The TempScop for this region. - TempScop *TempScopOfRegion; - // The Scop Scop *scop; isl_ctx *ctx; @@ -1466,15 +1424,14 @@ // Clear the context. void clear(); - // Build the temporary information of Region R, where R must be a valid part - // of Scop. - TempScop *buildTempScop(Region &R); + // Build the SCoP for Region @p R. + Scop *buildScop(Region &R, DominatorTree &DT); /// @brief Build an instance of IRAccess from the Load/Store instruction. /// /// @param Inst The Load/Store instruction that access the memory /// @param L The parent loop of the instruction - /// @param R The region on which we are going to build a TempScop + /// @param R The region on which to build the data access dictionary. /// @param BoxedLoops The set of loops that are overapproximated in @p R. /// /// @return The IRAccess to describe the access function of the @@ -1525,11 +1482,6 @@ explicit ScopInfo(); ~ScopInfo(); - /// @brief Get the temporay Scop information in LLVM IR for this region. - /// - /// @return The Scop information in LLVM IR represent. - TempScop *getTempScop() const; - /// @brief Try to build the Polly IR of static control part on the current /// SESE-Region. /// Index: polly/trunk/lib/Analysis/ScopInfo.cpp =================================================================== --- polly/trunk/lib/Analysis/ScopInfo.cpp +++ polly/trunk/lib/Analysis/ScopInfo.cpp @@ -738,9 +738,8 @@ Domain = NewDomain; } -void ScopStmt::buildAccesses(TempScop &tempScop, BasicBlock *Block, - bool isApproximated) { - AccFuncSetType *AFS = tempScop.getAccessFunctions(Block); +void ScopStmt::buildAccesses(BasicBlock *Block, bool isApproximated) { + AccFuncSetType *AFS = Parent.getAccessFunctions(Block); if (!AFS) return; @@ -983,7 +982,7 @@ } } -ScopStmt::ScopStmt(Scop &parent, TempScop &tempScop, Region &R) +ScopStmt::ScopStmt(Scop &parent, Region &R) : Parent(parent), BB(nullptr), R(&R), Build(nullptr) { BaseName = getIslCompatibleName("Stmt_", R.getNameStr(), ""); @@ -993,21 +992,21 @@ BasicBlock *EntryBB = R.getEntry(); for (BasicBlock *Block : R.blocks()) { - buildAccesses(tempScop, Block, Block != EntryBB); + buildAccesses(Block, Block != EntryBB); deriveAssumptions(Block); } if (DetectReductions) checkForReductions(); } -ScopStmt::ScopStmt(Scop &parent, TempScop &tempScop, BasicBlock &bb) +ScopStmt::ScopStmt(Scop &parent, BasicBlock &bb) : Parent(parent), BB(&bb), R(nullptr), Build(nullptr) { BaseName = getIslCompatibleName("Stmt_", &bb, ""); buildDomain(); collectSurroundingLoops(); - buildAccesses(tempScop, BB); + buildAccesses(BB); deriveAssumptions(BB); if (DetectReductions) checkForReductions(); @@ -2085,14 +2084,14 @@ return MaxLD - MinLD + 1; } -Scop::Scop(Region &R, ScalarEvolution &ScalarEvolution, DominatorTree &DT, +Scop::Scop(Region &R, AccFuncMapType &AccFuncMap, + ScalarEvolution &ScalarEvolution, DominatorTree &DT, isl_ctx *Context, unsigned MaxLoopDepth) - : DT(DT), SE(&ScalarEvolution), R(R), IsOptimized(false), - HasSingleExitEdge(R.getExitingBlock()), MaxLoopDepth(MaxLoopDepth), - IslCtx(Context), Affinator(this) {} + : DT(DT), SE(&ScalarEvolution), R(R), AccFuncMap(AccFuncMap), + IsOptimized(false), HasSingleExitEdge(R.getExitingBlock()), + MaxLoopDepth(MaxLoopDepth), IslCtx(Context), Affinator(this) {} -void Scop::initFromTempScop(TempScop &TempScop, LoopInfo &LI, ScopDetection &SD, - AliasAnalysis &AA) { +void Scop::init(LoopInfo &LI, ScopDetection &SD, AliasAnalysis &AA) { buildContext(); buildDomains(&R, LI, SD, DT); @@ -2101,7 +2100,7 @@ Loop *L = getLoopSurroundingRegion(R, LI); LoopSchedules[L]; - buildSchedule(&R, TempScop, LI, SD, LoopSchedules); + buildSchedule(&R, LI, SD, LoopSchedules); Schedule = LoopSchedules[L].first; realignParams(); @@ -2111,18 +2110,6 @@ buildAliasChecks(AA); } -Scop *Scop::createFromTempScop(TempScop &TempScop, LoopInfo &LI, - ScalarEvolution &SE, ScopDetection &SD, - AliasAnalysis &AA, DominatorTree &DT, - isl_ctx *ctx) { - auto &R = TempScop.getMaxRegion(); - auto MaxLoopDepth = getMaxLoopDepthInRegion(R, LI, SD); - auto S = new Scop(R, SE, DT, ctx, MaxLoopDepth); - S->initFromTempScop(TempScop, LI, SD, AA); - - return S; -} - Scop::~Scop() { isl_set_free(Context); isl_set_free(AssumedContext); @@ -2450,8 +2437,8 @@ ScalarEvolution *Scop::getSE() const { return SE; } -bool Scop::isTrivialBB(BasicBlock *BB, TempScop &tempScop) { - if (tempScop.getAccessFunctions(BB) && !isErrorBlock(*BB)) +bool Scop::isTrivialBB(BasicBlock *BB) { + if (getAccessFunctions(BB) && !isErrorBlock(*BB)) return false; return true; @@ -2515,15 +2502,15 @@ return isl_multi_union_pw_aff_from_union_pw_multi_aff(Data.Res); } -ScopStmt *Scop::addScopStmt(BasicBlock *BB, Region *R, TempScop &tempScop) { +ScopStmt *Scop::addScopStmt(BasicBlock *BB, Region *R) { ScopStmt *Stmt; if (BB) { - Stmts.emplace_back(*this, tempScop, *BB); + Stmts.emplace_back(*this, *BB); Stmt = &Stmts.back(); StmtMap[BB] = Stmt; } else { assert(R && "Either basic block or a region expected."); - Stmts.emplace_back(*this, tempScop, *R); + Stmts.emplace_back(*this, *R); Stmt = &Stmts.back(); for (BasicBlock *BB : R->blocks()) StmtMap[BB] = Stmt; @@ -2532,7 +2519,7 @@ } void Scop::buildSchedule( - Region *R, TempScop &TS, LoopInfo &LI, ScopDetection &SD, + Region *R, LoopInfo &LI, ScopDetection &SD, DenseMap> &LoopSchedules) { ReversePostOrderTraversal RTraversal(R); @@ -2541,7 +2528,7 @@ if (RN->isSubRegion()) { Region *SubRegion = RN->getNodeAs(); if (!SD.isNonAffineSubRegion(SubRegion, &getRegion())) { - buildSchedule(SubRegion, TS, LI, SD, LoopSchedules); + buildSchedule(SubRegion, LI, SD, LoopSchedules); continue; } } @@ -2552,13 +2539,13 @@ LSchedulePair.second += getNumBlocksInRegionNode(RN); BasicBlock *BB = getRegionNodeBasicBlock(RN); - if (RN->isSubRegion() || !isTrivialBB(BB, TS)) { + if (RN->isSubRegion() || !isTrivialBB(BB)) { ScopStmt *Stmt; if (RN->isSubRegion()) - Stmt = addScopStmt(nullptr, RN->getNodeAs(), TS); + Stmt = addScopStmt(nullptr, RN->getNodeAs()); else - Stmt = addScopStmt(BB, nullptr, TS); + Stmt = addScopStmt(BB, nullptr); auto *UDomain = isl_union_set_from_set(Stmt->getDomain()); auto *StmtSchedule = isl_schedule_from_domain(UDomain); @@ -2593,18 +2580,16 @@ return StmtMapIt->second; } -//===----------------------------------------------------------------------===// -// TempScop implementation -TempScop::~TempScop() {} - -void TempScop::print(raw_ostream &OS, ScalarEvolution *SE, LoopInfo *LI) const { +void Scop::printIRAccesses(raw_ostream &OS, ScalarEvolution *SE, + LoopInfo *LI) const { OS << "Scop: " << R.getNameStr() << "\n"; - printDetail(OS, SE, LI, &R, 0); + printIRAccessesDetail(OS, SE, LI, &R, 0); } -void TempScop::printDetail(raw_ostream &OS, ScalarEvolution *SE, LoopInfo *LI, - const Region *CurR, unsigned ind) const { +void Scop::printIRAccessesDetail(raw_ostream &OS, ScalarEvolution *SE, + LoopInfo *LI, const Region *CurR, + unsigned ind) const { // FIXME: Print other details rather than memory accesses. for (const auto &CurBlock : CurR->blocks()) { AccFuncMapType::const_iterator AccSetIt = AccFuncMap.find(CurBlock); @@ -2891,8 +2876,9 @@ Accs.insert(Accs.end(), Functions.begin(), Functions.end()); } -TempScop *ScopInfo::buildTempScop(Region &R) { - TempScop *TScop = new TempScop(R, AccFuncMap); +Scop *ScopInfo::buildScop(Region &R, DominatorTree &DT) { + unsigned MaxLoopDepth = getMaxLoopDepthInRegion(R, *LI, *SD); + Scop *S = new Scop(R, AccFuncMap, *SE, DT, ctx, MaxLoopDepth); buildAccessFunctions(R, R); @@ -2906,27 +2892,22 @@ if (!R.getExitingBlock()) buildAccessFunctions(R, *R.getExit(), nullptr, /* IsExitBlock */ true); - return TScop; + S->init(*LI, *SD, *AA); + return S; } -TempScop *ScopInfo::getTempScop() const { return TempScopOfRegion; } - void ScopInfo::print(raw_ostream &OS, const Module *) const { - if (TempScopOfRegion) - TempScopOfRegion->print(OS, SE, LI); - - if (scop) - scop->print(OS); - else + if (!scop) { OS << "Invalid Scop!\n"; + return; + } + + scop->printIRAccesses(OS, SE, LI); + scop->print(OS); } void ScopInfo::clear() { AccFuncMap.clear(); - if (TempScopOfRegion) - delete TempScopOfRegion; - TempScopOfRegion = nullptr; - if (scop) { delete scop; scop = 0; @@ -2934,7 +2915,7 @@ } //===----------------------------------------------------------------------===// -ScopInfo::ScopInfo() : RegionPass(ID), TempScopOfRegion(nullptr), scop(0) { +ScopInfo::ScopInfo() : RegionPass(ID), scop(0) { ctx = isl_ctx_alloc(); isl_options_set_on_error(ctx, ISL_ON_ERROR_ABORT); } @@ -2969,17 +2950,7 @@ DominatorTree &DT = getAnalysis().getDomTree(); ZeroOffset = SE->getConstant(TD->getIntPtrType(F->getContext()), 0); - assert(!TempScopOfRegion && "Build the TempScop only once"); - TempScopOfRegion = buildTempScop(*R); - - // This region is no Scop. - if (!TempScopOfRegion) { - scop = nullptr; - return false; - } - - scop = - Scop::createFromTempScop(*TempScopOfRegion, *LI, *SE, *SD, *AA, DT, ctx); + scop = buildScop(*R, DT); DEBUG(scop->print(dbgs()));