[flang-commits] [flang] [flang][OpenMP] Move leftover functions from structure to loop, NFC (PR #228705)

via flang-commits flang-commits at lists.llvm.org
Sat Oct 3 05:47:18 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-semantics

Author: Krzysztof Parzyszek (kparzysz)

<details>
<summary>Changes</summary>

There were some loop-related functions still left in the check-omp-structure.cpp file. Move them to check-omp-loop.cpp.

---
Full diff: https://github.com/llvm/llvm-project/pull/228705.diff


3 Files Affected:

- (modified) flang/lib/Semantics/check-omp-loop.cpp (+142) 
- (modified) flang/lib/Semantics/check-omp-structure.cpp (-142) 
- (modified) flang/lib/Semantics/check-omp-structure.h (+2-2) 


``````````diff
diff --git a/flang/lib/Semantics/check-omp-loop.cpp b/flang/lib/Semantics/check-omp-loop.cpp
index d2466cdf219cb..7797c19db0f18 100644
--- a/flang/lib/Semantics/check-omp-loop.cpp
+++ b/flang/lib/Semantics/check-omp-loop.cpp
@@ -741,10 +741,105 @@ void OmpStructureChecker::Leave(const parser::OpenMPLoopConstruct &x) {
   }
 }
 
+void OmpStructureChecker::Enter(const parser::OmpClause::Collapse &x) {
+  RequiresConstantPositiveParameter(llvm::omp::Clause::OMPC_collapse, x.v);
+}
+
 void OmpStructureChecker::Enter(const parser::OmpClause::Depth &x) {
   RequiresConstantPositiveParameter(llvm::omp::Clause::OMPC_depth, x.v);
 }
 
+void OmpStructureChecker::Enter(const parser::OmpClause::Doacross &x) {
+  CheckDoacross(x.v.v, llvm::omp::Clause::OMPC_doacross);
+}
+
+void OmpStructureChecker::CheckDoacross(
+    const parser::OmpDoacross &doa, llvm::omp::Clause clauseId) {
+  auto &iterVec{std::get<std::optional<parser::OmpIterationVector>>(doa.t)};
+
+  auto &modifiers{OmpGetModifiers(doa)};
+  auto &depType{*OmpGetUniqueModifier<parser::OmpDependenceType>(modifiers)};
+  if (depType.v == parser::OmpDependenceType::Value::Source) {
+    if (iterVec) {
+      context_.Say(OmpGetModifierSource(modifiers, &depType),
+          "Iteration vector may not be specified with SOURCE dependence type"_err_en_US);
+    }
+    return;
+  }
+  assert(depType.v == parser::OmpDependenceType::Value::Sink &&
+      "Unexpected dependence-type");
+  if (!iterVec) {
+    context_.Say(OmpGetModifierSource(modifiers, &depType),
+        "Iteration vector must be specified with SINK dependence type"_err_en_US);
+    return;
+  }
+
+  // Process SINK dependence type. SINK may only appear in an ORDER construct,
+  // which references a prior ORDERED(n) clause on a DO or SIMD construct
+  // that marks the top of the loop nest.
+
+  const std::list<parser::OmpIteration> &vec{iterVec->v};
+
+  // Check if the variables in the iteration vector are unique.
+  struct Less {
+    using Iterator = std::list<parser::OmpIteration>::const_iterator;
+    bool operator()(Iterator a, Iterator b) const {
+      auto namea{std::get<parser::Name>(a->t)};
+      auto nameb{std::get<parser::Name>(b->t)};
+      assert(namea.symbol && nameb.symbol && "Unresolved symbols");
+      // The non-determinism of the "<" doesn't matter, we only care about
+      // equality, i.e.  a == b  <=>  !(a < b) && !(b < a)
+      return reinterpret_cast<uintptr_t>(namea.symbol) <
+          reinterpret_cast<uintptr_t>(nameb.symbol);
+    }
+  };
+  if (auto maybeIter{FindDuplicate<Less>(vec)}) {
+    auto name{std::get<parser::Name>((*maybeIter)->t)};
+    context_.Say(name.source,
+        "Duplicate variable '%s' in the iteration vector"_err_en_US,
+        name.ToString());
+  }
+
+  // Check if the variables in the iteration vector are induction variables.
+  // Ignore any mismatch between the size of the iteration vector and the
+  // number of DO constructs on the stack. This is checked elsewhere.
+
+  std::set<const Symbol *> inductionVars;
+  for (const LoopOrConstruct &c : llvm::reverse(constructStack_)) {
+    if (auto *doc{std::get_if<const parser::DoConstruct *>(&c)}) {
+      // Do-construct, collect the induction variable.
+      if (auto &control{(*doc)->GetLoopControl()}) {
+        if (auto *b{std::get_if<parser::LoopControl::Bounds>(&control->u)}) {
+          inductionVars.insert(b->Name().thing.symbol);
+        }
+      }
+    } else {
+      // Omp-loop-construct, check if it's do/simd with an ORDERED clause.
+      auto *omp{std::get_if<const parser::OpenMPConstruct *>(&c)};
+      assert(omp && "Expecting OpenMPConstruct");
+      if (auto *loop{parser::Unwrap<parser::OpenMPLoopConstruct>(*omp)}) {
+        const parser::OmpDirectiveSpecification &beginSpec{loop->BeginDir()};
+        llvm::omp::Directive loopDir{beginSpec.DirId()};
+        if (loopDir == llvm::omp::OMPD_do || loopDir == llvm::omp::OMPD_simd) {
+          // If it has ORDERED clause, stop the traversal.
+          if (parser::omp::FindClause(
+                  beginSpec, llvm::omp::Clause::OMPC_ordered)) {
+            break;
+          }
+        }
+      }
+    }
+  }
+  for (const parser::OmpIteration &iter : vec) {
+    auto &name{std::get<parser::Name>(iter.t)};
+    if (!inductionVars.count(name.symbol)) {
+      context_.Say(name.source,
+          "The iteration vector element '%s' is not an induction variable within the ORDERED loop nest"_err_en_US,
+          name.ToString());
+    }
+  }
+}
+
 void OmpStructureChecker::Enter(const parser::OmpClause::Ordered &x) {
   llvm::omp::Version version{context_.langOptions().getOpenMPVersion()};
   parser::CharBlock source{GetContext().clauseSource};
@@ -888,6 +983,53 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Linear &x) {
   }
 }
 
