diff options
Diffstat (limited to 'polly')
-rw-r--r-- | polly/include/polly/ScopBuilder.h | 19 | ||||
-rw-r--r-- | polly/include/polly/ScopInfo.h | 43 | ||||
-rw-r--r-- | polly/lib/Analysis/ScopBuilder.cpp | 21 | ||||
-rw-r--r-- | polly/lib/Analysis/ScopInfo.cpp | 19 |
4 files changed, 51 insertions, 51 deletions
diff --git a/polly/include/polly/ScopBuilder.h b/polly/include/polly/ScopBuilder.h index 0c1e15a12a6..7de59feb676 100644 --- a/polly/include/polly/ScopBuilder.h +++ b/polly/include/polly/ScopBuilder.h @@ -375,6 +375,25 @@ class ScopBuilder { /// ... void verifyInvariantLoads(); + /// Hoist invariant memory loads and check for required ones. + /// + /// We first identify "common" invariant loads, thus loads that are invariant + /// and can be hoisted. Then we check if all required invariant loads have + /// been identified as (common) invariant. A load is a required invariant load + /// if it was assumed to be invariant during SCoP detection, e.g., to assume + /// loop bounds to be affine or runtime alias checks to be placeable. In case + /// a required invariant load was not identified as (common) invariant we will + /// drop this SCoP. An example for both "common" as well as required invariant + /// loads is given below: + /// + /// for (int i = 1; i < *LB[0]; i++) + /// for (int j = 1; j < *LB[1]; j++) + /// A[i][j] += A[0][0] + (*V); + /// + /// 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(); + /// 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 diff --git a/polly/include/polly/ScopInfo.h b/polly/include/polly/ScopInfo.h index 583b99ef2be..3045b7a4f10 100644 --- a/polly/include/polly/ScopInfo.h +++ b/polly/include/polly/ScopInfo.h @@ -2031,42 +2031,11 @@ private: /// Check if the base ptr of @p MA is in the SCoP but not hoistable. bool hasNonHoistableBasePtrInScop(MemoryAccess *MA, isl::union_map Writes); - /// Return the context under which the access cannot be hoisted. - /// - /// @param Access The access to check. - /// @param Writes The set of all memory writes in the scop. - /// - /// @return Return the context under which the access cannot be hoisted or a - /// nullptr if it cannot be hoisted at all. - isl::set getNonHoistableCtx(MemoryAccess *Access, isl::union_map Writes); - - /// Hoist invariant memory loads and check for required ones. - /// - /// We first identify "common" invariant loads, thus loads that are invariant - /// and can be hoisted. Then we check if all required invariant loads have - /// been identified as (common) invariant. A load is a required invariant load - /// if it was assumed to be invariant during SCoP detection, e.g., to assume - /// loop bounds to be affine or runtime alias checks to be placeable. In case - /// a required invariant load was not identified as (common) invariant we will - /// drop this SCoP. An example for both "common" as well as required invariant - /// loads is given below: - /// - /// for (int i = 1; i < *LB[0]; i++) - /// for (int j = 1; j < *LB[1]; j++) - /// A[i][j] += A[0][0] + (*V); - /// - /// 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(); - /// Check if @p MA can always be hoisted without execution context. bool canAlwaysBeHoisted(MemoryAccess *MA, bool StmtInvalidCtxIsEmpty, bool MAInvalidCtxIsEmpty, bool NonHoistableCtxIsEmpty); - /// Add invariant loads listed in @p InvMAs with the domain of @p Stmt. - void addInvariantLoads(ScopStmt &Stmt, InvariantAccessesTy &InvMAs); - /// Create an id for @p Param and store it in the ParameterIds map. void createParameterId(const SCEV *Param); @@ -2341,6 +2310,9 @@ public: InvEquivClassVMap[LoadInst] = ClassRep; } + /// Add invariant loads listed in @p InvMAs with the domain of @p Stmt. + void addInvariantLoads(ScopStmt &Stmt, InvariantAccessesTy &InvMAs); + /// Remove the metadata stored for @p Access. void removeAccessData(MemoryAccess *Access); @@ -2663,6 +2635,15 @@ public: return MinMaxAliasGroups; } + /// Return the context under which the access cannot be hoisted. + /// + /// @param Access The access to check. + /// @param Writes The set of all memory writes in the scop. + /// + /// @return Return the context under which the access cannot be hoisted or a + /// nullptr if it cannot be hoisted at all. + isl::set getNonHoistableCtx(MemoryAccess *Access, isl::union_map Writes); + /// Get an isl string representing the context. std::string getContextStr() const; diff --git a/polly/lib/Analysis/ScopBuilder.cpp b/polly/lib/Analysis/ScopBuilder.cpp index c4ac225d04e..dcacd3eae5e 100644 --- a/polly/lib/Analysis/ScopBuilder.cpp +++ b/polly/lib/Analysis/ScopBuilder.cpp @@ -1320,6 +1320,25 @@ void ScopBuilder::verifyInvariantLoads() { } } +void ScopBuilder::hoistInvariantLoads() { + if (!PollyInvariantLoadHoisting) + return; + + isl::union_map Writes = scop->getWrites(); + for (ScopStmt &Stmt : *scop) { + InvariantAccessesTy InvariantAccesses; + + for (MemoryAccess *Access : Stmt) + if (isl::set NHCtx = scop->getNonHoistableCtx(Access, Writes)) + InvariantAccesses.push_back({Access, NHCtx}); + + // Transfer the memory access from the statement to the SCoP. + for (auto InvMA : InvariantAccesses) + Stmt.removeMemoryAccess(InvMA.MA); + scop->addInvariantLoads(Stmt, InvariantAccesses); + } +} + void ScopBuilder::collectCandidateReductionLoads( MemoryAccess *StoreMA, SmallVectorImpl<MemoryAccess *> &Loads) { ScopStmt *Stmt = StoreMA->getStatement(); @@ -1670,7 +1689,7 @@ void ScopBuilder::buildScop(Region &R, AssumptionCache &AC, return; } - scop->hoistInvariantLoads(); + hoistInvariantLoads(); canonicalizeDynamicBasePtrs(); verifyInvariantLoads(); scop->simplifySCoP(true); diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp index 0a8da7426bc..00ede96ada3 100644 --- a/polly/lib/Analysis/ScopInfo.cpp +++ b/polly/lib/Analysis/ScopInfo.cpp @@ -3778,25 +3778,6 @@ isl::set Scop::getNonHoistableCtx(MemoryAccess *Access, isl::union_map Writes) { return WrittenCtx; } -void Scop::hoistInvariantLoads() { - if (!PollyInvariantLoadHoisting) - return; - - isl::union_map Writes = getWrites(); - for (ScopStmt &Stmt : *this) { - InvariantAccessesTy InvariantAccesses; - - for (MemoryAccess *Access : Stmt) - if (isl::set NHCtx = getNonHoistableCtx(Access, Writes)) - InvariantAccesses.push_back({Access, NHCtx}); - - // Transfer the memory access from the statement to the SCoP. - for (auto InvMA : InvariantAccesses) - Stmt.removeMemoryAccess(InvMA.MA); - addInvariantLoads(Stmt, InvariantAccesses); - } -} - ScopArrayInfo *Scop::getOrCreateScopArrayInfo(Value *BasePtr, Type *ElementType, ArrayRef<const SCEV *> Sizes, MemoryKind Kind, |