[flang-commits] [flang] 608fabb - [flang][OpenMP] Create generic interfaces for "container" entities (#229524)
via flang-commits
flang-commits at lists.llvm.org
Sun Oct 18 16:18:08 PDT 2026
Author: Krzysztof Parzyszek
Date: 2026-10-18T18:17:56-05:00
New Revision: 608fabba8ad1f86f2a305a837a142329e647d13f
URL: https://github.com/llvm/llvm-project/commit/608fabba8ad1f86f2a305a837a142329e647d13f
DIFF: https://github.com/llvm/llvm-project/commit/608fabba8ad1f86f2a305a837a142329e647d13f.diff
LOG: [flang][OpenMP] Create generic interfaces for "container" entities (#229524)
In short, clauses are containers of modifiers, and directives are
containers of clauses. With the abstractions in place, clauses and
modifiers look almost the same from the point of view of syntactic
properties.
Use these functions to implement generic GetAllowedElements and
GetElementVersionRange functions.
Added:
Modified:
flang/include/flang/Parser/openmp-utils.h
flang/lib/Parser/openmp-utils.cpp
flang/lib/Semantics/check-omp-syntax.cpp
Removed:
################################################################################
diff --git a/flang/include/flang/Parser/openmp-utils.h b/flang/include/flang/Parser/openmp-utils.h
index bd90be6c5ffc6f..c7d92c988c781e 100644
--- a/flang/include/flang/Parser/openmp-utils.h
+++ b/flang/include/flang/Parser/openmp-utils.h
@@ -18,6 +18,7 @@
#include "flang/Parser/parse-tree.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Frontend/OpenMP/OMP.h"
+#include "llvm/Frontend/OpenMP/OMPDescriptors.h"
#include <cassert>
#include <iterator>
@@ -36,6 +37,61 @@ template <typename T> constexpr auto addr_if(const std::optional<T> &x) {
return x ? &*x : nullptr;
}
+namespace descriptor {
+// Generic interfaces for entities that are "containers":
+// * Clause:
+// ├─ Elements: Modifiers
+// ╰─ Sets: ModifierSets
+// * Directive
+// ├─ Elements: Clauses
+// ╰─ Sets: ClauseSets
+// * ClauseSet:
+// ╰─ Elements: Clauses
+// * ModifierSet:
+// ╰─ Elements: Modifiers
+llvm::omp::Modifiers GetElements(
+ const llvm::omp::descriptor::Clause &desc, llvm::omp::Version version);
+llvm::omp::ModifierSets GetSets(
+ const llvm::omp::descriptor::Clause &desc, llvm::omp::Version version);
+llvm::omp::Clauses GetElements(
+ const llvm::omp::descriptor::Directive &desc, llvm::omp::Version version);
+llvm::omp::ClauseSets GetSets(
+ const llvm::omp::descriptor::Directive &desc, llvm::omp::Version version);
+llvm::omp::Clauses GetElements(
+ const llvm::omp::descriptor::ClauseSet &desc, llvm::omp::Version version);
+llvm::omp::Modifiers GetElements(
+ const llvm::omp::descriptor::ModifierSet &desc, llvm::omp::Version version);
+
+// The set of "elements" allowed on a given "container" is the union of all
+// elements listed explicitly, and elements of all sets. E.g. the set of all
+// clauses allowed on a given directive is the set of clauses listed in the
+// descriptor, plus the union of all clause sets.
+template <typename DescriptorTy>
+auto GetAllowedElements(const DescriptorTy &desc, llvm::omp::Version version) {
+ auto allowed{GetElements(desc, version)};
+ for (auto s : GetSets(desc, version)) {
+ allowed |= GetElements(llvm::omp::getDescriptor(s), version);
+ }
+ return allowed;
+}
+
+template <typename ElemTy, typename OwnerTy>
+llvm::directive::VersionRange GetVersionRangeForElement(
+ ElemTy elemId, OwnerTy ownerId) {
+ llvm::omp::Version minVer{~0u}, maxVer{0u};
+ const auto &desc{llvm::omp::getDescriptor(ownerId)};
+ for (llvm::omp::Version v : desc.getVersions()) {
+ if (GetAllowedElements(desc, v).test(elemId)) {
+ minVer = std::min(minVer, v);
+ maxVer = std::max(maxVer, v);
+ }
+ }
+ return llvm::directive::VersionRange{
+ static_cast<int>(static_cast<unsigned>(minVer)),
+ static_cast<int>(static_cast<unsigned>(maxVer))};
+}
+} // namespace descriptor
+
const parser::Designator *GetDesignatorFromObj(const parser::OmpObject &object);
const parser::DataRef *GetDataRefFromObj(const parser::OmpObject &object);
const parser::OmpLocator *GetLocatorFromObj(const parser::OmpObject &object);
diff --git a/flang/lib/Parser/openmp-utils.cpp b/flang/lib/Parser/openmp-utils.cpp
index ed5f00581dec99..1910d765e22d02 100644
--- a/flang/lib/Parser/openmp-utils.cpp
+++ b/flang/lib/Parser/openmp-utils.cpp
@@ -17,12 +17,43 @@
#include "flang/Parser/tools.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Frontend/OpenMP/OMP.h"
+#include "llvm/Frontend/OpenMP/OMPDescriptors.h"
#include <tuple>
#include <type_traits>
#include <variant>
namespace Fortran::parser::omp {
+namespace descriptor {
+llvm::omp::Modifiers GetElements(
+ const llvm::omp::descriptor::Clause &desc, llvm::omp::Version version) {
+ return desc.getModifiers(version);
+}
+
+llvm::omp::ModifierSets GetSets(
+ const llvm::omp::descriptor::Clause &desc, llvm::omp::Version version) {
+ return desc.getModifierSets(version);
+}
+llvm::omp::Clauses GetElements(
+ const llvm::omp::descriptor::Directive &desc, llvm::omp::Version version) {
+ return desc.getClauses(version);
+}
+
+llvm::omp::ClauseSets GetSets(
+ const llvm::omp::descriptor::Directive &desc, llvm::omp::Version version) {
+ return desc.getClauseSets(version);
+}
+
+llvm::omp::Clauses GetElements(
+ const llvm::omp::descriptor::ClauseSet &desc, llvm::omp::Version version) {
+ return desc.getClauses(version);
+}
+
+llvm::omp::Modifiers GetElements(const llvm::omp::descriptor::ModifierSet &desc,
+ llvm::omp::Version version) {
+ return desc.getModifiers(version);
+}
+} // namespace descriptor
const parser::Designator *GetDesignatorFromObj(
const parser::OmpObject &object) {
diff --git a/flang/lib/Semantics/check-omp-syntax.cpp b/flang/lib/Semantics/check-omp-syntax.cpp
index ef2d08adb06202..14f6e94d21fa44 100644
--- a/flang/lib/Semantics/check-omp-syntax.cpp
+++ b/flang/lib/Semantics/check-omp-syntax.cpp
@@ -33,32 +33,6 @@
namespace Fortran::semantics {
using namespace Fortran::parser::omp;
-static llvm::omp::Modifiers GetElements(
- const llvm::omp::descriptor::Clause &desc, llvm::omp::Version version) {
- return desc.getModifiers(version);
-}
-
-static llvm::omp::Modifiers GetElements(
- const llvm::omp::descriptor::ModifierSet &desc,
- llvm::omp::Version version) {
- return desc.getModifiers(version);
-}
-
-static llvm::omp::ModifierSets GetSets(
- const llvm::omp::descriptor::Clause &desc, llvm::omp::Version version) {
- return desc.getModifierSets(version);
-}
-
-template <typename DescriptorTy>
-static auto GetAllowedElements(
- const DescriptorTy &desc, llvm::omp::Version version) {
- auto allowed{GetElements(desc, version)};
- for (auto s : GetSets(desc, version)) {
- allowed |= GetElements(llvm::omp::getDescriptor(s), version);
- }
- return allowed;
-}
-
template < //
typename ElemTy, typename SetsSetTy, typename OwnerTy,
typename ResultTy = llvm::DenseMap<ElemTy,
@@ -71,26 +45,14 @@ static ResultTy VerifyVersions(
ResultTy result;
auto &odesc{llvm::omp::getDescriptor(ownerId)};
- ElemSetTy allowed{GetAllowedElements(odesc, version)};
+ ElemSetTy allowed{descriptor::GetAllowedElements(odesc, version)};
for (const AppliedElementTy &elem : info.elements) {
- if (allowed.test(elem.id.value)) {
- continue;
- }
- llvm::omp::Version since{~0u}, until{0u};
- for (llvm::omp::Version v : odesc.getVersions()) {
- if (GetElements(odesc, v).test(elem.id.value)) {
- if (v < version) {
- until = std::max(until, v);
- } else if (v > version) {
- since = std::min(since, v);
- }
- }
+ if (!allowed.test(elem.id.value)) {
+ result.insert({elem.id.value,
+ {elem.id.source,
+ descriptor::GetVersionRangeForElement(elem.id.value, ownerId)}});
}
- int minVer = static_cast<unsigned>(since);
- int maxVer = static_cast<unsigned>(until);
- result.insert({elem.id.value,
- {elem.id.source, llvm::directive::VersionRange{minVer, maxVer}}});
}
return result;
}
@@ -106,13 +68,13 @@ static ResultTy VerifyRequired(
ResultTy required;
auto &odesc{llvm::omp::getDescriptor(ownerId)};
- for (auto e : GetElements(odesc, version)) {
+ for (auto e : descriptor::GetElements(odesc, version)) {
auto &edesc{llvm::omp::getDescriptor(e)};
if (edesc.getProperties(version).test(llvm::omp::Property::Required)) {
required.first.set(e);
}
}
- for (auto s : GetSets(odesc, version)) {
+ for (auto s : descriptor::GetSets(odesc, version)) {
auto &sdesc{llvm::omp::getDescriptor(s)};
if (sdesc.getProperties(version).test(llvm::omp::Property::Required)) {
required.second.set(s);
@@ -138,19 +100,19 @@ static ResultTy VerifyUnique(const AppliedElementInfo<ElemTy, SetsSetTy> &info,
ElemSetTy unique;
auto &odesc{llvm::omp::getDescriptor(ownerId)};
- ElemSetTy allowed{GetAllowedElements(odesc, version)};
+ ElemSetTy allowed{descriptor::GetAllowedElements(odesc, version)};
- for (auto e : GetElements(odesc, version)) {
+ for (auto e : descriptor::GetElements(odesc, version)) {
auto &edesc{llvm::omp::getDescriptor(e)};
// Ultimate modifiers should have the "unique" property present as well.
if (edesc.getProperties(version).test(llvm::omp::Property::Unique)) {
unique.set(e);
}
}
- for (auto s : GetSets(odesc, version)) {
+ for (auto s : descriptor::GetSets(odesc, version)) {
auto &sdesc{llvm::omp::getDescriptor(s)};
if (sdesc.getProperties(version).test(llvm::omp::Property::Unique)) {
- unique |= GetElements(sdesc, version);
+ unique |= descriptor::GetElements(sdesc, version);
}
}
@@ -183,7 +145,7 @@ static ResultTy VerifyExclusive(
ResultTy result;
auto &odesc{llvm::omp::getDescriptor(ownerId)};
- auto allowed{GetAllowedElements(odesc, version)};
+ auto allowed{descriptor::GetAllowedElements(odesc, version)};
llvm::DenseMap<ElemTy, parser::CharBlock> present;
for (const AppliedElementTy &elem : info.elements) {
@@ -224,7 +186,7 @@ static ResultTy VerifyMutuallyExclusive(
ResultTy result;
auto &odesc{llvm::omp::getDescriptor(ownerId)};
- auto allowed{GetAllowedElements(odesc, version)};
+ auto allowed{descriptor::GetAllowedElements(odesc, version)};
llvm::DenseMap<SetTy, const AppliedElementTy *> exclusive;
for (const AppliedElementTy &elem : info.elements) {
@@ -266,18 +228,18 @@ static ResultTy VerifyUltimate(
llvm::omp::EnumSet<ElemTy> ultimate;
auto &odesc{llvm::omp::getDescriptor(ownerId)};
- auto allowed{GetAllowedElements(odesc, version)};
+ auto allowed{descriptor::GetAllowedElements(odesc, version)};
- for (auto e : GetElements(odesc, version)) {
+ for (auto e : descriptor::GetElements(odesc, version)) {
auto &edesc{llvm::omp::getDescriptor(e)};
if (edesc.getProperties(version).test(llvm::omp::Property::Ultimate)) {
ultimate.set(e);
}
}
- for (auto s : GetSets(odesc, version)) {
+ for (auto s : descriptor::GetSets(odesc, version)) {
auto &sdesc{llvm::omp::getDescriptor(s)};
if (sdesc.getProperties(version).test(llvm::omp::Property::Ultimate)) {
- ultimate |= GetElements(sdesc, version);
+ ultimate |= descriptor::GetElements(sdesc, version);
}
}
More information about the flang-commits
mailing list