Index: polly/include/polly/ScopBuilder.h =================================================================== --- polly/include/polly/ScopBuilder.h +++ polly/include/polly/ScopBuilder.h @@ -360,6 +360,21 @@ /// potential reduction. void checkForReductions(ScopStmt &Stmt); + /// Verify that all required invariant loads have been hoisted. + /// + /// Invariant load hoisting is not guaranteed to hoist all loads that were + /// assumed to be scop invariant during scop detection. This function checks + /// for cases where the hoisting failed, but where it would have been + /// necessary for our scop modeling to be correct. In case of insufficient + /// hoisting the scop is marked as invalid. + /// + /// In the example below Bound[1] is required to be invariant: + /// + /// for (int i = 1; i < Bound[0]; i++) + /// for (int j = 1; j < Bound[1]; j++) + /// ... + void verifyInvariantLoads(); + /// 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 Index: polly/include/polly/ScopInfo.h =================================================================== --- polly/include/polly/ScopInfo.h +++ polly/include/polly/ScopInfo.h @@ -2040,21 +2040,6 @@ /// nullptr if it cannot be hoisted at all. isl::set getNonHoistableCtx(MemoryAccess *Access, isl::union_map Writes); - /// Verify that all required invariant loads have been hoisted. - /// - /// Invariant load hoisting is not guaranteed to hoist all loads that were - /// assumed to be scop invariant during scop detection. This function checks - /// for cases where the hoisting failed, but where it would have been - /// necessary for our scop modeling to be correct. In case of insufficient - /// hoisting the scop is marked as invalid. - /// - /// In the example below Bound[1] is required to be invariant: - /// - /// for (int i = 1; i < Bound[0]; i++) - /// for (int j = 1; j < Bound[1]; j++) - /// ... - void verifyInvariantLoads(); - /// Hoist invariant memory loads and check for required ones. /// /// We first identify "common" invariant loads, thus loads that are invariant Index: polly/lib/Analysis/ScopBuilder.cpp =================================================================== --- polly/lib/Analysis/ScopBuilder.cpp +++ polly/lib/Analysis/ScopBuilder.cpp @@ -1306,6 +1306,20 @@ } } +void ScopBuilder::verifyInvariantLoads() { + auto &RIL = scop->getRequiredInvariantLoads(); + for (LoadInst *LI : RIL) { + assert(LI && scop->contains(LI)); + // If there exists a statement in the scop which has a memory access for + // @p LI, then mark this scop as infeasible for optimization. + for (ScopStmt &Stmt : *scop) + if (Stmt.getArrayAccessOrNULLFor(LI)) { + scop->invalidate(INVARIANTLOAD, LI->getDebugLoc(), LI->getParent()); + return; + } + } +} + void ScopBuilder::collectCandidateReductionLoads( MemoryAccess *StoreMA, SmallVectorImpl &Loads) { ScopStmt *Stmt = StoreMA->getStatement(); @@ -1588,7 +1602,7 @@ scop->hoistInvariantLoads(); scop->canonicalizeDynamicBasePtrs(); - scop->verifyInvariantLoads(); + verifyInvariantLoads(); scop->simplifySCoP(true); // Check late for a feasible runtime context because profitability did not Index: polly/lib/Analysis/ScopInfo.cpp =================================================================== --- polly/lib/Analysis/ScopInfo.cpp +++ polly/lib/Analysis/ScopInfo.cpp @@ -3778,20 +3778,6 @@ return WrittenCtx; } -void Scop::verifyInvariantLoads() { - auto &RIL = getRequiredInvariantLoads(); - for (LoadInst *LI : RIL) { - assert(LI && contains(LI)); - // If there exists a statement in the scop which has a memory access for - // @p LI, then mark this scop as infeasible for optimization. - for (ScopStmt &Stmt : Stmts) - if (Stmt.getArrayAccessOrNULLFor(LI)) { - invalidate(INVARIANTLOAD, LI->getDebugLoc(), LI->getParent()); - return; - } - } -} - void Scop::hoistInvariantLoads() { if (!PollyInvariantLoadHoisting) return;