[llvm] [LoopInterchange] Add metadata to control loop-interchange (PR #127474)

Ryotaro Kasuga via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 17 04:14:18 PST 2025


================
@@ -572,6 +578,70 @@ struct LoopInterchange {
 
 } // end anonymous namespace
 
+bool LoopInterchangeList::hasSupportedLoopDepth(
+    OptimizationRemarkEmitter &ORE) {
+  unsigned LoopNestDepth = ListEnd - ListBegin;
+  if (LoopNestDepth < MinLoopNestDepth || LoopNestDepth > MaxLoopNestDepth) {
+    LLVM_DEBUG(dbgs() << "Unsupported depth of loop nest " << LoopNestDepth
+                      << ", the supported range is [" << MinLoopNestDepth
+                      << ", " << MaxLoopNestDepth << "].\n");
+    Loop *OuterLoop = LoopList[ListBegin];
+    ORE.emit([&]() {
+      return OptimizationRemarkMissed(DEBUG_TYPE, "UnsupportedLoopNestDepth",
+                                      OuterLoop->getStartLoc(),
+                                      OuterLoop->getHeader())
+             << "Unsupported depth of loop nest, the supported range is ["
+             << std::to_string(MinLoopNestDepth) << ", "
+             << std::to_string(MaxLoopNestDepth) << "].\n";
+    });
+    return false;
+  }
+  return true;
+}
+
+// Check the metadata for interchange. The outermost one is taken into account
+// and nested ones are ignored. The metadata affects the entire loop nest such
+// that the outermost loop is the loop for which the metadata is specified. For
+// example, in the following example, the loop-interchange will be performed
+// only to the outermost two loops, and the second pragma is ignored.
+//
+// for (...)
+//   for (...)
+//     #pragma clang loop interchange(disable)
+//     for (...)
+//       #pragma clang loop interchange(enable)
+//       for (...)
+//         for (...)
+//           Stmt
+//
----------------
kasuga-fj wrote:

Since LoopInterchange processes a loop nest, I think it makes sense that the pragma applies to the entire loop, not just the two loops it's specified for. However, with or without the interchange pragma, I'm not sure how to properly handle any other pragmas. Currently, LoopInterchange doesn't change the metadata of transformed loops. So, if the loops are interchanged in the following case:

```c
#pragma unroll_and_jam
for (int j = 0; j < N; j++)
  for (int i = 0; i < N; i++)
    ...
```

then it looks like:

```c
for (int i = 0; i < N; i++)
  #pragma unroll_and_jam
  for (int j = 0; j < N; j++)
    ...
```

Is this a desired behavior?  Or is there a better way to handle it? This may be relevant to what we should set in the follow-up metadata for the interchange. IMHO the current behavior is reasonable (i.e., in the above case, unroll_and_jam is not performed due to "unsupported transformation ordering"). Would like to hear any opinions.

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


More information about the llvm-commits mailing list