[flang][OpenMP] Parse GROUPPRIVATE directive (#153807)

No semantic checks or lowering yet.
This commit is contained in:
Krzysztof Parzyszek 2025-08-19 08:32:43 -05:00 committed by GitHub
parent 292faf6133
commit 42350f428d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 93 additions and 19 deletions

View File

@ -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(

View File

@ -733,6 +733,7 @@ public:
NODE(parser, OpenMPLoopConstruct)
NODE(parser, OpenMPExecutableAllocate)
NODE(parser, OpenMPAllocatorsConstruct)
NODE(parser, OpenMPGroupprivate)
NODE(parser, OpenMPRequiresConstruct)
NODE(parser, OpenMPSimpleStandaloneConstruct)
NODE(parser, OpenMPStandaloneConstruct)

View File

@ -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);

View File

@ -4955,6 +4955,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);
@ -4982,8 +4991,9 @@ struct OpenMPDeclarativeConstruct {
std::variant<OpenMPDeclarativeAllocate, OpenMPDeclarativeAssumes,
OpenMPDeclareMapperConstruct, OpenMPDeclareReductionConstruct,
OpenMPDeclareSimdConstruct, OpenMPDeclareTargetConstruct,
OmpDeclareVariantDirective, OpenMPThreadprivate, OpenMPRequiresConstruct,
OpenMPUtilityConstruct, OmpMetadirectiveDirective>
OmpDeclareVariantDirective, OpenMPGroupprivate, OpenMPThreadprivate,
OpenMPRequiresConstruct, OpenMPUtilityConstruct,
OmpMetadirectiveDirective>
u;
};

View File

@ -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,

View File

@ -1790,6 +1790,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>{})))
@ -1825,6 +1831,8 @@ TYPE_PARSER(
Parser<OmpDeclareVariantDirective>{}) ||
construct<OpenMPDeclarativeConstruct>(
Parser<OpenMPDeclarativeAllocate>{}) ||
construct<OpenMPDeclarativeConstruct>(
Parser<OpenMPGroupprivate>{}) ||
construct<OpenMPDeclarativeConstruct>(
Parser<OpenMPRequiresConstruct>{}) ||
construct<OpenMPDeclarativeConstruct>(

View File

@ -2721,6 +2721,13 @@ public:
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 ");

View File

@ -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);
@ -1175,6 +1179,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(

View File

@ -126,6 +126,8 @@ public:
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 &);

View File

@ -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

View File

@ -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