[flang-commits] [flang] [flang][OpenMP] Implement utility to locate OmpClause in ODS, NFC (PR #184866)
Krzysztof Parzyszek via flang-commits
flang-commits at lists.llvm.org
Thu Mar 5 11:50:20 PST 2026
https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/184866
Simplify looking for a specific clause in OmpDirectiveSpecification. This is alternative to DirectiveStructureChecker::FindClause for when the internal checker structures have not yet been updated in the AST traversal.
>From d679178933f60c788eab3ceed690f56b4f834208 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Thu, 5 Mar 2026 10:30:13 -0600
Subject: [PATCH] [flang][OpenMP] Implement utility to locate OmpClause in ODS,
NFC
Simplify looking for a specific clause in OmpDirectiveSpecification.
This is alternative to DirectiveStructureChecker::FindClause for when
the internal checker structures have not yet been updated in the AST
traversal.
---
flang/include/flang/Parser/openmp-utils.h | 3 +
flang/lib/Lower/OpenMP/Utils.cpp | 10 +--
flang/lib/Parser/openmp-utils.cpp | 10 +++
flang/lib/Parser/parse-tree.cpp | 8 +--
flang/lib/Semantics/check-omp-loop.cpp | 71 +++++++++------------
flang/lib/Semantics/check-omp-structure.cpp | 18 ++----
6 files changed, 53 insertions(+), 67 deletions(-)
diff --git a/flang/include/flang/Parser/openmp-utils.h b/flang/include/flang/Parser/openmp-utils.h
index b8fb6078d59a5..f23e52585d567 100644
--- a/flang/include/flang/Parser/openmp-utils.h
+++ b/flang/include/flang/Parser/openmp-utils.h
@@ -226,6 +226,9 @@ const T *GetFirstArgument(const OmpDirectiveSpecification &spec) {
return nullptr;
}
+const OmpClause *FindClause(
+ const OmpDirectiveSpecification &spec, llvm::omp::Clause clauseId);
+
const BlockConstruct *GetFortranBlockConstruct(
const ExecutionPartConstruct &epc);
const Block &GetInnermostExecPart(const Block &block);
diff --git a/flang/lib/Lower/OpenMP/Utils.cpp b/flang/lib/Lower/OpenMP/Utils.cpp
index e9ba5f386803a..394c7a485525f 100644
--- a/flang/lib/Lower/OpenMP/Utils.cpp
+++ b/flang/lib/Lower/OpenMP/Utils.cpp
@@ -786,13 +786,9 @@ static void processTileSizesFromOpenMPConstruct(
innerConstruct->BeginDir();
if (innerBeginSpec.DirId() == llvm::omp::Directive::OMPD_tile) {
// Get the size values from parse tree and convert to a vector.
- for (const auto &clause : innerBeginSpec.Clauses().v) {
- if (const auto tclause{
- std::get_if<parser::OmpClause::Sizes>(&clause.u)}) {
- processFun(tclause);
- break;
- }
- }
+ if (auto *clause = parser::omp::FindClause(
+ innerBeginSpec, llvm::omp::Clause::OMPC_sizes))
+ processFun(&std::get<parser::OmpClause::Sizes>(clause->u));
}
}
}
diff --git a/flang/lib/Parser/openmp-utils.cpp b/flang/lib/Parser/openmp-utils.cpp
index c81f48f6323dd..6d4326af78344 100644
--- a/flang/lib/Parser/openmp-utils.cpp
+++ b/flang/lib/Parser/openmp-utils.cpp
@@ -145,6 +145,16 @@ const OmpObjectList *GetOmpObjectList(const OmpDependClause::TaskDep &x) {
return &std::get<OmpObjectList>(x.t);
}
+const OmpClause *FindClause(
+ const OmpDirectiveSpecification &spec, llvm::omp::Clause clauseId) {
+ for (auto &clause : spec.Clauses().v) {
+ if (clause.Id() == clauseId) {
+ return &clause;
+ }
+ }
+ return nullptr;
+}
+
const BlockConstruct *GetFortranBlockConstruct(
const ExecutionPartConstruct &epc) {
// ExecutionPartConstruct -> ExecutableConstruct
diff --git a/flang/lib/Parser/parse-tree.cpp b/flang/lib/Parser/parse-tree.cpp
index afe28182f8627..5bdfa47bea1cb 100644
--- a/flang/lib/Parser/parse-tree.cpp
+++ b/flang/lib/Parser/parse-tree.cpp
@@ -347,16 +347,12 @@ llvm::omp::Clause OpenMPAtomicConstruct::GetKind() const {
bool OpenMPAtomicConstruct::IsCapture() const {
const OmpDirectiveSpecification &dirSpec{std::get<OmpBeginDirective>(t)};
- return llvm::any_of(dirSpec.Clauses().v, [](auto &clause) {
- return clause.Id() == llvm::omp::Clause::OMPC_capture;
- });
+ return omp::FindClause(dirSpec, llvm::omp::Clause::OMPC_capture);
}
bool OpenMPAtomicConstruct::IsCompare() const {
const OmpDirectiveSpecification &dirSpec{std::get<OmpBeginDirective>(t)};
- return llvm::any_of(dirSpec.Clauses().v, [](auto &clause) {
- return clause.Id() == llvm::omp::Clause::OMPC_compare;
- });
+ return omp::FindClause(dirSpec, llvm::omp::Clause::OMPC_compare);
}
} // namespace Fortran::parser
diff --git a/flang/lib/Semantics/check-omp-loop.cpp b/flang/lib/Semantics/check-omp-loop.cpp
index 0cad16dc3deb1..f81bde981594d 100644
--- a/flang/lib/Semantics/check-omp-loop.cpp
+++ b/flang/lib/Semantics/check-omp-loop.cpp
@@ -159,12 +159,11 @@ void OmpStructureChecker::HasInvalidLoopBinding(
const parser::OmpDirectiveName &beginName{beginSpec.DirName()};
auto teamsBindingChecker = [&](parser::MessageFixedText msg) {
- for (const auto &clause : beginSpec.Clauses().v) {
- if (const auto *bindClause{
- std::get_if<parser::OmpClause::Bind>(&clause.u)}) {
- if (bindClause->v.v != parser::OmpBindClause::Binding::Teams) {
- context_.Say(beginName.source, msg);
- }
+ if (auto *clause{
+ parser::omp::FindClause(beginSpec, llvm::omp::Clause::OMPC_bind)}) {
+ auto &bind{std::get<parser::OmpClause::Bind>(clause->u).v};
+ if (bind.v != parser::OmpBindClause::Binding::Teams) {
+ context_.Say(beginName.source, msg);
}
}
};
@@ -204,11 +203,9 @@ void OmpStructureChecker::CheckSIMDNest(const parser::OpenMPConstruct &c) {
[&](const parser::OmpBlockConstruct &c) {
const parser::OmpDirectiveSpecification &beginSpec{c.BeginDir()};
if (beginSpec.DirId() == llvm::omp::Directive::OMPD_ordered) {
- for (const auto &clause : beginSpec.Clauses().v) {
- if (std::get_if<parser::OmpClause::Simd>(&clause.u)) {
- eligibleSIMD = true;
- break;
- }
+ if (parser::omp::FindClause(
+ beginSpec, llvm::omp::Clause::OMPC_simd)) {
+ eligibleSIMD = true;
}
}
},
@@ -217,11 +214,9 @@ void OmpStructureChecker::CheckSIMDNest(const parser::OpenMPConstruct &c) {
&c.u)}) {
llvm::omp::Directive dirId{ssc->v.DirId()};
if (dirId == llvm::omp::Directive::OMPD_ordered) {
- for (const parser::OmpClause &x : ssc->v.Clauses().v) {
- if (x.Id() == llvm::omp::Clause::OMPC_simd) {
- eligibleSIMD = true;
- break;
- }
+ if (parser::omp::FindClause(
+ ssc->v, llvm::omp::Clause::OMPC_simd)) {
+ eligibleSIMD = true;
}
} else if (dirId == llvm::omp::Directive::OMPD_scan) {
eligibleSIMD = true;
@@ -274,9 +269,8 @@ static bool IsFullUnroll(const parser::OpenMPLoopConstruct &x) {
const parser::OmpDirectiveSpecification &beginSpec{x.BeginDir()};
if (beginSpec.DirName().v == llvm::omp::Directive::OMPD_unroll) {
- return llvm::none_of(beginSpec.Clauses().v, [](const parser::OmpClause &c) {
- return c.Id() == llvm::omp::Clause::OMPC_partial;
- });
+ return parser::omp::FindClause(
+ beginSpec, llvm::omp::Clause::OMPC_partial) == nullptr;
}
return false;
}
@@ -312,15 +306,13 @@ static std::optional<size_t> CountGeneratedNests(
if (!nestedCount || *nestedCount == 0) {
return std::nullopt;
}
- auto rangeAt{
- llvm::find_if(beginSpec.Clauses().v, [](const parser::OmpClause &c) {
- return c.Id() == llvm::omp::Clause::OMPC_looprange;
- })};
- if (rangeAt == beginSpec.Clauses().v.end()) {
+ auto *clause{
+ parser::omp::FindClause(beginSpec, llvm::omp::Clause::OMPC_looprange)};
+ if (!clause) {
return 1;
}
- auto *loopRange{parser::Unwrap<parser::OmpLooprangeClause>(*rangeAt)};
+ auto *loopRange{parser::Unwrap<parser::OmpLooprangeClause>(*clause)};
std::optional<int64_t> count{GetIntValue(std::get<1>(loopRange->t))};
if (!count || *count <= 0) {
return std::nullopt;
@@ -617,23 +609,22 @@ void OmpStructureChecker::CheckDistLinear(
void OmpStructureChecker::CheckLooprangeBounds(
const parser::OpenMPLoopConstruct &x) {
- for (const parser::OmpClause &clause : x.BeginDir().Clauses().v) {
- if (auto *lrClause{parser::Unwrap<parser::OmpLooprangeClause>(clause)}) {
- auto first{GetIntValue(std::get<0>(lrClause->t))};
- auto count{GetIntValue(std::get<1>(lrClause->t))};
- if (!first || !count || *first <= 0 || *count <= 0) {
- return;
- }
- auto requiredCount{static_cast<size_t>(*first + *count - 1)};
- if (auto loopCount{CountGeneratedNests(std::get<parser::Block>(x.t))}) {
- if (*loopCount < requiredCount) {
- context_.Say(clause.source,
- "The specified loop range requires %zu loops, but the loop sequence has a length of %zu"_err_en_US,
- requiredCount, *loopCount);
- }
- }
+ if (auto *clause{parser::omp::FindClause(
+ x.BeginDir(), llvm::omp::Clause::OMPC_looprange)}) {
+ auto *lrClause{parser::Unwrap<parser::OmpLooprangeClause>(clause)};
+ auto first{GetIntValue(std::get<0>(lrClause->t))};
+ auto count{GetIntValue(std::get<1>(lrClause->t))};
+ if (!first || !count || *first <= 0 || *count <= 0) {
return;
}
+ auto requiredCount{static_cast<size_t>(*first + *count - 1)};
+ if (auto loopCount{CountGeneratedNests(std::get<parser::Block>(x.t))}) {
+ if (*loopCount < requiredCount) {
+ context_.Say(clause->source,
+ "The specified loop range requires %zu loops, but the loop sequence has a length of %zu"_err_en_US,
+ requiredCount, *loopCount);
+ }
+ }
}
}
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 7ffda12c1fb83..431c41f443f7a 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1800,16 +1800,8 @@ void OmpStructureChecker::CheckIndividualAllocateDirective(
return true;
}};
- const auto *allocator{[&]() {
- // Can't use FindClause in Enter (because clauses haven't been visited
- // yet).
- for (const parser::OmpClause &c : beginSpec.Clauses().v) {
- if (c.Id() == llvm::omp::Clause::OMPC_allocator) {
- return &c;
- }
- }
- return static_cast<const parser::OmpClause *>(nullptr);
- }()};
+ const auto *allocator{
+ parser::omp::FindClause(beginSpec, llvm::omp::Clause::OMPC_allocator)};
if (InTargetRegion()) {
bool hasDynAllocators{
@@ -4674,11 +4666,9 @@ void OmpStructureChecker::CheckDoacross(const parser::OmpDoacross &doa) {
const parser::OmpDirectiveSpecification &beginSpec{(*loopc)->BeginDir()};
llvm::omp::Directive loopDir{beginSpec.DirId()};
if (loopDir == llvm::omp::OMPD_do || loopDir == llvm::omp::OMPD_simd) {
- auto IsOrdered{[](const parser::OmpClause &c) {
- return c.Id() == llvm::omp::OMPC_ordered;
- }};
// If it has ORDERED clause, stop the traversal.
- if (llvm::any_of(beginSpec.Clauses().v, IsOrdered)) {
+ if (parser::omp::FindClause(
+ beginSpec, llvm::omp::Clause::OMPC_ordered)) {
break;
}
}
More information about the flang-commits
mailing list