[flang] [llvm] [mlir] [flang][OpenMP] Enable tiling (PR #143715)

Krzysztof Parzyszek via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 23 08:28:11 PDT 2025


================
@@ -131,20 +133,48 @@ class CanonicalizationOfOmp {
       // Ignore compiler directives.
       if (GetConstructIf<parser::CompilerDirective>(*nextIt))
         continue;
+      // Keep track of the loops to handle the end loop directives
+      std::stack<parser::OpenMPLoopConstruct *> loops;
+      loops.push(&x);
+      if (auto *innerConstruct{
+              GetConstructIf<parser::OpenMPConstruct>(*nextIt)}) {
+        if (auto *innerOmpLoop{
+                std::get_if<parser::OpenMPLoopConstruct>(&innerConstruct->u)}) {
+          auto &innerBeginDir{
+              std::get<parser::OmpBeginLoopDirective>(innerOmpLoop->t)};
+          auto &innerDir{std::get<parser::OmpLoopDirective>(innerBeginDir.t)};
+          if (innerDir.v == llvm::omp::Directive::OMPD_tile) {
+            std::get<std::optional<
+                common::Indirection<parser::OpenMPLoopConstruct>>>(
+                loops.top()->t) = std::move(*innerOmpLoop);
+            // Retrieveing the address so that DoConstruct or inner loop can be
+            // set later.
+            loops.push(&(std::get<std::optional<
+                    common::Indirection<parser::OpenMPLoopConstruct>>>(
+                loops.top()->t)
+                    .value()
+                    .value()));
+            nextIt = block.erase(nextIt);
+          }
+        }
+      }
 
       if (auto *doCons{GetConstructIf<parser::DoConstruct>(*nextIt)}) {
         if (doCons->GetLoopControl()) {
-          // move DoConstruct
-          std::get<std::optional<parser::DoConstruct>>(x.t) =
+          std::get<std::optional<parser::DoConstruct>>(loops.top()->t) =
               std::move(*doCons);
           nextIt = block.erase(nextIt);
           // try to match OmpEndLoopDirective
-          if (nextIt != block.end()) {
+          while (nextIt != block.end() && !loops.empty()) {
             if (auto *endDir{
                     GetConstructIf<parser::OmpEndLoopDirective>(*nextIt)}) {
-              std::get<std::optional<parser::OmpEndLoopDirective>>(x.t) =
-                  std::move(*endDir);
-              block.erase(nextIt);
+              std::get<std::optional<parser::OmpEndLoopDirective>>(
+                  loops.top()->t) = std::move(*endDir);
----------------
kparzysz wrote:

> Is the !$omp end tile optional? In that case we would need a special case for tile, since generally the mismatches are not handled here. If it is not optional then it should be handled later on in the checker.

Yes, for most of the loop directives the end-directive is optional.

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


More information about the llvm-commits mailing list