[flang-commits] [flang] [flang][OpenMP] Use common utility functions to get affected nest depth (PR #191418)

Krzysztof Parzyszek via flang-commits flang-commits at lists.llvm.org
Fri Apr 10 13:19:00 PDT 2026


https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/191418

>From 9953fd8d7040c60366ad0fd7d4d469742fb08632 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Wed, 8 Apr 2026 12:06:55 -0500
Subject: [PATCH] [flang][OpenMP] Use common utility functions to get affected
 nest depth

Remove the existing code that calculates the number of affected loops in
an OpenMP construct. There is a single function that does that and that
handles all directives and clauses.

Issue: https://github.com/llvm/llvm-project/issues/191249
---
 flang/lib/Semantics/resolve-directives.cpp | 138 ++-------------------
 1 file changed, 9 insertions(+), 129 deletions(-)

diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index ea5790105164f..39dfc30c77b13 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -1052,28 +1052,9 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
     }
   }
 
-  const parser::OmpClause *associatedClause{nullptr};
-  void SetAssociatedClause(const parser::OmpClause *c) { associatedClause = c; }
-  const parser::OmpClause *GetAssociatedClause() { return associatedClause; }
-
 private:
-  /// Given a vector of loop levels and a vector of corresponding clauses find
-  /// the largest loop level and set the associated loop level to the found
-  /// maximum. This is used for error handling to ensure that the number of
-  /// affected loops is not larger that the number of available loops.
-  std::int64_t SetAssociatedMaxClause(llvm::SmallVector<std::int64_t> &,
-      llvm::SmallVector<const parser::OmpClause *> &);
   std::int64_t GetNumAffectedLoopsFromLoopConstruct(
       const parser::OpenMPLoopConstruct &);
-  void CollectNumAffectedLoopsFromLoopConstruct(
-      const parser::OpenMPLoopConstruct &, llvm::SmallVector<std::int64_t> &,
-      llvm::SmallVector<const parser::OmpClause *> &);
-  void CollectNumAffectedLoopsFromInnerLoopContruct(
-      const parser::OpenMPLoopConstruct &, llvm::SmallVector<std::int64_t> &,
-      llvm::SmallVector<const parser::OmpClause *> &);
-  void CollectNumAffectedLoopsFromClauses(const parser::OmpClauseList &,
-      llvm::SmallVector<std::int64_t> &,
-      llvm::SmallVector<const parser::OmpClause *> &);
 
   Symbol::Flags dataSharingAttributeFlags{Symbol::Flag::OmpShared,
       Symbol::Flag::OmpPrivate, Symbol::Flag::OmpFirstPrivate,
@@ -2081,7 +2062,8 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPLoopConstruct &x) {
     IssueNonConformanceWarning(beginName.v, beginName.source, version);
   }
   ClearDataSharingAttributeObjects();
