[llvm-branch-commits] [flang] [flang][OpenMP] Parse GROUPPRIVATE directive (PR #153807)
Krzysztof Parzyszek via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Aug 15 07:24:06 PDT 2025
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/153807
>From ccc414db30f65308d47d2efbb3198a896bd5a67e Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Fri, 15 Aug 2025 08:12:45 -0500
Subject: [PATCH 1/3] [flang][OpenMP] Parse GROUPPRIVATE directive
No semantic checks or lowering yet.
---
flang/include/flang/Parser/dump-parse-tree.h | 1 +
flang/include/flang/Parser/parse-tree.h | 14 +++++++--
flang/lib/Lower/OpenMP/OpenMP.cpp | 7 +++++
flang/lib/Parser/openmp-parsers.cpp | 8 +++++
flang/lib/Parser/unparse.cpp | 7 +++++
flang/lib/Semantics/check-omp-structure.cpp | 13 ++++++++
flang/lib/Semantics/check-omp-structure.h | 2 ++
flang/test/Lower/OpenMP/Todo/groupprivate.f90 | 9 ++++++
flang/test/Parser/OpenMP/groupprivate.f90 | 30 +++++++++++++++++++
9 files changed, 89 insertions(+), 2 deletions(-)
create mode 100644 flang/test/Lower/OpenMP/Todo/groupprivate.f90
create mode 100644 flang/test/Parser/OpenMP/groupprivate.f90
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index 2c666a6d09a7b..8fbc6ccc639bf 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -729,6 +729,7 @@ class ParseTreeDumper {
NODE(parser, OpenMPLoopConstruct)
NODE(parser, OpenMPExecutableAllocate)
NODE(parser, OpenMPAllocatorsConstruct)
+ NODE(parser, OpenMPGroupprivate)
NODE(parser, OpenMPRequiresConstruct)
NODE(parser, OpenMPSimpleStandaloneConstruct)
NODE(parser, OpenMPStandaloneConstruct)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index e72190f019dd1..ae0259fe9025e 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -4943,6 +4943,15 @@ struct OpenMPDeclareSimdConstruct {
std::tuple<Verbatim, std::optional<Name>, OmpClauseList> t;
};
+// ref: [6.0:301-303]
+//
+// groupprivate-directive ->
+// GROUPPRIVATE (variable-list-item...) // since 6.0
+struct OpenMPGroupprivate {
+ WRAPPER_CLASS_BOILERPLATE(OpenMPGroupprivate, OmpDirectiveSpecification);
+ CharBlock source;
+};
+
// 2.4 requires -> REQUIRES requires-clause[ [ [,] requires-clause]...]
struct OpenMPRequiresConstruct {
TUPLE_CLASS_BOILERPLATE(OpenMPRequiresConstruct);
@@ -4970,8 +4979,9 @@ struct OpenMPDeclarativeConstruct {
std::variant<OpenMPDeclarativeAllocate, OpenMPDeclarativeAssumes,
OpenMPDeclareMapperConstruct, OpenMPDeclareReductionConstruct,
OpenMPDeclareSimdConstruct, OpenMPDeclareTargetConstruct,
- OmpDeclareVariantDirective, OpenMPThreadprivate, OpenMPRequiresConstruct,
- OpenMPUtilityConstruct, OmpMetadirectiveDirective>
+ OmpDeclareVariantDirective, OpenMPGroupprivate, OpenMPThreadprivate,
+ OpenMPRequiresConstruct, OpenMPUtilityConstruct,
+ OmpMetadirectiveDirective>
u;
};
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index fef64ccc15015..ec2ec37e623f8 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -3593,6 +3593,13 @@ genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
}
}
+static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
+ semantics::SemanticsContext &semaCtx,
+ lower::pft::Evaluation &eval,
+ const parser::OpenMPGroupprivate &directive) {
+ TODO(converter.getCurrentLocation(), "GROUPPRIVATE");
+}
+
static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx,
lower::pft::Evaluation &eval,
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 46b14861096f1..41c16212f5771 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -1773,6 +1773,12 @@ TYPE_PARSER(sourced(construct<OpenMPDeclareSimdConstruct>(
verbatim("DECLARE SIMD"_tok) || verbatim("DECLARE_SIMD"_tok),
maybe(parenthesized(name)), Parser<OmpClauseList>{})))
+TYPE_PARSER(sourced( //
+ construct<OpenMPGroupprivate>(
+ predicated(OmpDirectiveNameParser{},
+ IsDirective(llvm::omp::Directive::OMPD_groupprivate)) >=
+ Parser<OmpDirectiveSpecification>{})))
+
// 2.4 Requires construct
TYPE_PARSER(sourced(construct<OpenMPRequiresConstruct>(
verbatim("REQUIRES"_tok), Parser<OmpClauseList>{})))
@@ -1808,6 +1814,8 @@ TYPE_PARSER(
Parser<OmpDeclareVariantDirective>{}) ||
construct<OpenMPDeclarativeConstruct>(
Parser<OpenMPDeclarativeAllocate>{}) ||
+ construct<OpenMPDeclarativeConstruct>(
+ Parser<OpenMPGroupprivate>{}) ||
construct<OpenMPDeclarativeConstruct>(
Parser<OpenMPRequiresConstruct>{}) ||
construct<OpenMPDeclarativeConstruct>(
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 4f8d498972807..4294a6d491648 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2716,6 +2716,13 @@ class UnparseVisitor {
void Unparse(const OpenMPDispatchConstruct &x) { //
Unparse(static_cast<const OmpBlockConstruct &>(x));
}
+ void Unparse(const OpenMPGroupprivate &x) {
+ BeginOpenMP();
+ Word("!$OMP ");
+ Walk(x.v);
+ Put("\n");
+ EndOpenMP();
+ }
void Unparse(const OpenMPRequiresConstruct &y) {
BeginOpenMP();
Word("!$OMP REQUIRES ");
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index bf126bbb0d8c1..ea8c391999331 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -571,6 +571,10 @@ template <typename Checker> struct DirectiveSpellingVisitor {
Directive::OMPD_declare_variant);
return false;
}
+ bool Pre(const parser::OpenMPGroupprivate &x) {
+ checker_(x.v.DirName().source, Directive::OMPD_groupprivate);
+ return false;
+ }
bool Pre(const parser::OpenMPThreadprivate &x) {
checker_(
std::get<parser::Verbatim>(x.t).source, Directive::OMPD_threadprivate);
@@ -1189,6 +1193,15 @@ void OmpStructureChecker::CheckThreadprivateOrDeclareTargetVar(
}
}
+void OmpStructureChecker::Enter(const parser::OpenMPGroupprivate &x) {
+ PushContextAndClauseSets(
+ x.v.DirName().source, llvm::omp::Directive::OMPD_groupprivate);
+}
+
+void OmpStructureChecker::Leave(const parser::OpenMPGroupprivate &x) {
+ dirContext_.pop_back();
+}
+
void OmpStructureChecker::Enter(const parser::OpenMPThreadprivate &c) {
const auto &dir{std::get<parser::Verbatim>(c.t)};
PushContextAndClauseSets(
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index a973aee28d0e2..9bc8ae79f3765 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -126,6 +126,8 @@ class OmpStructureChecker
void Leave(const parser::OpenMPAllocatorsConstruct &);
void Enter(const parser::OpenMPRequiresConstruct &);
void Leave(const parser::OpenMPRequiresConstruct &);
+ void Enter(const parser::OpenMPGroupprivate &);
+ void Leave(const parser::OpenMPGroupprivate &);
void Enter(const parser::OpenMPThreadprivate &);
void Leave(const parser::OpenMPThreadprivate &);
diff --git a/flang/test/Lower/OpenMP/Todo/groupprivate.f90 b/flang/test/Lower/OpenMP/Todo/groupprivate.f90
new file mode 100644
index 0000000000000..9ad9b9382760c
--- /dev/null
+++ b/flang/test/Lower/OpenMP/Todo/groupprivate.f90
@@ -0,0 +1,9 @@
+!RUN: %not_todo_cmd %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=60 -o - %s 2>&1 | FileCheck %s
+
+!CHECK: not yet implemented: GROUPPRIVATE
+
+module m
+implicit none
+integer :: x
+!$omp groupprivate(x)
+end module
diff --git a/flang/test/Parser/OpenMP/groupprivate.f90 b/flang/test/Parser/OpenMP/groupprivate.f90
new file mode 100644
index 0000000000000..8bd840147a2dd
--- /dev/null
+++ b/flang/test/Parser/OpenMP/groupprivate.f90
@@ -0,0 +1,30 @@
+!RUN: %flang_fc1 -fdebug-unparse -fopenmp -fopenmp-version=60 %s | FileCheck --ignore-case --check-prefix="UNPARSE" %s
+!RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=60 %s | FileCheck --check-prefix="PARSE-TREE" %s
+
+module m
+implicit none
+
+integer :: x, y(10), z
+!$omp groupprivate(x, y) device_type(nohost)
+!$omp groupprivate(z)
+
+end module
+
+!UNPARSE: MODULE m
+!UNPARSE: IMPLICIT NONE
+!UNPARSE: INTEGER x, y(10_4), z
+!UNPARSE: !$OMP GROUPPRIVATE(x, y) DEVICE_TYPE(NOHOST)
+!UNPARSE: !$OMP GROUPPRIVATE(z)
+!UNPARSE: END MODULE
+
+!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPGroupprivate -> OmpDirectiveSpecification
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = groupprivate
+!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpLocator -> OmpObject -> Designator -> DataRef -> Name = 'x'
+!PARSE-TREE: | OmpArgument -> OmpLocator -> OmpObject -> Designator -> DataRef -> Name = 'y'
+!PARSE-TREE: | OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> DeviceTypeDescription = Nohost
+!PARSE-TREE: | Flags = None
+!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPGroupprivate -> OmpDirectiveSpecification
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = groupprivate
+!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpLocator -> OmpObject -> Designator -> DataRef -> Name = 'z'
+!PARSE-TREE: | OmpClauseList ->
+!PARSE-TREE: | Flags = None
>From 3a70dbf9221240cee5b7593fc5966e4d6154de8f Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Fri, 15 Aug 2025 09:23:42 -0500
Subject: [PATCH 2/3] Handle grouprivate in GetOmpDirectiveName
---
flang/include/flang/Parser/openmp-utils.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/flang/include/flang/Parser/openmp-utils.h b/flang/include/flang/Parser/openmp-utils.h
index fa0f7656cd5d8..5cae305c55a37 100644
--- a/flang/include/flang/Parser/openmp-utils.h
+++ b/flang/include/flang/Parser/openmp-utils.h
@@ -95,7 +95,8 @@ struct DirectiveNameScope {
std::is_same_v<T, OpenMPDepobjConstruct> ||
std::is_same_v<T, OpenMPFlushConstruct> ||
std::is_same_v<T, OpenMPInteropConstruct> ||
- std::is_same_v<T, OpenMPSimpleStandaloneConstruct>) {
+ std::is_same_v<T, OpenMPSimpleStandaloneConstruct> ||
+ std::is_same_v<T, OpenMPGroupprivate>) {
return x.v.DirName();
} else {
return GetOmpDirectiveName(x.v);
>From ae76658e3e33d06b0bd665395b6e003ce31ad4ae Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Fri, 15 Aug 2025 09:23:44 -0500
Subject: [PATCH 3/3] Fix example
---
.../FlangOmpReport/FlangOmpReportVisitor.cpp | 18 ++----------------
1 file changed, 2 insertions(+), 16 deletions(-)
diff --git a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp
index 5c64870b74be2..cc058bf28329b 100644
--- a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp
+++ b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp
@@ -101,22 +101,8 @@ std::string OpenMPCounterVisitor::getName(const OmpWrapperType &w) {
return getName(*std::get<const OpenMPDeclarativeConstruct *>(w));
}
std::string OpenMPCounterVisitor::getName(const OpenMPDeclarativeConstruct &c) {
- return std::visit( //
- Fortran::common::visitors{
- [&](const OpenMPUtilityConstruct &o) -> std::string {
- const CharBlock &source{o.source};
- return normalize_construct_name(source.ToString());
- },
- [&](const OmpMetadirectiveDirective &o) -> std::string {
- const CharBlock &source{o.source};
- return normalize_construct_name(source.ToString());
- },
- [&](const auto &o) -> std::string {
- const CharBlock &source{std::get<Verbatim>(o.t).source};
- return normalize_construct_name(source.ToString());
- },
- },
- c.u);
+ return normalize_construct_name(
+ omp::GetOmpDirectiveName(c).source.ToString());
}
std::string OpenMPCounterVisitor::getName(const OpenMPConstruct &c) {
return normalize_construct_name(
More information about the llvm-branch-commits
mailing list