Index: include/polly/ScopInfo.h =================================================================== --- include/polly/ScopInfo.h +++ include/polly/ScopInfo.h @@ -271,6 +271,12 @@ ScopStmt *Statement); public: + // @brief Common constructor to set the most basic properties. + MemoryAccess(AccessType AccType, Instruction *AccInst, ScopStmt *Statement); + + // @brief Setup the object using data of an IRAccess. + void init(const IRAccess &Access, const ScopArrayInfo *SAI, int Identifier); + /// @brief Create a memory access from an access in LLVM-IR. /// /// @param Access The memory access. @@ -279,8 +285,9 @@ /// @param SAI The ScopArrayInfo object for this base pointer. /// @param Identifier An identifier that is unique for all memory accesses /// belonging to the same scop statement. - MemoryAccess(const IRAccess &Access, Instruction *AccInst, - ScopStmt *Statement, const ScopArrayInfo *SAI, int Identifier); + static MemoryAccess *create(const IRAccess &Access, Instruction *AccInst, + ScopStmt *Statement, const ScopArrayInfo *SAI, + int Identifier); ~MemoryAccess(); @@ -421,13 +428,27 @@ ScopStmt(const ScopStmt &) = delete; const ScopStmt &operator=(const ScopStmt &) = delete; - /// Create the ScopStmt from a BasicBlock. - ScopStmt(Scop &parent, TempScop &tempScop, const Region &CurRegion, - BasicBlock &bb, SmallVectorImpl &NestLoops); + /// @brief Common constructor for all ScopStmts to set the fundamental + /// properties. + ScopStmt(Scop &parent, ArrayRef OuterLoops); + + /// @brief Initialize this ScopStmt using an overapproximating TempScop + /// object. + void initFromRegion(TempScop &tempScop, const Region &CurRegion, Region &R); + + /// @brief Create an overapproximating ScopStmt for the region @p R. + static ScopStmt *createFromRegion(Scop &parent, TempScop &tempScop, + const Region &CurRegion, Region &R, + ArrayRef OuterLoops); - /// Create an overapproximating ScopStmt for the region @p R. - ScopStmt(Scop &parent, TempScop &tempScop, const Region &CurRegion, Region &R, - SmallVectorImpl &NestLoops); + /// @brief Initialize this ScopStmt using a TempScop object. + void initFromBasicBlock(TempScop &tempScop, const Region &CurRegion, + BasicBlock &BB); + + /// @brief Create the ScopStmt from a BasicBlock. + static ScopStmt *createFromBasicBlock(Scop &parent, TempScop &tempScop, + const Region &CurRegion, BasicBlock &BB, + ArrayRef OuterLoops); private: /// Polyhedral description @@ -822,10 +843,17 @@ /// 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, isl_ctx *ctx, unsigned MaxLoopDepth); + + /// @brief Initialize this ScopInfo using a TempScop object. + void initFromTempScop(TempScop &TempScop, LoopInfo &LI, ScopDetection &SD); + /// 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); + static Scop *createFromTempScop(TempScop &TempScop, LoopInfo &LI, + ScalarEvolution &SE, ScopDetection &SD, + isl_ctx *ctx); /// @brief Check if a basic block is trivial. /// Index: lib/Analysis/ScopInfo.cpp =================================================================== --- lib/Analysis/ScopInfo.cpp +++ lib/Analysis/ScopInfo.cpp @@ -656,12 +656,13 @@ return AccessRelation; } -MemoryAccess::MemoryAccess(const IRAccess &Access, Instruction *AccInst, - ScopStmt *Statement, const ScopArrayInfo *SAI, - int Identifier) - : AccType(getMemoryAccessType(Access)), Statement(Statement), Inst(AccInst), - newAccessRelation(nullptr) { +MemoryAccess::MemoryAccess(AccessType AccType, Instruction *AccInst, + ScopStmt *Statement) + : AccType(AccType), Statement(Statement), Inst(AccInst), + newAccessRelation(nullptr) {} +void MemoryAccess::init(const IRAccess &Access, const ScopArrayInfo *SAI, + int Identifier) { isl_ctx *Ctx = Statement->getIslCtx(); BaseAddr = Access.getBase(); BaseName = getIslCompatibleName("MemRef_", getBaseAddr(), ""); @@ -722,6 +723,14 @@ isl_space_free(Space); } +MemoryAccess *MemoryAccess::create(const IRAccess &Access, Instruction *AccInst, + ScopStmt *Statement, + const ScopArrayInfo *SAI, int Identifier) { + auto MA = new MemoryAccess(getMemoryAccessType(Access), AccInst, Statement); + MA->init(Access, SAI, Identifier); + return MA; +} + void MemoryAccess::realignParams() { isl_space *ParamSpace = Statement->getParent()->getParamSpace(); AccessRelation = isl_map_align_params(AccessRelation, ParamSpace); @@ -898,8 +907,10 @@ MemoryAccessList *&MAL = InstructionToAccess[AccessInst]; if (!MAL) MAL = new MemoryAccessList(); - MAL->emplace_front(Access, AccessInst, this, SAI, MemAccs.size()); - MemAccs.push_back(&MAL->front()); + MAL->emplace_front(getMemoryAccessType(Access), AccessInst, this); + auto &MA = MAL->front(); + MA.init(Access, SAI, MemAccs.size()); + MemAccs.push_back(&MA); } } @@ -1065,14 +1076,15 @@ deriveAssumptionsFromGEP(GEP); } -ScopStmt::ScopStmt(Scop &parent, TempScop &tempScop, const Region &CurRegion, - Region &R, SmallVectorImpl &Nest) - : Parent(parent), BB(nullptr), R(&R), Build(nullptr), - NestLoops(Nest.size()) { - // Setup the induction variables. - for (unsigned i = 0, e = Nest.size(); i < e; ++i) - NestLoops[i] = Nest[i]; +ScopStmt::ScopStmt(Scop &parent, ArrayRef OuterLoops) + : Parent(parent), NestLoops(OuterLoops.begin(), OuterLoops.end()), + BB(nullptr), R(nullptr), Domain(nullptr), Build(nullptr) {} + +void ScopStmt::initFromRegion(TempScop &tempScop, const Region &CurRegion, + Region &R) { + assert(!this->R && !this->BB); + this->R = &R; BaseName = getIslCompatibleName("Stmt_", R.getNameStr(), ""); Domain = buildDomain(tempScop, CurRegion); @@ -1085,22 +1097,36 @@ checkForReductions(); } -ScopStmt::ScopStmt(Scop &parent, TempScop &tempScop, const Region &CurRegion, - BasicBlock &bb, SmallVectorImpl &Nest) - : Parent(parent), BB(&bb), R(nullptr), Build(nullptr), - NestLoops(Nest.size()) { - // Setup the induction variables. - for (unsigned i = 0, e = Nest.size(); i < e; ++i) - NestLoops[i] = Nest[i]; +static ScopStmt *createFromRegion(Scop &parent, TempScop &tempScop, + const Region &CurRegion, Region &R, + ArrayRef OuterLoops) { + auto SS = new ScopStmt(parent, OuterLoops); + SS->initFromRegion(tempScop, CurRegion, R); + return SS; +} + +void ScopStmt::initFromBasicBlock(TempScop &tempScop, const Region &CurRegion, + BasicBlock &BB) { + assert(!this->R && !this->BB); - BaseName = getIslCompatibleName("Stmt_", &bb, ""); + this->BB = &BB; + BaseName = getIslCompatibleName("Stmt_", &BB, ""); Domain = buildDomain(tempScop, CurRegion); - buildAccesses(tempScop, BB); - deriveAssumptions(BB); + buildAccesses(tempScop, &BB); + deriveAssumptions(&BB); checkForReductions(); } +ScopStmt *ScopStmt::createFromBasicBlock(Scop &parent, TempScop &tempScop, + const Region &CurRegion, + BasicBlock &BB, + ArrayRef OuterLoops) { + auto SS = new ScopStmt(parent, OuterLoops); + SS->initFromBasicBlock(tempScop, CurRegion, BB); + return SS; +} + /// @brief Collect loads which might form a reduction chain with @p StoreMA /// /// Check if the stored value for @p StoreMA is a binary operator with one or @@ -1669,19 +1695,20 @@ return MaxLD - MinLD + 1; } -Scop::Scop(TempScop &tempScop, LoopInfo &LI, ScalarEvolution &ScalarEvolution, - ScopDetection &SD, isl_ctx *Context) - : SE(&ScalarEvolution), R(tempScop.getMaxRegion()), IsOptimized(false), - MaxLoopDepth(getMaxLoopDepthInRegion(tempScop.getMaxRegion(), LI, SD)) { - IslCtx = Context; +Scop::Scop(Region &R, ScalarEvolution &ScalarEvolution, isl_ctx *Context, + unsigned MaxLoopDepth) + : SE(&ScalarEvolution), R(R), IsOptimized(false), + MaxLoopDepth(MaxLoopDepth), IslCtx(Context) {} +void Scop::initFromTempScop(TempScop &TempScop, LoopInfo &LI, + ScopDetection &SD) { buildContext(); SmallVector NestLoops; // Build the iteration domain, access functions and schedule functions // traversing the region tree. - Schedule = buildScop(tempScop, getRegion(), NestLoops, LI, SD); + Schedule = buildScop(TempScop, getRegion(), NestLoops, LI, SD); if (!Schedule) Schedule = isl_schedule_empty(getParamSpace()); @@ -1692,6 +1719,16 @@ assert(NestLoops.empty() && "NestLoops not empty at top level!"); } +Scop *Scop::createFromTempScop(TempScop &TempScop, LoopInfo &LI, + ScalarEvolution &SE, ScopDetection &SD, + isl_ctx *ctx) { + auto &R = TempScop.getMaxRegion(); + auto MaxLoopDepth = getMaxLoopDepthInRegion(R, LI, SD); + auto S = new Scop(R, SE, ctx, MaxLoopDepth); + S->initFromTempScop(TempScop, LI, SD); + return S; +} + Scop::~Scop() { isl_set_free(Context); isl_set_free(AssumedContext); @@ -2056,15 +2093,15 @@ ScopStmt *Scop::addScopStmt(BasicBlock *BB, Region *R, TempScop &tempScop, const Region &CurRegion, SmallVectorImpl &NestLoops) { - ScopStmt *Stmt; + + Stmts.emplace_back(*this, NestLoops); + ScopStmt *Stmt = &Stmts.back(); if (BB) { - Stmts.emplace_back(*this, tempScop, CurRegion, *BB, NestLoops); - Stmt = &Stmts.back(); + Stmt->initFromBasicBlock(tempScop, CurRegion, *BB); StmtMap[BB] = Stmt; } else { assert(R && "Either basic block or a region expected."); - Stmts.emplace_back(*this, tempScop, CurRegion, *R, NestLoops); - Stmt = &Stmts.back(); + Stmt->initFromRegion(tempScop, CurRegion, *R); for (BasicBlock *BB : R->blocks()) StmtMap[BB] = Stmt; } @@ -2171,7 +2208,7 @@ return false; } - scop = new Scop(*tempScop, LI, SE, SD, ctx); + scop = Scop::createFromTempScop(*tempScop, LI, SE, SD, ctx); DEBUG(scop->print(dbgs())); Index: lib/CodeGen/IslAst.cpp =================================================================== --- lib/CodeGen/IslAst.cpp +++ lib/CodeGen/IslAst.cpp @@ -71,8 +71,7 @@ namespace polly { class IslAst { public: - IslAst(Scop *Scop, const Dependences &D); - + static IslAst *create(Scop *Scop, const Dependences &D); ~IslAst(); /// Print a source code representation of the program. @@ -88,6 +87,9 @@ isl_ast_node *Root; isl_ast_expr *RunCondition; + IslAst(Scop *Scop); + void init(const Dependences &D); + void buildRunCondition(__isl_keep isl_ast_build *Build); }; } // End namespace polly. @@ -376,14 +378,14 @@ return true; } -IslAst::IslAst(Scop *Scop, const Dependences &D) - : S(Scop), Root(nullptr), RunCondition(nullptr) { +IslAst::IslAst(Scop *Scop) : S(Scop), Root(nullptr), RunCondition(nullptr) {} +void IslAst::init(const Dependences &D) { bool PerformParallelTest = PollyParallel || DetectParallel || PollyVectorizerChoice != VECTORIZER_NONE; // Skip AST and code generation if there was no benefit achieved. - if (!benefitsFromPolly(Scop, PerformParallelTest)) + if (!benefitsFromPolly(S, PerformParallelTest)) return; isl_ctx *Ctx = S->getIslCtx(); @@ -415,6 +417,12 @@ isl_ast_build_free(Build); } +IslAst *IslAst::create(Scop *Scop, const Dependences &D) { + auto Ast = new IslAst(Scop); + Ast->init(D); + return Ast; +} + IslAst::~IslAst() { isl_ast_node_free(Root); isl_ast_expr_free(RunCondition); @@ -440,7 +448,7 @@ const Dependences &D = getAnalysis().getDependences(); - Ast = new IslAst(&Scop, D); + Ast = IslAst::create(&Scop, D); DEBUG(printScop(dbgs(), Scop)); return false;