[flang-commits] [flang] [llvm] [flang][Lower] Lower OmpDependClause to Depend or Doacross (PR #175772)
Krzysztof Parzyszek via flang-commits
flang-commits at lists.llvm.org
Tue Jan 13 07:07:01 PST 2026
https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/175772
The clause::Depend class was a variant that either held a TaskDep class or a Doacross clause. This mirrors the OmpDependClause in the AST, which due to changes in the OpenMP spec can contain two different forms.
This is not actually necessary, and we can save some complexity by having clause::Depend only represent task dependence, and lowering OmpDependClause to either clause:Depend or clause::Doacross.
>From 06791afec822f6a29d6b90dc63b8d626f5c58ca2 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Tue, 13 Jan 2026 08:36:18 -0600
Subject: [PATCH] [flang][Lower] Lower OmpDependClause to Depend or Doacross
The clause::Depend class was a variant that either held a TaskDep
class or a Doacross clause. This mirrors the OmpDependClause in
the AST, which due to changes in the OpenMP spec can contain two
different forms.
This is not actually necessary, and we can save some complexity by
having clause::Depend only represent task dependence, and lowering
OmpDependClause to either clause:Depend or clause::Doacross.
---
flang/lib/Lower/OpenMP/ClauseProcessor.cpp | 12 +---
flang/lib/Lower/OpenMP/Clauses.cpp | 61 ++++++++++-----------
llvm/include/llvm/Frontend/OpenMP/ClauseT.h | 15 +----
3 files changed, 36 insertions(+), 52 deletions(-)
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index b923e415231d6..2f531efaf09aa 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -1021,17 +1021,11 @@ bool ClauseProcessor::processDepend(lower::SymMap &symMap,
mlir::omp::DependClauseOps &result) const {
auto process = [&](const omp::clause::Depend &clause,
const parser::CharBlock &) {
- using Depend = omp::clause::Depend;
- if (!std::holds_alternative<Depend::TaskDep>(clause.u)) {
- TODO(converter.getCurrentLocation(),
- "DEPEND clause with SINK or SOURCE is not supported yet");
- }
- auto &taskDep = std::get<Depend::TaskDep>(clause.u);
- auto depType = std::get<clause::DependenceType>(taskDep.t);
- auto &objects = std::get<omp::ObjectList>(taskDep.t);
+ auto depType = std::get<clause::DependenceType>(clause.t);
+ auto &objects = std::get<omp::ObjectList>(clause.t);
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
- if (std::get<std::optional<omp::clause::Iterator>>(taskDep.t)) {
+ if (std::get<std::optional<omp::clause::Iterator>>(clause.t)) {
TODO(converter.getCurrentLocation(),
"Support for iterator modifiers is not implemented yet");
}
diff --git a/flang/lib/Lower/OpenMP/Clauses.cpp b/flang/lib/Lower/OpenMP/Clauses.cpp
index a2716fb22a75c..c739249bff211 100644
--- a/flang/lib/Lower/OpenMP/Clauses.cpp
+++ b/flang/lib/Lower/OpenMP/Clauses.cpp
@@ -717,37 +717,20 @@ Doacross makeDoacross(const parser::OmpDoacross &doa,
return common::visit(common::visitors{visitSink, visitSource}, doa.u);
}
-Depend make(const parser::OmpClause::Depend &inp,
- semantics::SemanticsContext &semaCtx) {
- // inp.v -> parser::OmpDependClause
- using wrapped = parser::OmpDependClause;
- using Variant = decltype(Depend::u);
-
- auto visitTaskDep = [&](const wrapped::TaskDep &s) -> Variant {
- auto &mods = semantics::OmpGetModifiers(s);
- auto *m0 = semantics::OmpGetUniqueModifier<parser::OmpIterator>(mods);
- auto *m1 =
- semantics::OmpGetUniqueModifier<parser::OmpTaskDependenceType>(mods);
- auto &t1 = std::get<parser::OmpObjectList>(s.t);
- assert(m1 && "expecting task dependence type");
-
- auto &&maybeIter =
- m0 ? makeIterator(*m0, semaCtx) : std::optional<Iterator>{};
- return Depend::TaskDep{{/*DependenceType=*/makeDepType(*m1),
- /*Iterator=*/std::move(maybeIter),
- /*LocatorList=*/makeObjects(t1, semaCtx)}};
- };
+Depend makeDepend(const parser::OmpDependClause::TaskDep &inp,
+ semantics::SemanticsContext &semaCtx) {
+ auto &mods = semantics::OmpGetModifiers(inp);
+ auto *m0 = semantics::OmpGetUniqueModifier<parser::OmpIterator>(mods);
+ auto *m1 =
+ semantics::OmpGetUniqueModifier<parser::OmpTaskDependenceType>(mods);
+ auto &t1 = std::get<parser::OmpObjectList>(inp.t);
+ assert(m1 && "expecting task dependence type");
- return Depend{common::visit( //
- common::visitors{
- // Doacross
- [&](const parser::OmpDoacross &s) -> Variant {
- return makeDoacross(s, semaCtx);
- },
- // Depend::TaskDep
- visitTaskDep,
- },
- inp.v.u)};
+ auto &&maybeIter =
+ m0 ? makeIterator(*m0, semaCtx) : std::optional<Iterator>{};
+ return Depend{{/*DependenceType=*/makeDepType(*m1),
+ /*Iterator=*/std::move(maybeIter),
+ /*LocatorList=*/makeObjects(t1, semaCtx)}};
}
// Depobj: empty
@@ -1701,12 +1684,28 @@ Clause makeClause(const parser::OmpClause &cls,
common::visitors{
[&](const parser::OmpClause::Default &s) {
using DSA = parser::OmpDefaultClause::DataSharingAttribute;
+ using ODS = common::Indirection<parser::OmpDirectiveSpecification>;
if (std::holds_alternative<DSA>(s.v.u)) {
return makeClause(llvm::omp::Clause::OMPC_default,
clause::makeDefault(s, semaCtx), cls.source);
- } else {
+ } else if (std::holds_alternative<ODS>(s.v.u)) {
return makeClause(llvm::omp::Clause::OMPC_otherwise,
clause::makeOtherwise(s, semaCtx), cls.source);
+ } else {
+ llvm_unreachable("Unexpected alternative");
+ }
+ },
+ [&](const parser::OmpClause::Depend &s) {
+ using TaskDep = parser::OmpDependClause::TaskDep;
+ if (auto *dep = std::get_if<TaskDep>(&s.v.u)) {
+ return makeClause(llvm::omp::Clause::OMPC_depend,
+ clause::makeDepend(*dep, semaCtx), cls.source);
+ } else if (auto *doa = std::get_if<parser::OmpDoacross>(&s.v.u)) {
+ return makeClause(llvm::omp::Clause::OMPC_doacross,
+ clause::makeDoacross(*doa, semaCtx),
+ cls.source);
+ } else {
+ llvm_unreachable("Unexpected alternative");
}
},
[&](auto &&s) {
diff --git a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
index 7543f27136e7d..898961499c473 100644
--- a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
+++ b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
@@ -527,9 +527,6 @@ struct DefaultmapT {
std::tuple<ImplicitBehavior, OPT(VariableCategory)> t;
};
-template <typename T, typename I, typename E> //
-struct DoacrossT;
-
// V5.2: [15.9.5] `depend` clause
template <typename T, typename I, typename E> //
struct DependT {
@@ -537,15 +534,9 @@ struct DependT {
using LocatorList = ObjectListT<I, E>;
using DependenceType = tomp::type::DependenceType;
- struct TaskDep { // The form with task dependence type.
- using TupleTrait = std::true_type;
- // Empty LocatorList means "omp_all_memory".
- std::tuple<DependenceType, OPT(Iterator), LocatorList> t;
- };
-
- using Doacross = DoacrossT<T, I, E>;
- using UnionTrait = std::true_type;
- std::variant<Doacross, TaskDep> u; // Doacross form is legacy
+ using TupleTrait = std::true_type;
+ // Empty LocatorList means "omp_all_memory".
+ std::tuple<DependenceType, OPT(Iterator), LocatorList> t;
};
// V5.2: [3.5] `destroy` clause
More information about the flang-commits
mailing list