[flang-commits] [flang] [llvm] [flang][mlir] Add flang to mlir lowering for dyn_groupprivate (PR #180938)
via flang-commits
flang-commits at lists.llvm.org
Mon May 25 23:44:29 PDT 2026
https://github.com/skc7 updated https://github.com/llvm/llvm-project/pull/180938
>From 10fafe5b5cae5bab80235681419e1f8a202c25d4 Mon Sep 17 00:00:00 2001
From: skc7 <Krishna.Sankisa at amd.com>
Date: Wed, 11 Feb 2026 18:41:48 +0530
Subject: [PATCH 1/2] [flang][mlir] Add flang to mlir lowering for
dyn_groupprivate
---
flang/lib/Lower/OpenMP/ClauseProcessor.cpp | 68 +++++++
flang/lib/Lower/OpenMP/ClauseProcessor.h | 4 +-
flang/lib/Lower/OpenMP/OpenMP.cpp | 6 +-
.../OpenMP/Todo/dyn-groupprivate-clause.f90 | 10 -
.../Lower/OpenMP/dyn-groupprivate-clause.f90 | 186 ++++++++++++++++++
.../Frontend/OpenMP/ConstructDecompositionT.h | 18 ++
6 files changed, 279 insertions(+), 13 deletions(-)
delete mode 100644 flang/test/Lower/OpenMP/Todo/dyn-groupprivate-clause.f90
create mode 100644 flang/test/Lower/OpenMP/dyn-groupprivate-clause.f90
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index 213b5f783430e..45a43b1c96e4e 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -921,6 +921,74 @@ bool ClauseProcessor::processThreadLimit(
return false;
}
+bool ClauseProcessor::processDynGroupprivate(
+ lower::StatementContext &stmtCtx,
+ mlir::omp::DynGroupprivateClauseOps &result) const {
+ using DynGroupprivate = omp::clause::DynGroupprivate;
+
+ // OpenMP 6.1 allows the `dyn_groupprivate` clause to appear more than once
+ // on the same construct (with distinct access-group modifiers). Semantics
+ // already rejects two clauses sharing the same access-group, but multiple
+ // clauses with different access-groups are spec-legal. The current MLIR
+ // representation (`mlir::omp::DynGroupprivateClauseOps`) and the OMPIRBuilder
+ // only support a single set of modifiers + size, so reject the multi-clause
+ // form up-front.
+ unsigned count = 0;
+ parser::CharBlock duplicateSource;
+ findRepeatableClause<DynGroupprivate>(
+ [&](const DynGroupprivate &, const parser::CharBlock &source) {
+ if (++count == 2)
+ duplicateSource = source;
+ });
+ if (count > 1) {
+ TODO(converter.genLocation(duplicateSource),
+ "multiple dyn_groupprivate clauses on the same construct");
+ }
+
+ if (auto *clause = findUniqueClause<DynGroupprivate>()) {
+ fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
+ mlir::MLIRContext *context = firOpBuilder.getContext();
+
+ // Process AccessGroup modifier (cgroup)
+ if (auto accessGroup =
+ std::get<std::optional<DynGroupprivate::AccessGroup>>(clause->t)) {
+ switch (*accessGroup) {
+ case DynGroupprivate::AccessGroup::Cgroup:
+ result.dynGroupprivateAccessGroup =
+ mlir::omp::AccessGroupModifierAttr::get(
+ context, mlir::omp::AccessGroupModifier::cgroup);
+ break;
+ }
+ }
+
+ // Process Fallback modifier (abort, default_mem, null)
+ if (auto fallback =
+ std::get<std::optional<DynGroupprivate::Fallback>>(clause->t)) {
+ switch (*fallback) {
+ case DynGroupprivate::Fallback::Abort:
+ result.dynGroupprivateFallback = mlir::omp::FallbackModifierAttr::get(
+ context, mlir::omp::FallbackModifier::abort);
+ break;
+ case DynGroupprivate::Fallback::Default_Mem:
+ result.dynGroupprivateFallback = mlir::omp::FallbackModifierAttr::get(
+ context, mlir::omp::FallbackModifier::default_mem);
+ break;
+ case DynGroupprivate::Fallback::Null:
+ result.dynGroupprivateFallback = mlir::omp::FallbackModifierAttr::get(
+ context, mlir::omp::FallbackModifier::null);
+ break;
+ }
+ }
+
+ // Process size expression
+ const auto &sizeExpr = std::get<SomeExpr>(clause->t);
+ result.dynGroupprivateSize =
+ fir::getBase(converter.genExprValue(sizeExpr, stmtCtx));
+ return true;
+ }
+ return false;
+}
+
bool ClauseProcessor::processUntied(mlir::omp::UntiedClauseOps &result) const {
return markClauseOccurrence<omp::clause::Untied>(result.untied);
}
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.h b/flang/lib/Lower/OpenMP/ClauseProcessor.h
index 1fc221b721ebf..b47c3ca48907e 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.h
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.h
@@ -124,7 +124,9 @@ class ClauseProcessor {
bool processThreadLimit(lower::StatementContext &stmtCtx,
mlir::omp::ThreadLimitClauseOps &result) const;
bool processUntied(mlir::omp::UntiedClauseOps &result) const;
-
+ bool
+ processDynGroupprivate(lower::StatementContext &stmtCtx,
+ mlir::omp::DynGroupprivateClauseOps &result) const;
bool processDetach(mlir::omp::DetachClauseOps &result) const;
// 'Repeatable' clauses: They can appear multiple times in the clause list.
bool processAffinity(mlir::omp::AffinityClauseOps &result) const;
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 7cb7e379eb503..ae2a154986ce6 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -1892,7 +1892,7 @@ genTargetClauses(lower::AbstractConverter &converter,
&mapObjects);
cp.processNowait(clauseOps);
cp.processThreadLimit(stmtCtx, clauseOps);
-
+ cp.processDynGroupprivate(stmtCtx, clauseOps);
cp.processTODO<clause::Allocate, clause::InReduction, clause::UsesAllocators>(
loc, llvm::omp::Directive::OMPD_target);
@@ -2034,6 +2034,7 @@ static void genTeamsClauses(lower::AbstractConverter &converter,
}
cp.processReduction(loc, clauseOps, reductionObjects);
+ cp.processDynGroupprivate(stmtCtx, clauseOps);
// TODO Support delayed privatization.
}
@@ -4789,7 +4790,8 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
!std::holds_alternative<clause::Untied>(clause.u) &&
!std::holds_alternative<clause::TaskReduction>(clause.u) &&
!std::holds_alternative<clause::Detach>(clause.u) &&
- !std::holds_alternative<clause::Device>(clause.u)) {
+ !std::holds_alternative<clause::Device>(clause.u) &&
+ !std::holds_alternative<clause::DynGroupprivate>(clause.u)) {
const common::LangOptions &options = semaCtx.langOptions();
if (!options.OpenMPSimd) {
std::string name =
diff --git a/flang/test/Lower/OpenMP/Todo/dyn-groupprivate-clause.f90 b/flang/test/Lower/OpenMP/Todo/dyn-groupprivate-clause.f90
deleted file mode 100644
index e06470f772bf8..0000000000000
--- a/flang/test/Lower/OpenMP/Todo/dyn-groupprivate-clause.f90
+++ /dev/null
@@ -1,10 +0,0 @@
-!RUN: %not_todo_cmd %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=61 -o - %s 2>&1 | FileCheck %s
-
-!CHECK: not yet implemented: DYN_GROUPPRIVATE clause is not implemented yet
-subroutine f00(n)
- implicit none
- integer :: n
- !$omp target dyn_groupprivate(n)
- !$omp end target
-end
-
diff --git a/flang/test/Lower/OpenMP/dyn-groupprivate-clause.f90 b/flang/test/Lower/OpenMP/dyn-groupprivate-clause.f90
new file mode 100644
index 0000000000000..fcf8a388183f1
--- /dev/null
+++ b/flang/test/Lower/OpenMP/dyn-groupprivate-clause.f90
@@ -0,0 +1,186 @@
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=61 -o - %s 2>&1 | FileCheck %s
+
+! Lowering of the OpenMP 6.1 `dyn_groupprivate` clause on the directives that
+! currently accept it in flang.
+
+! test 0: target with bare size, no modifiers.
+! CHECK-LABEL: func.func @_QPf00
+! CHECK: omp.target dyn_groupprivate({{.*}} : i32)
+subroutine f00(n)
+ implicit none
+ integer :: n
+ !$omp target dyn_groupprivate(n)
+ !$omp end target
+end subroutine
+
+! test 1: target with cgroup-only modifier.
+! CHECK-LABEL: func.func @_QPf01
+! CHECK: omp.target dyn_groupprivate(cgroup, {{.*}} : i32)
+subroutine f01(n)
+ implicit none
+ integer :: n
+ !$omp target dyn_groupprivate(cgroup: n)
+ !$omp end target
+end subroutine
+
+! test 2: target with fallback(abort), no access-group.
+! CHECK-LABEL: func.func @_QPf02
+! CHECK: omp.target dyn_groupprivate(fallback(abort), {{.*}} : i32)
+subroutine f02(n)
+ implicit none
+ integer :: n
+ !$omp target dyn_groupprivate(fallback(abort): n)
+ !$omp end target
+end subroutine
+
+! test 3: target with fallback(default_mem), no access-group.
+! CHECK-LABEL: func.func @_QPf03
+! CHECK: omp.target dyn_groupprivate(fallback(default_mem), {{.*}} : i32)
+subroutine f03(n)
+ implicit none
+ integer :: n
+ !$omp target dyn_groupprivate(fallback(default_mem): n)
+ !$omp end target
+end subroutine
+
+! test 4: target with fallback(null), no access-group.
+! CHECK-LABEL: func.func @_QPf04
+! CHECK: omp.target dyn_groupprivate(fallback(null), {{.*}} : i32)
+subroutine f04(n)
+ implicit none
+ integer :: n
+ !$omp target dyn_groupprivate(fallback(null): n)
+ !$omp end target
+end subroutine
+
+! test 5: target with cgroup + fallback(abort).
+! CHECK-LABEL: func.func @_QPf05
+! CHECK: omp.target dyn_groupprivate(cgroup, fallback(abort), {{.*}} : i32)
+subroutine f05(n)
+ implicit none
+ integer :: n
+ !$omp target dyn_groupprivate(cgroup, fallback(abort): n)
+ !$omp end target
+end subroutine
+
+! test 6: target with cgroup + fallback(default_mem).
+! CHECK-LABEL: func.func @_QPf06
+! CHECK: omp.target dyn_groupprivate(cgroup, fallback(default_mem), {{.*}} : i32)
+subroutine f06(n)
+ implicit none
+ integer :: n
+ !$omp target dyn_groupprivate(cgroup, fallback(default_mem): n)
+ !$omp end target
+end subroutine
+
+! test 7: target with cgroup + fallback(null).
+! CHECK-LABEL: func.func @_QPf07
+! CHECK: omp.target dyn_groupprivate(cgroup, fallback(null), {{.*}} : i32)
+subroutine f07(n)
+ implicit none
+ integer :: n
+ !$omp target dyn_groupprivate(cgroup, fallback(null): n)
+ !$omp end target
+end subroutine
+
+! test 8: Constant integer literal as the size operand.
+! CHECK-LABEL: func.func @_QPf08
+! CHECK: %[[CST:.*]] = arith.constant 1024 : i32
+! CHECK: omp.target dyn_groupprivate(%[[CST]] : i32)
+subroutine f08()
+ !$omp target dyn_groupprivate(1024)
+ !$omp end target
+end subroutine
+
+! test 9: Arithmetic expression as the size operand (n*1024).
+! CHECK-LABEL: func.func @_QPf09
+! CHECK: %{{.*}} = arith.muli {{.*}} : i32
+! CHECK: omp.target dyn_groupprivate({{.*}} : i32)
+subroutine f09(n)
+ implicit none
+ integer :: n
+ !$omp target dyn_groupprivate(n*1024)
+ !$omp end target
+end subroutine
+
+! test 10: 64-bit (kind=8) integer size operand: verify the size type is propagated.
+! CHECK-LABEL: func.func @_QPf10
+! CHECK: omp.target dyn_groupprivate({{.*}} : i64)
+subroutine f10(n)
+ implicit none
+ integer(kind=8) :: n
+ !$omp target dyn_groupprivate(n)
+ !$omp end target
+end subroutine
+
+! test 11: teams with bare size, no modifiers.
+! CHECK-LABEL: func.func @_QPf11
+! CHECK: omp.teams dyn_groupprivate({{.*}} : i32)
+subroutine f11(n)
+ implicit none
+ integer :: n
+ integer :: x
+ !$omp teams dyn_groupprivate(n)
+ x = 1
+ !$omp end teams
+end subroutine
+
+! test 12: teams with cgroup-only modifier.
+! CHECK-LABEL: func.func @_QPf12
+! CHECK: omp.teams dyn_groupprivate(cgroup, {{.*}} : i32)
+subroutine f12(n)
+ implicit none
+ integer :: n
+ integer :: x
+ !$omp teams dyn_groupprivate(cgroup: n)
+ x = 1
+ !$omp end teams
+end subroutine
+
+! test 13: teams with fallback(abort), no access-group.
+! CHECK-LABEL: func.func @_QPf13
+! CHECK: omp.teams dyn_groupprivate(fallback(abort), {{.*}} : i32)
+subroutine f13(n)
+ implicit none
+ integer :: n
+ integer :: x
+ !$omp teams dyn_groupprivate(fallback(abort): n)
+ x = 1
+ !$omp end teams
+end subroutine
+
+! test 14: teams with fallback(default_mem), no access-group.
+! CHECK-LABEL: func.func @_QPf14
+! CHECK: omp.teams dyn_groupprivate(fallback(default_mem), {{.*}} : i32)
+subroutine f14(n)
+ implicit none
+ integer :: n
+ integer :: x
+ !$omp teams dyn_groupprivate(fallback(default_mem): n)
+ x = 1
+ !$omp end teams
+end subroutine
+
+! test 15: teams with cgroup + fallback(default_mem).
+! CHECK-LABEL: func.func @_QPf15
+! CHECK: omp.teams dyn_groupprivate(cgroup, fallback(default_mem), {{.*}} : i32)
+subroutine f15(n)
+ implicit none
+ integer :: n
+ integer :: x
+ !$omp teams dyn_groupprivate(cgroup, fallback(default_mem): n)
+ x = 1
+ !$omp end teams
+end subroutine
+
+! test 16: teams with cgroup + fallback(null).
+! CHECK-LABEL: func.func @_QPf16
+! CHECK: omp.teams dyn_groupprivate(cgroup, fallback(null), {{.*}} : i32)
+subroutine f16(n)
+ implicit none
+ integer :: n
+ integer :: x
+ !$omp teams dyn_groupprivate(cgroup, fallback(null): n)
+ x = 1
+ !$omp end teams
+end subroutine
diff --git a/llvm/include/llvm/Frontend/OpenMP/ConstructDecompositionT.h b/llvm/include/llvm/Frontend/OpenMP/ConstructDecompositionT.h
index 9e49d8f6fca46..44b223ff93759 100644
--- a/llvm/include/llvm/Frontend/OpenMP/ConstructDecompositionT.h
+++ b/llvm/include/llvm/Frontend/OpenMP/ConstructDecompositionT.h
@@ -259,6 +259,9 @@ struct ConstructDecompositionT {
bool
applyClause(const tomp::clause::ThreadLimitT<TypeTy, IdTy, ExprTy> &clause,
const ClauseTy *);
+ bool applyClause(
+ const tomp::clause::DynGroupprivateT<TypeTy, IdTy, ExprTy> &clause,
+ const ClauseTy *);
uint32_t version;
HelperType &helper;
@@ -1149,6 +1152,21 @@ bool ConstructDecompositionT<C, H>::applyClause(
return true;
}
+// DYN_GROUPPRIVATE
+// [6.1] dyn_groupprivate clause
+// Directives: target, teams
+//
+// The effect of the dyn_groupprivate clause is as if it is applied to the
+// outermost leaf construct that permits it.
+template <typename C, typename H>
+bool ConstructDecompositionT<C, H>::applyClause(
+ const tomp::clause::DynGroupprivateT<TypeTy, IdTy, ExprTy> &clause,
+ const ClauseTy *node) {
+ if (!applyToOutermost(node))
+ return error(node, ErrorCode::NoLeafAllowing);
+ return true;
+}
+
// --- Splitting ------------------------------------------------------
template <typename C, typename H> bool ConstructDecompositionT<C, H>::split() {
>From eb96d58903fc6f4dcaae1208e4007cbcd5df3b4d Mon Sep 17 00:00:00 2001
From: skc7 <Krishna.Sankisa at amd.com>
Date: Wed, 13 May 2026 13:42:48 +0530
Subject: [PATCH 2/2] NFC code changes
---
flang/lib/Lower/OpenMP/ClauseProcessor.cpp | 136 +++++++++---------
flang/lib/Lower/OpenMP/ClauseProcessor.h | 6 +-
flang/lib/Lower/OpenMP/OpenMP.cpp | 5 +-
.../Frontend/OpenMP/ConstructDecompositionT.h | 36 ++---
4 files changed, 93 insertions(+), 90 deletions(-)
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index 45a43b1c96e4e..ee9c620a20c3e 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -921,74 +921,6 @@ bool ClauseProcessor::processThreadLimit(
return false;
}
-bool ClauseProcessor::processDynGroupprivate(
- lower::StatementContext &stmtCtx,
- mlir::omp::DynGroupprivateClauseOps &result) const {
- using DynGroupprivate = omp::clause::DynGroupprivate;
-
- // OpenMP 6.1 allows the `dyn_groupprivate` clause to appear more than once
- // on the same construct (with distinct access-group modifiers). Semantics
- // already rejects two clauses sharing the same access-group, but multiple
- // clauses with different access-groups are spec-legal. The current MLIR
- // representation (`mlir::omp::DynGroupprivateClauseOps`) and the OMPIRBuilder
- // only support a single set of modifiers + size, so reject the multi-clause
- // form up-front.
- unsigned count = 0;
- parser::CharBlock duplicateSource;
- findRepeatableClause<DynGroupprivate>(
- [&](const DynGroupprivate &, const parser::CharBlock &source) {
- if (++count == 2)
- duplicateSource = source;
- });
- if (count > 1) {
- TODO(converter.genLocation(duplicateSource),
- "multiple dyn_groupprivate clauses on the same construct");
- }
-
- if (auto *clause = findUniqueClause<DynGroupprivate>()) {
- fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
- mlir::MLIRContext *context = firOpBuilder.getContext();
-
- // Process AccessGroup modifier (cgroup)
- if (auto accessGroup =
- std::get<std::optional<DynGroupprivate::AccessGroup>>(clause->t)) {
- switch (*accessGroup) {
- case DynGroupprivate::AccessGroup::Cgroup:
- result.dynGroupprivateAccessGroup =
- mlir::omp::AccessGroupModifierAttr::get(
- context, mlir::omp::AccessGroupModifier::cgroup);
- break;
- }
- }
-
- // Process Fallback modifier (abort, default_mem, null)
- if (auto fallback =
- std::get<std::optional<DynGroupprivate::Fallback>>(clause->t)) {
- switch (*fallback) {
- case DynGroupprivate::Fallback::Abort:
- result.dynGroupprivateFallback = mlir::omp::FallbackModifierAttr::get(
- context, mlir::omp::FallbackModifier::abort);
- break;
- case DynGroupprivate::Fallback::Default_Mem:
- result.dynGroupprivateFallback = mlir::omp::FallbackModifierAttr::get(
- context, mlir::omp::FallbackModifier::default_mem);
- break;
- case DynGroupprivate::Fallback::Null:
- result.dynGroupprivateFallback = mlir::omp::FallbackModifierAttr::get(
- context, mlir::omp::FallbackModifier::null);
- break;
- }
- }
-
- // Process size expression
- const auto &sizeExpr = std::get<SomeExpr>(clause->t);
- result.dynGroupprivateSize =
- fir::getBase(converter.genExprValue(sizeExpr, stmtCtx));
- return true;
- }
- return false;
-}
-
bool ClauseProcessor::processUntied(mlir::omp::UntiedClauseOps &result) const {
return markClauseOccurrence<omp::clause::Untied>(result.untied);
}
@@ -1538,6 +1470,74 @@ bool ClauseProcessor::processDepend(lower::SymMap &symMap,
return findRepeatableClause<omp::clause::Depend>(process);
}
+bool ClauseProcessor::processDynGroupprivate(
+ lower::StatementContext &stmtCtx,
+ mlir::omp::DynGroupprivateClauseOps &result) const {
+ using DynGroupprivate = omp::clause::DynGroupprivate;
+
+ // OpenMP 6.1 allows the `dyn_groupprivate` clause to appear more than once
+ // on the same construct (with distinct access-group modifiers). Semantics
+ // already rejects two clauses sharing the same access-group, but multiple
+ // clauses with different access-groups are spec-legal. The current MLIR
+ // representation (`mlir::omp::DynGroupprivateClauseOps`) and the OMPIRBuilder
+ // only support a single set of modifiers + size, so reject the multi-clause
+ // form up-front.
+ unsigned count = 0;
+ parser::CharBlock duplicateSource;
+ findRepeatableClause<DynGroupprivate>(
+ [&](const DynGroupprivate &, const parser::CharBlock &source) {
+ if (++count == 2)
+ duplicateSource = source;
+ });
+ if (count > 1) {
+ TODO(converter.genLocation(duplicateSource),
+ "multiple dyn_groupprivate clauses on the same construct");
+ }
+
+ if (auto *clause = findUniqueClause<DynGroupprivate>()) {
+ fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
+ mlir::MLIRContext *context = firOpBuilder.getContext();
+
+ // Process AccessGroup modifier (cgroup).
+ if (auto accessGroup =
+ std::get<std::optional<DynGroupprivate::AccessGroup>>(clause->t)) {
+ switch (*accessGroup) {
+ case DynGroupprivate::AccessGroup::Cgroup:
+ result.dynGroupprivateAccessGroup =
+ mlir::omp::AccessGroupModifierAttr::get(
+ context, mlir::omp::AccessGroupModifier::cgroup);
+ break;
+ }
+ }
+
+ // Process Fallback modifier (abort, default_mem, null).
+ if (auto fallback =
+ std::get<std::optional<DynGroupprivate::Fallback>>(clause->t)) {
+ switch (*fallback) {
+ case DynGroupprivate::Fallback::Abort:
+ result.dynGroupprivateFallback = mlir::omp::FallbackModifierAttr::get(
+ context, mlir::omp::FallbackModifier::abort);
+ break;
+ case DynGroupprivate::Fallback::Default_Mem:
+ result.dynGroupprivateFallback = mlir::omp::FallbackModifierAttr::get(
+ context, mlir::omp::FallbackModifier::default_mem);
+ break;
+ case DynGroupprivate::Fallback::Null:
+ result.dynGroupprivateFallback = mlir::omp::FallbackModifierAttr::get(
+ context, mlir::omp::FallbackModifier::null);
+ break;
+ }
+ }
+
+ // Process size expression.
+ const auto &sizeExpr = std::get<SomeExpr>(clause->t);
+ result.dynGroupprivateSize =
+ fir::getBase(converter.genExprValue(sizeExpr, stmtCtx));
+ return true;
+ }
+ return false;
+}
+
bool ClauseProcessor::processGrainsize(
lower::StatementContext &stmtCtx,
mlir::omp::GrainsizeClauseOps &result) const {
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.h b/flang/lib/Lower/OpenMP/ClauseProcessor.h
index b47c3ca48907e..319dbe25bf651 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.h
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.h
@@ -124,9 +124,6 @@ class ClauseProcessor {
bool processThreadLimit(lower::StatementContext &stmtCtx,
mlir::omp::ThreadLimitClauseOps &result) const;
bool processUntied(mlir::omp::UntiedClauseOps &result) const;
- bool
- processDynGroupprivate(lower::StatementContext &stmtCtx,
- mlir::omp::DynGroupprivateClauseOps &result) const;
bool processDetach(mlir::omp::DetachClauseOps &result) const;
// 'Repeatable' clauses: They can appear multiple times in the clause list.
bool processAffinity(mlir::omp::AffinityClauseOps &result) const;
@@ -140,6 +137,9 @@ class ClauseProcessor {
bool processDepend(lower::SymMap &symMap, lower::StatementContext &stmtCtx,
mlir::omp::DependClauseOps &result) const;
bool
+ processDynGroupprivate(lower::StatementContext &stmtCtx,
+ mlir::omp::DynGroupprivateClauseOps &result) const;
+ bool
processEnter(llvm::SmallVectorImpl<DeclareTargetCaptureInfo> &result) const;
bool processIf(omp::clause::If::DirectiveNameModifier directiveName,
mlir::omp::IfClauseOps &result) const;
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index ae2a154986ce6..83b2f12b76a29 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -1880,6 +1880,7 @@ genTargetClauses(lower::AbstractConverter &converter,
cp.processDefaultMap(stmtCtx, defaultMaps);
cp.processDepend(symTable, stmtCtx, clauseOps);
cp.processDevice(stmtCtx, clauseOps);
+ cp.processDynGroupprivate(stmtCtx, clauseOps);
cp.processHasDeviceAddr(stmtCtx, clauseOps, hasDeviceAddrObjects);
if (HostEvalInfo *hostEvalInfo = getHostEvalInfoStackTop(converter)) {
// Only process host_eval if compiling for the host device.
@@ -1892,7 +1893,6 @@ genTargetClauses(lower::AbstractConverter &converter,
&mapObjects);
cp.processNowait(clauseOps);
cp.processThreadLimit(stmtCtx, clauseOps);
- cp.processDynGroupprivate(stmtCtx, clauseOps);
cp.processTODO<clause::Allocate, clause::InReduction, clause::UsesAllocators>(
loc, llvm::omp::Directive::OMPD_target);
@@ -2025,6 +2025,9 @@ static void genTeamsClauses(lower::AbstractConverter &converter,
llvm::SmallVectorImpl<Object> &reductionObjects) {
ClauseProcessor cp(converter, semaCtx, clauses);
cp.processAllocate(clauseOps);
+ // TODO: Only evaluate it here if it's not host-evaluated, like num_teams and
+ // thread_limit.
+ cp.processDynGroupprivate(stmtCtx, clauseOps);
cp.processIf(llvm::omp::Directive::OMPD_teams, clauseOps);
HostEvalInfo *hostEvalInfo = getHostEvalInfoStackTop(converter);
diff --git a/llvm/include/llvm/Frontend/OpenMP/ConstructDecompositionT.h b/llvm/include/llvm/Frontend/OpenMP/ConstructDecompositionT.h
index 44b223ff93759..bf812860a2543 100644
--- a/llvm/include/llvm/Frontend/OpenMP/ConstructDecompositionT.h
+++ b/llvm/include/llvm/Frontend/OpenMP/ConstructDecompositionT.h
@@ -231,6 +231,9 @@ struct ConstructDecompositionT {
const ClauseTy *);
bool applyClause(const tomp::clause::DefaultT<TypeTy, IdTy, ExprTy> &clause,
const ClauseTy *);
+ bool applyClause(
+ const tomp::clause::DynGroupprivateT<TypeTy, IdTy, ExprTy> &clause,
+ const ClauseTy *);
bool
applyClause(const tomp::clause::FirstprivateT<TypeTy, IdTy, ExprTy> &clause,
const ClauseTy *);
@@ -259,9 +262,6 @@ struct ConstructDecompositionT {
bool
applyClause(const tomp::clause::ThreadLimitT<TypeTy, IdTy, ExprTy> &clause,
const ClauseTy *);
- bool applyClause(
- const tomp::clause::DynGroupprivateT<TypeTy, IdTy, ExprTy> &clause,
- const ClauseTy *);
uint32_t version;
HelperType &helper;
@@ -542,6 +542,21 @@ bool ConstructDecompositionT<C, H>::applyClause(
return true;
}
+// DYN_GROUPPRIVATE
+// [6.1] dyn_groupprivate clause
+// Directives: target, teams
+//
+// The effect of the dyn_groupprivate clause is as if it is applied to the
+// outermost leaf construct that permits it.
+template <typename C, typename H>
+bool ConstructDecompositionT<C, H>::applyClause(
+ const tomp::clause::DynGroupprivateT<TypeTy, IdTy, ExprTy> &clause,
+ const ClauseTy *node) {
+ if (!applyToOutermost(node))
+ return error(node, ErrorCode::NoLeafAllowing);
+ return true;
+}
+
// FIRSTPRIVATE
// [5.2:112:5-7]
// Directives: distribute, do, for, parallel, scope, sections, single, target,
@@ -1152,21 +1167,6 @@ bool ConstructDecompositionT<C, H>::applyClause(
return true;
}
-// DYN_GROUPPRIVATE
-// [6.1] dyn_groupprivate clause
-// Directives: target, teams
-//
-// The effect of the dyn_groupprivate clause is as if it is applied to the
-// outermost leaf construct that permits it.
-template <typename C, typename H>
-bool ConstructDecompositionT<C, H>::applyClause(
- const tomp::clause::DynGroupprivateT<TypeTy, IdTy, ExprTy> &clause,
- const ClauseTy *node) {
- if (!applyToOutermost(node))
- return error(node, ErrorCode::NoLeafAllowing);
- return true;
-}
-
// --- Splitting ------------------------------------------------------
template <typename C, typename H> bool ConstructDecompositionT<C, H>::split() {
More information about the flang-commits
mailing list