[Openmp-commits] [clang] [flang] [llvm] [openmp] [Clang][OpenMP][LoopTransformations] Add support for "#pragma omp fuse" loop transformation directive and "looprange" clause (PR #139293)
Michael Kruse via Openmp-commits
openmp-commits at lists.llvm.org
Wed Aug 6 05:03:07 PDT 2025
================
@@ -14236,28 +14279,282 @@ bool SemaOpenMP::checkTransformableLoopNest(
return false;
},
[&OriginalInits](OMPLoopBasedDirective *Transform) {
- Stmt *DependentPreInits;
- if (auto *Dir = dyn_cast<OMPTileDirective>(Transform))
- DependentPreInits = Dir->getPreInits();
- else if (auto *Dir = dyn_cast<OMPStripeDirective>(Transform))
- DependentPreInits = Dir->getPreInits();
- else if (auto *Dir = dyn_cast<OMPUnrollDirective>(Transform))
- DependentPreInits = Dir->getPreInits();
- else if (auto *Dir = dyn_cast<OMPReverseDirective>(Transform))
- DependentPreInits = Dir->getPreInits();
- else if (auto *Dir = dyn_cast<OMPInterchangeDirective>(Transform))
- DependentPreInits = Dir->getPreInits();
- else
- llvm_unreachable("Unhandled loop transformation");
-
- appendFlattenedStmtList(OriginalInits.back(), DependentPreInits);
+ updatePreInits(Transform, OriginalInits.back());
});
assert(OriginalInits.back().empty() && "No preinit after innermost loop");
OriginalInits.pop_back();
return Result;
}
-/// Add preinit statements that need to be propageted from the selected loop.
+/// Counts the total number of nested loops, including the outermost loop (the
+/// original loop). PRECONDITION of this visitor is that it must be invoked from
+/// the original loop to be analyzed. The traversal stops for Decl's and
+/// Expr's given that they may contain inner loops that must not be counted.
+///
+/// Example AST structure for the code:
+///
+/// int main() {
+/// #pragma omp fuse
+/// {
+/// for (int i = 0; i < 100; i++) { <-- Outer loop
+/// []() {
+/// for(int j = 0; j < 100; j++) {} <-- NOT A LOOP
+/// };
+/// for(int j = 0; j < 5; ++j) {} <-- Inner loop
+/// }
+/// for (int r = 0; i < 100; i++) { <-- Outer loop
+/// struct LocalClass {
+/// void bar() {
+/// for(int j = 0; j < 100; j++) {} <-- NOT A LOOP
+/// }
+/// };
+/// for(int k = 0; k < 10; ++k) {} <-- Inner loop
+/// {x = 5; for(k = 0; k < 10; ++k) x += k; x}; <-- NOT A LOOP
+/// }
+/// }
+/// }
----------------
Meinersbur wrote:
```suggestion
/// int main() {
/// #pragma omp fuse
/// {
/// for (int i = 0; i < 100; i++) { <-- Outer loop
/// []() {
/// for(int j = 0; j < 100; j++) {} <-- NOT A LOOP (1)
/// };
/// for(int j = 0; j < 5; ++j) {} <-- Inner loop
/// }
/// for (int r = 0; i < 100; i++) { <-- Outer loop
/// struct LocalClass {
/// void bar() {
/// for(int j = 0; j < 100; j++) {} <-- NOT A LOOP (2)
/// }
/// };
/// for(int k = 0; k < 10; ++k) {} <-- Inner loop
/// {x = 5; for(k = 0; k < 10; ++k) x += k; x}; <-- NOT A LOOP (3)
/// }
/// }
/// }
/// (1) because in a different function (here: a lambda)
/// (2) because in a different function (here: class method)
/// (3) because considered to be intervening-code of non-perfectly nested loop
```
https://github.com/llvm/llvm-project/pull/139293
More information about the Openmp-commits
mailing list