+void OmpStructureChecker::Enter(const parser::OmpClause::Safelen &x) {
+  RequiresConstantPositiveParameter(llvm::omp::Clause::OMPC_safelen, x.v);
+}
+
+void OmpStructureChecker::Enter(const parser::OmpClause::Schedule &x) {
+  const parser::OmpScheduleClause &scheduleClause = x.v;
+
+  // 2.7 Loop Construct Restriction
+  if (llvm::omp::allDoSet.test(GetContext().directive)) {
+    auto &modifiers{OmpGetModifiers(scheduleClause)};
+    auto kind{std::get<parser::OmpScheduleClause::Kind>(scheduleClause.t)};
+    auto &chunk{
+        std::get<std::optional<parser::ScalarIntExpr>>(scheduleClause.t)};
+    if (chunk) {
+      if (kind == parser::OmpScheduleClause::Kind::Runtime ||
+          kind == parser::OmpScheduleClause::Kind::Auto) {
+        context_.Say(GetContext().clauseSource,
+            "When SCHEDULE clause has %s specified, "
+            "it must not have chunk size specified"_err_en_US,
+            parser::ToUpperCaseLetters(
+                parser::OmpScheduleClause::EnumToString(kind)));
+      }
+      if (const auto &chunkExpr{std::get<std::optional<parser::ScalarIntExpr>>(
+              scheduleClause.t)}) {
+        RequiresPositiveParameter(
+            llvm::omp::Clause::OMPC_schedule, *chunkExpr, "chunk size");
+      }
+    }
+
+    auto *ordering{
+        OmpGetUniqueModifier<parser::OmpOrderingModifier>(modifiers)};
+    if (ordering &&
+        ordering->v == parser::OmpOrderingModifier::Value::Nonmonotonic) {
+      if (kind != parser::OmpScheduleClause::Kind::Dynamic &&
+          kind != parser::OmpScheduleClause::Kind::Guided) {
+        context_.Say(GetContext().clauseSource,
+            "The NONMONOTONIC modifier can only be specified with "
+            "SCHEDULE(DYNAMIC) or SCHEDULE(GUIDED)"_err_en_US);
+      }
+    }
+  }
+}
+
+void OmpStructureChecker::Enter(const parser::OmpClause::Simdlen &x) {
+  RequiresConstantPositiveParameter(llvm::omp::Clause::OMPC_simdlen, x.v);
+}
+
 void OmpStructureChecker::Enter(const parser::OmpClause::Sizes &c) {
   for (const parser::Cosubscript &v : c.v)
     RequiresPositiveParameter(llvm::omp::Clause::OMPC_sizes, v,
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 3880128545f5e..bef046d79df6c 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -5116,45 +5116,6 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Map &x) {
   }
 }
 