-  SetContextAssociatedLoopLevel(GetNumAffectedLoopsFromLoopConstruct(x));
+  int64_t affectedDepth{GetNumAffectedLoopsFromLoopConstruct(x)};
+  SetContextAssociatedLoopLevel(affectedDepth);
 
   if (beginName.v == llvm::omp::Directive::OMPD_do) {
     if (const parser::DoConstruct *doConstruct{x.GetNestedLoop()}) {
@@ -2177,116 +2159,14 @@ bool OmpAttributeVisitor::Pre(const parser::DoConstruct &x) {
   return true;
 }
 
-static bool isSizesClause(const parser::OmpClause *clause) {
-  return std::holds_alternative<parser::OmpClause::Sizes>(clause->u);
-}
-
-static bool isCollapseClause(const parser::OmpClause *clause) {
-  return std::holds_alternative<parser::OmpClause::Collapse>(clause->u);
-}
-
-std::int64_t OmpAttributeVisitor::SetAssociatedMaxClause(
-    llvm::SmallVector<std::int64_t> &levels,
-    llvm::SmallVector<const parser::OmpClause *> &clauses) {
-
-  // Find the tile level to ensure that the COLLAPSE clause value
-  // does not exeed the number of tiled loops.
-  std::int64_t tileLevel = 0;
-  for (auto [level, clause] : llvm::zip_equal(levels, clauses))
-    if (clause && isSizesClause(clause))
-      tileLevel = level;
-
-  std::int64_t maxLevel = 1;
-  const parser::OmpClause *maxClause = nullptr;
-  for (auto [level, clause] : llvm::zip_equal(levels, clauses)) {
-    if (clause && isCollapseClause(clause) && tileLevel > 0 &&
-        tileLevel < level) {
-      return 1;
-    }
-
-    if (level > maxLevel) {
-      maxLevel = level;
-      maxClause = clause;
-    }
-  }
-  if (maxClause)
-    SetAssociatedClause(maxClause);
-  return maxLevel;
-}
-
-std::int64_t OmpAttributeVisitor::GetNumAffectedLoopsFromLoopConstruct(
+int64_t OmpAttributeVisitor::GetNumAffectedLoopsFromLoopConstruct(
     const parser::OpenMPLoopConstruct &x) {
-  llvm::SmallVector<std::int64_t> levels;
-  llvm::SmallVector<const parser::OmpClause *> clauses;
-
-  CollectNumAffectedLoopsFromLoopConstruct(x, levels, clauses);
-  return SetAssociatedMaxClause(levels, clauses);
-}
-
-void OmpAttributeVisitor::CollectNumAffectedLoopsFromLoopConstruct(
-    const parser::OpenMPLoopConstruct &x,
-    llvm::SmallVector<std::int64_t> &levels,
-    llvm::SmallVector<const parser::OmpClause *> &clauses) {
-  const auto &clauseList{x.BeginDir().Clauses()};
-
-  CollectNumAffectedLoopsFromClauses(clauseList, levels, clauses);
-  CollectNumAffectedLoopsFromInnerLoopContruct(x, levels, clauses);
-
-  // OMPD_interchange with no permutation clause needs a level 2 nest
-  if (x.BeginDir().DirId() == llvm::omp::Directive::OMPD_interchange &&
-      !parser::omp::FindClause(
-          x.BeginDir(), llvm::omp::Clause::OMPC_permutation)) {
-    levels.push_back(2);
-    clauses.push_back(nullptr);
-  }
-}
-
-void OmpAttributeVisitor::CollectNumAffectedLoopsFromInnerLoopContruct(
-    const parser::OpenMPLoopConstruct &x,
-    llvm::SmallVector<std::int64_t> &levels,
-    llvm::SmallVector<const parser::OmpClause *> &clauses) {
-  for (auto &construct : std::get<parser::Block>(x.t)) {
-    if (auto *innerConstruct{parser::omp::GetOmpLoop(construct)}) {
-      CollectNumAffectedLoopsFromLoopConstruct(
-          *innerConstruct, levels, clauses);
-    }
-  }
-}
-
-void OmpAttributeVisitor::CollectNumAffectedLoopsFromClauses(
-    const parser::OmpClauseList &x, llvm::SmallVector<std::int64_t> &levels,
-    llvm::SmallVector<const parser::OmpClause *> &clauses) {
-  for (const auto &clause : x.v) {
-    if (const auto oclause{
-            std::get_if<parser::OmpClause::Ordered>(&clause.u)}) {
-      std::int64_t level = 0;
-      if (const auto v{EvaluateInt64(context_, oclause->v)}) {
-        level = *v;
-      }
-      levels.push_back(level);
-      clauses.push_back(&clause);
-    }
-
-    if (const auto cclause{
-            std::get_if<parser::OmpClause::Collapse>(&clause.u)}) {
-      std::int64_t level = 0;
-      if (const auto v{EvaluateInt64(context_, cclause->v)}) {
-        level = *v;
-      }
-      levels.push_back(level);
-      clauses.push_back(&clause);
-    }
-
-    if (const auto tclause{std::get_if<parser::OmpClause::Sizes>(&clause.u)}) {
-      levels.push_back(tclause->v.size());
-      clauses.push_back(&clause);
-    }
-    if (const auto iclause{
-            std::get_if<parser::OmpClause::Permutation>(&clause.u)}) {
-      levels.push_back(iclause->v.size());
-      clauses.push_back(&clause);
-    }
-  }
+  unsigned version{context_.langOptions().OpenMPVersion};
+  auto [depth, _]{
+      omp::GetAffectedNestDepthWithReason(x.BeginDir(), version, &context_)};
+  // If there was a problem obtaining the depth, it will be diagnosed in
+  // the semantic checks.
+  return depth.value.value_or(1);
 }
 
 // 2.15.1.1 Data-sharing Attribute Rules - Predetermined



More information about the flang-commits mailing list