[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