-void OmpStructureChecker::Enter(const parser::OmpClause::Schedule &x) {
-  const parser::OmpScheduleClause &scheduleClause = x.v;
-
-  // 2.7 Loop Construct Restriction
-  if (llvm::omp::allDoSet.test(GetContext().directive)) {
-    auto &modifiers{OmpGetModifiers(scheduleClause)};
-    auto kind{std::get<parser::OmpScheduleClause::Kind>(scheduleClause.t)};
-    auto &chunk{
-        std::get<std::optional<parser::ScalarIntExpr>>(scheduleClause.t)};
-    if (chunk) {
-      if (kind == parser::OmpScheduleClause::Kind::Runtime ||
-          kind == parser::OmpScheduleClause::Kind::Auto) {
-        context_.Say(GetContext().clauseSource,
-            "When SCHEDULE clause has %s specified, "
-            "it must not have chunk size specified"_err_en_US,
-            parser::ToUpperCaseLetters(
-                parser::OmpScheduleClause::EnumToString(kind)));
-      }
-      if (const auto &chunkExpr{std::get<std::optional<parser::ScalarIntExpr>>(
-              scheduleClause.t)}) {
-        RequiresPositiveParameter(
-            llvm::omp::Clause::OMPC_schedule, *chunkExpr, "chunk size");
-      }
-    }
-
-    auto *ordering{
-        OmpGetUniqueModifier<parser::OmpOrderingModifier>(modifiers)};
-    if (ordering &&
-        ordering->v == parser::OmpOrderingModifier::Value::Nonmonotonic) {
-      if (kind != parser::OmpScheduleClause::Kind::Dynamic &&
-          kind != parser::OmpScheduleClause::Kind::Guided) {
-        context_.Say(GetContext().clauseSource,
-            "The NONMONOTONIC modifier can only be specified with "
-            "SCHEDULE(DYNAMIC) or SCHEDULE(GUIDED)"_err_en_US);
-      }
-    }
-  }
-}
-
 void OmpStructureChecker::Enter(const parser::OmpClause::Device &x) {
   const parser::OmpDeviceClause &deviceClause{x.v};
   const auto &device{std::get<parser::ScalarIntExpr>(deviceClause.t)};
@@ -5281,97 +5242,6 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Depend &x) {
   }
 }
 
