Index: include/polly/ScopInfo.h =================================================================== --- include/polly/ScopInfo.h +++ include/polly/ScopInfo.h @@ -881,7 +881,9 @@ ScopStmt(Scop &parent, Region &R); /// Initialize members after all MemoryAccesses have been added. - void init(); + /// + /// @param SD The ScopDetection analysis for the current function. + void init(ScopDetection &SD); private: /// Polyhedral description @@ -1007,10 +1009,10 @@ /// result scanning for GEP[s] is imprecise. Even though this is not a /// correctness problem, this imprecision may result in missed optimizations /// or non-optimal run-time checks. - void deriveAssumptionsFromGEP(GetElementPtrInst *Inst); + void deriveAssumptionsFromGEP(GetElementPtrInst *Inst, ScopDetection &SD); /// @brief Scan @p Block and derive assumptions about parameter values. - void deriveAssumptions(BasicBlock *Block); + void deriveAssumptions(BasicBlock *Block, ScopDetection &SD); public: ~ScopStmt(); @@ -1235,9 +1237,6 @@ DominatorTree &DT; ScalarEvolution *SE; - /// @brief The scop detection analysis. - ScopDetection &SD; - /// The underlying Region. Region &R; @@ -1372,12 +1371,11 @@ InvariantEquivClassesTy InvariantEquivClasses; /// @brief Scop constructor; invoked from ScopInfo::buildScop. - Scop(Region &R, AccFuncMapType &AccFuncMap, ScopDetection &SD, - ScalarEvolution &SE, DominatorTree &DT, LoopInfo &LI, isl_ctx *ctx, - unsigned MaxLoopDepth); + Scop(Region &R, AccFuncMapType &AccFuncMap, ScalarEvolution &SE, + DominatorTree &DT, LoopInfo &LI, isl_ctx *ctx, unsigned MaxLoopDepth); /// @brief Initialize this ScopInfo . - void init(AliasAnalysis &AA, AssumptionCache &AC); + void init(AliasAnalysis &AA, AssumptionCache &AC, ScopDetection &SD); /// @brief Add loop carried constraints to the header block of the loop @p L. /// @@ -1387,21 +1385,26 @@ /// @brief Compute the branching constraints for each basic block in @p R. /// /// @param R The region we currently build branching conditions for. - void buildDomainsWithBranchConstraints(Region *R); + /// @param SD The ScopDetection analysis for the current function. + void buildDomainsWithBranchConstraints(Region *R, ScopDetection &SD); /// @brief Propagate the domain constraints through the region @p R. /// /// @param R The region we currently build branching conditions for. - void propagateDomainConstraints(Region *R); + /// @param SD The ScopDetection analysis for the current function. + void propagateDomainConstraints(Region *R, ScopDetection &SD); /// @brief Remove domains of error blocks/regions (and blocks dominated by /// them). - void removeErrorBlockDomains(); + /// + /// @param SD The ScopDetection analysis for the current function. + void removeErrorBlockDomains(ScopDetection &SD); /// @brief Compute the domain for each basic block in @p R. /// /// @param R The region we currently traverse. - void buildDomains(Region *R); + /// @param SD The ScopDetection analysis for the current function. + void buildDomains(Region *R, ScopDetection &SD); /// @brief Check if a region part should be represented in the SCoP or not. /// @@ -1436,7 +1439,9 @@ /// consequence Scop::getIdForParam() will only return an id for the /// representing element of each equivalence class, thus for each required /// invariant location. - void buildInvariantEquivalenceClasses(); + /// + /// @param SD The ScopDetection analysis for the current function. + void buildInvariantEquivalenceClasses(ScopDetection &SD); /// @brief Check if a memory access can be hoisted. /// @@ -1461,7 +1466,8 @@ /// for (int j = 1; j < Bound[1]; j++) /// ... /// - void verifyInvariantLoads(); + /// @param SD The ScopDetection analysis for the current function. + void verifyInvariantLoads(ScopDetection &SD); /// @brief Hoist invariant memory loads and check for required ones. /// @@ -1480,7 +1486,9 @@ /// /// Common inv. loads: V, A[0][0], LB[0], LB[1] /// Required inv. loads: LB[0], LB[1], (V, if it may alias with A or LB) - void hoistInvariantLoads(); + /// + /// @param SD The ScopDetection analysis for the current function. + void hoistInvariantLoads(ScopDetection &SD); /// @brief Add invariant loads listed in @p InvMAs with the domain of @p Stmt. void addInvariantLoads(ScopStmt &Stmt, MemoryAccessList &InvMAs); @@ -1535,7 +1543,9 @@ void updateAccessDimensionality(); /// @brief Construct the schedule of this SCoP. - void buildSchedule(); + /// + /// @param SD The ScopDetection analysis for the current function. + void buildSchedule(ScopDetection &SD); /// @brief A loop stack element to keep track of per-loop information during /// schedule construction. @@ -1574,7 +1584,8 @@ /// @param R The region which to process. /// @param LoopStack A stack of loops that are currently under /// construction. - void buildSchedule(Region *R, LoopStackTy &LoopStack); + /// @param SD The ScopDetection analysis for the current function. + void buildSchedule(Region *R, LoopStackTy &LoopStack, ScopDetection &SD); /// @brief Build Schedule for the region node @p RN and add the derived /// information to @p LoopStack. @@ -1589,7 +1600,8 @@ /// @param RN The RegionNode region traversed. /// @param LoopStack A stack of loops that are currently under /// construction. - void buildSchedule(RegionNode *RN, LoopStackTy &LoopStack); + /// @param SD The ScopDetection analysis for the current function. + void buildSchedule(RegionNode *RN, LoopStackTy &LoopStack, ScopDetection &SD); /// @brief Collect all memory access relations of a given type. /// @@ -1627,7 +1639,6 @@ //@} ScalarEvolution *getSE() const; - ScopDetection &getSD() const { return SD; } /// @brief Get the count of parameters used in this Scop. /// Index: lib/Analysis/ScopInfo.cpp =================================================================== --- lib/Analysis/ScopInfo.cpp +++ lib/Analysis/ScopInfo.cpp @@ -1251,12 +1251,12 @@ Domain = isl_set_set_tuple_id(Domain, Id); } -void ScopStmt::deriveAssumptionsFromGEP(GetElementPtrInst *GEP) { +void ScopStmt::deriveAssumptionsFromGEP(GetElementPtrInst *GEP, + ScopDetection &SD) { isl_ctx *Ctx = Parent.getIslCtx(); isl_local_space *LSpace = isl_local_space_from_space(getDomainSpace()); Type *Ty = GEP->getPointerOperandType(); ScalarEvolution &SE = *Parent.getSE(); - ScopDetection &SD = Parent.getSD(); // The set of loads that are required to be invariant. auto &ScopRIL = *SD.getRequiredInvariantLoads(&Parent.getRegion()); @@ -1314,10 +1314,10 @@ isl_local_space_free(LSpace); } -void ScopStmt::deriveAssumptions(BasicBlock *Block) { +void ScopStmt::deriveAssumptions(BasicBlock *Block, ScopDetection &SD) { for (Instruction &Inst : *Block) if (auto *GEP = dyn_cast(&Inst)) - deriveAssumptionsFromGEP(GEP); + deriveAssumptionsFromGEP(GEP, SD); } void ScopStmt::collectSurroundingLoops() { @@ -1340,7 +1340,7 @@ BaseName = getIslCompatibleName("Stmt_", &bb, ""); } -void ScopStmt::init() { +void ScopStmt::init(ScopDetection &SD) { assert(!Domain && "init must be called only once"); buildDomain(); @@ -1348,10 +1348,10 @@ buildAccessRelations(); if (BB) { - deriveAssumptions(BB); + deriveAssumptions(BB, SD); } else { for (BasicBlock *Block : R->blocks()) { - deriveAssumptions(Block); + deriveAssumptions(Block, SD); } } @@ -1826,7 +1826,7 @@ isl_space_free(Space); } -void Scop::buildInvariantEquivalenceClasses() { +void Scop::buildInvariantEquivalenceClasses(ScopDetection &SD) { DenseMap, LoadInst *> EquivClasses; const InvariantLoadsSetTy &RIL = *SD.getRequiredInvariantLoads(&getRegion()); @@ -2085,7 +2085,7 @@ return isl_set_copy(DomainMap[BB]); } -void Scop::removeErrorBlockDomains() { +void Scop::removeErrorBlockDomains(ScopDetection &SD) { auto removeDomains = [this](BasicBlock *Start) { auto BBNode = DT.getNode(Start); for (auto ErrorChild : depth_first(BBNode)) { @@ -2117,7 +2117,7 @@ removeDomains(BB); } -void Scop::buildDomains(Region *R) { +void Scop::buildDomains(Region *R, ScopDetection &SD) { bool IsOnlyNonAffineRegion = SD.isNonAffineSubRegion(R, R); auto *EntryBB = R->getEntry(); @@ -2135,8 +2135,8 @@ if (IsOnlyNonAffineRegion) return; - buildDomainsWithBranchConstraints(R); - propagateDomainConstraints(R); + buildDomainsWithBranchConstraints(R, SD); + propagateDomainConstraints(R, SD); // Error blocks and blocks dominated by them have been assumed to never be // executed. Representing them in the Scop does not add any value. In fact, @@ -2146,10 +2146,10 @@ // Furthermore, basic blocks dominated by error blocks may reference // instructions in the error block which, if the error block is not modeled, // can themselves not be constructed properly. - removeErrorBlockDomains(); + removeErrorBlockDomains(SD); } -void Scop::buildDomainsWithBranchConstraints(Region *R) { +void Scop::buildDomainsWithBranchConstraints(Region *R, ScopDetection &SD) { auto &BoxedLoops = *SD.getBoxedLoops(&getRegion()); // To create the domain for each block in R we iterate over all blocks and @@ -2171,7 +2171,7 @@ if (RN->isSubRegion()) { Region *SubRegion = RN->getNodeAs(); if (!SD.isNonAffineSubRegion(SubRegion, &getRegion())) { - buildDomainsWithBranchConstraints(SubRegion); + buildDomainsWithBranchConstraints(SubRegion, SD); continue; } } @@ -2291,7 +2291,7 @@ return getDomainForBlock(R->getEntry(), DomainMap, RI); } -void Scop::propagateDomainConstraints(Region *R) { +void Scop::propagateDomainConstraints(Region *R, ScopDetection &SD) { // Iterate over the region R and propagate the domain constrains from the // predecessors to the current node. In contrast to the // buildDomainsWithBranchConstraints function, this one will pull the domain @@ -2312,7 +2312,7 @@ if (RN->isSubRegion()) { Region *SubRegion = RN->getNodeAs(); if (!SD.isNonAffineSubRegion(SubRegion, &getRegion())) { - propagateDomainConstraints(SubRegion); + propagateDomainConstraints(SubRegion, SD); continue; } } @@ -2726,23 +2726,22 @@ return MaxLD - MinLD + 1; } -Scop::Scop(Region &R, AccFuncMapType &AccFuncMap, ScopDetection &SD, +Scop::Scop(Region &R, AccFuncMapType &AccFuncMap, ScalarEvolution &ScalarEvolution, DominatorTree &DT, LoopInfo &LI, isl_ctx *Context, unsigned MaxLoopDepth) - : LI(LI), DT(DT), SE(&ScalarEvolution), SD(SD), R(R), - AccFuncMap(AccFuncMap), IsOptimized(false), - HasSingleExitEdge(R.getExitingBlock()), HasErrorBlock(false), - MaxLoopDepth(MaxLoopDepth), IslCtx(Context), Context(nullptr), - Affinator(this), AssumedContext(nullptr), BoundaryContext(nullptr), - Schedule(nullptr) { + : LI(LI), DT(DT), SE(&ScalarEvolution), R(R), AccFuncMap(AccFuncMap), + IsOptimized(false), HasSingleExitEdge(R.getExitingBlock()), + HasErrorBlock(false), MaxLoopDepth(MaxLoopDepth), IslCtx(Context), + Context(nullptr), Affinator(this), AssumedContext(nullptr), + BoundaryContext(nullptr), Schedule(nullptr) { buildContext(); } -void Scop::init(AliasAnalysis &AA, AssumptionCache &AC) { +void Scop::init(AliasAnalysis &AA, AssumptionCache &AC, ScopDetection &SD) { addUserAssumptions(AC); - buildInvariantEquivalenceClasses(); + buildInvariantEquivalenceClasses(SD); - buildDomains(&R); + buildDomains(&R, SD); // Remove empty and ignored statements. // Exit early in case there are no executable statements left in this scop. @@ -2752,9 +2751,9 @@ // The ScopStmts now have enough information to initialize themselves. for (ScopStmt &Stmt : Stmts) - Stmt.init(); + Stmt.init(SD); - buildSchedule(); + buildSchedule(SD); if (isl_set_is_empty(AssumedContext)) return; @@ -2767,7 +2766,7 @@ simplifyContexts(); buildAliasChecks(AA); - hoistInvariantLoads(); + hoistInvariantLoads(SD); simplifySCoP(false); } @@ -3002,7 +3001,7 @@ return true; } -void Scop::verifyInvariantLoads() { +void Scop::verifyInvariantLoads(ScopDetection &SD) { auto &RIL = *SD.getRequiredInvariantLoads(&getRegion()); for (LoadInst *LI : RIL) { assert(LI && getRegion().contains(LI)); @@ -3014,7 +3013,7 @@ } } -void Scop::hoistInvariantLoads() { +void Scop::hoistInvariantLoads(ScopDetection &SD) { isl_union_map *Writes = getWrites(); for (ScopStmt &Stmt : *this) { @@ -3037,7 +3036,7 @@ } isl_union_map_free(Writes); - verifyInvariantLoads(); + verifyInvariantLoads(SD); } const ScopArrayInfo * @@ -3509,10 +3508,10 @@ } } -void Scop::buildSchedule() { +void Scop::buildSchedule(ScopDetection &SD) { Loop *L = getLoopSurroundingRegion(getRegion(), LI); LoopStackTy LoopStack({LoopStackElementTy(L, nullptr, 0)}); - buildSchedule(getRegion().getNode(), LoopStack); + buildSchedule(getRegion().getNode(), LoopStack, SD); assert(LoopStack.size() == 1 && LoopStack.back().L == L); Schedule = LoopStack[0].Schedule; } @@ -3541,7 +3540,7 @@ /// sub-regions or blocks that are outside the last loop on the @p LoopStack. /// These region-nodes are then queue and only traverse after the all nodes /// within the current loop have been processed. -void Scop::buildSchedule(Region *R, LoopStackTy &LoopStack) { +void Scop::buildSchedule(Region *R, LoopStackTy &LoopStack, ScopDetection &SD) { Loop *OuterScopLoop = getLoopSurroundingRegion(getRegion(), LI); ReversePostOrderTraversal RTraversal(R); @@ -3581,18 +3580,19 @@ } LoopStack.push_back({L, nullptr, 0}); } - buildSchedule(RN, LoopStack); + buildSchedule(RN, LoopStack, SD); } return; } -void Scop::buildSchedule(RegionNode *RN, LoopStackTy &LoopStack) { +void Scop::buildSchedule(RegionNode *RN, LoopStackTy &LoopStack, + ScopDetection &SD) { if (RN->isSubRegion()) { auto *LocalRegion = RN->getNodeAs(); if (!SD.isNonAffineSubRegion(LocalRegion, &getRegion())) { - buildSchedule(LocalRegion, LoopStack); + buildSchedule(LocalRegion, LoopStack, SD); return; } } @@ -4119,7 +4119,7 @@ void ScopInfo::buildScop(Region &R, AssumptionCache &AC) { unsigned MaxLoopDepth = getMaxLoopDepthInRegion(R, *LI, *SD); - scop = new Scop(R, AccFuncMap, *SD, *SE, *DT, *LI, ctx, MaxLoopDepth); + scop = new Scop(R, AccFuncMap, *SE, *DT, *LI, ctx, MaxLoopDepth); buildStmts(R, R); buildAccessFunctions(R, R); @@ -4134,7 +4134,7 @@ if (!R.getExitingBlock()) buildAccessFunctions(R, *R.getExit(), nullptr, /* IsExitBlock */ true); - scop->init(*AA, AC); + scop->init(*AA, AC, *SD); } void ScopInfo::print(raw_ostream &OS, const Module *) const {