[polly] [polly] Add profitability check for expanded region. (PR #96548)

Michael Kruse via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 29 06:28:34 PDT 2024


================
@@ -1749,6 +1760,84 @@ bool ScopDetection::isProfitableRegion(DetectionContext &Context) const {
   return invalid<ReportUnprofitable>(Context, /*Assert=*/true, &CurRegion);
 }
 
+bool ScopDetection::isRegionExpansionProfitable(const Region &ExpandedRegion,
+                                                LoopInfo &LI) const {
+  if (!RegionExpansionProfitabilityCheck)
+    return true;
+
+  POLLY_DEBUG(dbgs() << "\nChecking expanded region: "
+                     << ExpandedRegion.getNameStr() << "\n");
+
+  // Collect outermost loops from expanded region.
+  SmallPtrSet<const Loop *, 2> OutermostLoops;
+  for (BasicBlock *BB : ExpandedRegion.blocks()) {
+    Loop *L = ExpandedRegion.outermostLoopInRegion(&LI, BB);
+    if (L)
+      OutermostLoops.insert(L);
+  }
+
+  if (OutermostLoops.empty()) {
+    POLLY_DEBUG(dbgs() << "Unprofitable expanded region: no loops found.\n");
+    return false;
+  }
+
+  // Return region expansion as unprofitable, if it contains basic blocks with
+  // memory accesses not used in outermost loops of the expanded region.
+  for (BasicBlock *BB : ExpandedRegion.blocks()) {
+    if (&BB->front() == BB->getTerminator())
+      continue;
+    if (BB == ExpandedRegion.getEntry())
+      continue;
+
+    // Only consider the expansion blocks added in addition to the loops. Also
+    // ignore preheader blocks because they may contain loop invariant loads.
+    if (llvm::any_of(OutermostLoops, [&](const Loop *L) {
+          return L->contains(BB) || (BB == L->getLoopPreheader());
+        }))
+      continue;
+
+    // Check if a basic block has instruction that access memory, but not used
+    // in any outermost loops of the expanded region.
+    bool BBContainsUnrelatedMemAccesses =
+        llvm::any_of(*BB, [&](const Instruction &I) {
+          if (!I.mayReadOrWriteMemory())
+            return false;
+          if (I.user_empty())
+            return false;
----------------
Meinersbur wrote:

Isn't a store's user list always empty? Wouldn't you look for the definition of the value it stores in that case? If the user list is empty, the following loop would have no iterations anyway. 

Also, what would matter is whether the accesses is to the same memory region as something in the loop, which would complicate the dependence and array subscript analysis. Not the value that us being loaded (unless you specifically want to check for indirect array accesses).

I think I would actually be fine to skip any non-loop code that is trailing (or leading) the loop nest. There isn't really any optimization opportunity for straight-line code.

https://github.com/llvm/llvm-project/pull/96548


More information about the llvm-commits mailing list