-void OmpStructureChecker::Enter(const parser::OmpClause::Doacross &x) {
-  CheckDoacross(x.v.v, llvm::omp::Clause::OMPC_doacross);
-}
-
-void OmpStructureChecker::CheckDoacross(
-    const parser::OmpDoacross &doa, llvm::omp::Clause clauseId) {
-  auto &iterVec{std::get<std::optional<parser::OmpIterationVector>>(doa.t)};
-
-  auto &modifiers{OmpGetModifiers(doa)};
-  auto &depType{*OmpGetUniqueModifier<parser::OmpDependenceType>(modifiers)};
-  if (depType.v == parser::OmpDependenceType::Value::Source) {
-    if (iterVec) {
-      context_.Say(OmpGetModifierSource(modifiers, &depType),
-          "Iteration vector may not be specified with SOURCE dependence type"_err_en_US);
-    }
-    return;
-  }
-  assert(depType.v == parser::OmpDependenceType::Value::Sink &&
-      "Unexpected dependence-type");
-  if (!iterVec) {
-    context_.Say(OmpGetModifierSource(modifiers, &depType),
-        "Iteration vector must be specified with SINK dependence type"_err_en_US);
-    return;
-  }
-
-  // Process SINK dependence type. SINK may only appear in an ORDER construct,
-  // which references a prior ORDERED(n) clause on a DO or SIMD construct
-  // that marks the top of the loop nest.
-
-  const std::list<parser::OmpIteration> &vec{iterVec->v};
-
-  // Check if the variables in the iteration vector are unique.
-  struct Less {
-    using Iterator = std::list<parser::OmpIteration>::const_iterator;
-    bool operator()(Iterator a, Iterator b) const {
-      auto namea{std::get<parser::Name>(a->t)};
-      auto nameb{std::get<parser::Name>(b->t)};
-      assert(namea.symbol && nameb.symbol && "Unresolved symbols");
-      // The non-determinism of the "<" doesn't matter, we only care about
-      // equality, i.e.  a == b  <=>  !(a < b) && !(b < a)
-      return reinterpret_cast<uintptr_t>(namea.symbol) <
-          reinterpret_cast<uintptr_t>(nameb.symbol);
-    }
-  };
-  if (auto maybeIter{FindDuplicate<Less>(vec)}) {
-    auto name{std::get<parser::Name>((*maybeIter)->t)};
-    context_.Say(name.source,
-        "Duplicate variable '%s' in the iteration vector"_err_en_US,
-        name.ToString());
-  }
-
-  // Check if the variables in the iteration vector are induction variables.
-  // Ignore any mismatch between the size of the iteration vector and the
-  // number of DO constructs on the stack. This is checked elsewhere.
-
-  std::set<const Symbol *> inductionVars;
-  for (const LoopOrConstruct &c : llvm::reverse(constructStack_)) {
-    if (auto *doc{std::get_if<const parser::DoConstruct *>(&c)}) {
-      // Do-construct, collect the induction variable.
-      if (auto &control{(*doc)->GetLoopControl()}) {
-        if (auto *b{std::get_if<parser::LoopControl::Bounds>(&control->u)}) {
-          inductionVars.insert(b->Name().thing.symbol);
-        }
-      }
-    } else {
-      // Omp-loop-construct, check if it's do/simd with an ORDERED clause.
-      auto *omp{std::get_if<const parser::OpenMPConstruct *>(&c)};
-      assert(omp && "Expecting OpenMPConstruct");
-      if (auto *loop{parser::Unwrap<parser::OpenMPLoopConstruct>(*omp)}) {
-        const parser::OmpDirectiveSpecification &beginSpec{loop->BeginDir()};
-        llvm::omp::Directive loopDir{beginSpec.DirId()};
-        if (loopDir == llvm::omp::OMPD_do || loopDir == llvm::omp::OMPD_simd) {
-          // If it has ORDERED clause, stop the traversal.
-          if (parser::omp::FindClause(
-                  beginSpec, llvm::omp::Clause::OMPC_ordered)) {
-            break;
-          }
-        }
-      }
-    }
-  }
-  for (const parser::OmpIteration &iter : vec) {
-    auto &name{std::get<parser::Name>(iter.t)};
-    if (!inductionVars.count(name.symbol)) {
-      context_.Say(name.source,
-          "The iteration vector element '%s' is not an induction variable within the ORDERED loop nest"_err_en_US,
-          name.ToString());
-    }
-  }
-}
-
 void OmpStructureChecker::CheckCopyingPolymorphicAllocatable(
     SymbolSourceMap &symbols, const llvm::omp::Clause clause) {
   llvm::omp::Version version{context_.langOptions().getOpenMPVersion()};
@@ -6830,18 +6700,6 @@ void OmpStructureChecker::Leave(const parser::OpenMPInvalidDirective &x) {
   dirContext_.pop_back();
 }
 
-void OmpStructureChecker::Enter(const parser::OmpClause::Collapse &x) {
-  RequiresConstantPositiveParameter(llvm::omp::Clause::OMPC_collapse, x.v);
-}
-
-void OmpStructureChecker::Enter(const parser::OmpClause::Safelen &x) {
-  RequiresConstantPositiveParameter(llvm::omp::Clause::OMPC_safelen, x.v);
-}
-
-void OmpStructureChecker::Enter(const parser::OmpClause::Simdlen &x) {
-  RequiresConstantPositiveParameter(llvm::omp::Clause::OMPC_simdlen, x.v);
-}
-
 void OmpStructureChecker::Enter(const parser::OmpClause::OmpxDynCgroupMem &x) {
   RequiresPositiveParameter(llvm::omp::Clause::OMPC_ompx_dyn_cgroup_mem, x.v);
 }
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index a77506e329934..c04336694f423 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -318,6 +318,8 @@ class OmpStructureChecker : public OmpStructureCheckerBase {
   std::int64_t GetOrdCollapseLevel(const parser::OpenMPLoopConstruct &x);
   void CheckAssociatedLoopConstraints(const parser::OpenMPLoopConstruct &x);
   void CheckScanModifier(const parser::OmpClause::Reduction &x);
+  void CheckDoacross(
+      const parser::OmpDoacross &doa, llvm::omp::Clause clauseId);
   void CheckDistLinear(const parser::OpenMPLoopConstruct &x);
   void CheckUnrollFullTripCount(const parser::OpenMPLoopConstruct &x);
 
@@ -430,8 +432,6 @@ class OmpStructureChecker : public OmpStructureCheckerBase {
   std::optional<IterTy> FindDuplicate(RangeTy &&);
 
   void CheckDependList(const parser::DataRef &);
-  void CheckDoacross(
-      const parser::OmpDoacross &doa, llvm::omp::Clause clauseId);
   void CheckDimsModifier(parser::CharBlock source, size_t numValues,
       const parser::OmpDimsModifier &x);
   void CheckTypeParamInquiry(const parser::CharBlock &source,

``````````

</details>


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


More information about the flang-commits mailing list