-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[flang][llvm][openmp]Add Initializer clause to OMP.td #129540
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Then use this in the Flang compiler for parsing the OpenMP declare reduction. This has no real functional change to the existing code, it's only moving the declaration itself around. A few tests has been updated, to reflect the new type names.
@llvm/pr-subscribers-flang-parser @llvm/pr-subscribers-flang-fir-hlfir Author: Mats Petersson (Leporacanthicus) ChangesThen use this in the Flang compiler for parsing the OpenMP declare reduction. This has no real functional change to the existing code, it's only moving the declaration itself around. A few tests has been updated, to reflect the new type names. Full diff: https://github.com/llvm/llvm-project/pull/129540.diff 11 Files Affected:
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index 5400d6fac98a9..3b3c6bdc448d7 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -638,9 +638,9 @@ class ParseTreeDumper {
NODE(parser, OmpReductionCombiner)
NODE(parser, OmpTaskReductionClause)
NODE(OmpTaskReductionClause, Modifier)
- NODE(parser, OmpReductionInitializerProc)
- NODE(parser, OmpReductionInitializerExpr)
- NODE(parser, OmpReductionInitializerClause)
+ NODE(parser, OmpInitializerProc)
+ NODE(parser, OmpInitializerExpr)
+ NODE(parser, OmpInitializerClause)
NODE(parser, OmpReductionIdentifier)
NODE(parser, OmpAllocateClause)
NODE(OmpAllocateClause, Modifier)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 2d56a6c9469db..1ad6a9bec40cc 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -4246,6 +4246,20 @@ struct OmpInReductionClause {
std::tuple<MODIFIERS(), OmpObjectList> t;
};
+// declare-reduction -> DECLARE REDUCTION (reduction-identifier : type-list
+// : combiner) [initializer-clause]
+struct OmpInitializerProc {
+ TUPLE_CLASS_BOILERPLATE(OmpInitializerProc);
+ std::tuple<ProcedureDesignator, std::list<ActualArgSpec>> t;
+};
+WRAPPER_CLASS(OmpInitializerExpr, Expr);
+
+// Initialization for declare reduction construct
+struct OmpInitializerClause {
+ UNION_CLASS_BOILERPLATE(OmpInitializerClause);
+ std::variant<OmpInitializerProc, OmpInitializerExpr> u;
+};
+
// Ref: [4.5:199-201], [5.0:288-290], [5.1:321-322], [5.2:115-117]
//
// lastprivate-clause ->
@@ -4627,24 +4641,14 @@ struct OpenMPDeclareMapperConstruct {
std::tuple<Verbatim, OmpMapperSpecifier, OmpClauseList> t;
};
+// ref: 5.2: Section 5.5.11 139-141
// 2.16 declare-reduction -> DECLARE REDUCTION (reduction-identifier : type-list
// : combiner) [initializer-clause]
-struct OmpReductionInitializerProc {
- TUPLE_CLASS_BOILERPLATE(OmpReductionInitializerProc);
- std::tuple<ProcedureDesignator, std::list<ActualArgSpec>> t;
-};
-WRAPPER_CLASS(OmpReductionInitializerExpr, Expr);
-
-struct OmpReductionInitializerClause {
- UNION_CLASS_BOILERPLATE(OmpReductionInitializerClause);
- std::variant<OmpReductionInitializerProc, OmpReductionInitializerExpr> u;
-};
-
struct OpenMPDeclareReductionConstruct {
TUPLE_CLASS_BOILERPLATE(OpenMPDeclareReductionConstruct);
CharBlock source;
std::tuple<Verbatim, common::Indirection<OmpReductionSpecifier>,
- std::optional<OmpReductionInitializerClause>>
+ OmpClauseList>
t;
};
diff --git a/flang/lib/Lower/OpenMP/Clauses.cpp b/flang/lib/Lower/OpenMP/Clauses.cpp
index 831ba23870360..84092b75e0b3c 100644
--- a/flang/lib/Lower/OpenMP/Clauses.cpp
+++ b/flang/lib/Lower/OpenMP/Clauses.cpp
@@ -863,7 +863,10 @@ Init make(const parser::OmpClause::Init &inp,
llvm_unreachable("Empty: init");
}
-// Initializer: missing-in-parser
+Initializer make(const parser::OmpClause::Initializer &inp,
+ semantics::SemanticsContext &semaCtx) {
+ llvm_unreachable("Empty: initializer");
+}
InReduction make(const parser::OmpClause::InReduction &inp,
semantics::SemanticsContext &semaCtx) {
diff --git a/flang/lib/Lower/OpenMP/Clauses.h b/flang/lib/Lower/OpenMP/Clauses.h
index 0f172e0acf626..25385e3c04086 100644
--- a/flang/lib/Lower/OpenMP/Clauses.h
+++ b/flang/lib/Lower/OpenMP/Clauses.h
@@ -231,6 +231,7 @@ using Inbranch = tomp::clause::InbranchT<TypeTy, IdTy, ExprTy>;
using Inclusive = tomp::clause::InclusiveT<TypeTy, IdTy, ExprTy>;
using Indirect = tomp::clause::IndirectT<TypeTy, IdTy, ExprTy>;
using Init = tomp::clause::InitT<TypeTy, IdTy, ExprTy>;
+using Initializer = tomp::clause::InitT<TypeTy, IdTy, ExprTy>;
using InReduction = tomp::clause::InReductionT<TypeTy, IdTy, ExprTy>;
using IsDevicePtr = tomp::clause::IsDevicePtrT<TypeTy, IdTy, ExprTy>;
using Lastprivate = tomp::clause::LastprivateT<TypeTy, IdTy, ExprTy>;
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 6409d9c4908f2..dde82dd2cf16f 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -855,6 +855,8 @@ TYPE_PARSER("ABSENT" >> construct<OmpClause>(construct<OmpClause::Absent>(
"INBRANCH" >> construct<OmpClause>(construct<OmpClause::Inbranch>()) ||
"INCLUSIVE" >> construct<OmpClause>(construct<OmpClause::Inclusive>(
parenthesized(Parser<OmpObjectList>{}))) ||
+ "INITIALIZER" >> construct<OmpClause>(construct<OmpClause::Initializer>(
+ parenthesized(Parser<OmpInitializerClause>{}))) ||
"IS_DEVICE_PTR" >> construct<OmpClause>(construct<OmpClause::IsDevicePtr>(
parenthesized(Parser<OmpObjectList>{}))) ||
"LASTPRIVATE" >> construct<OmpClause>(construct<OmpClause::Lastprivate>(
@@ -1174,22 +1176,19 @@ TYPE_PARSER(construct<OmpBlockDirective>(first(
TYPE_PARSER(sourced(construct<OmpBeginBlockDirective>(
sourced(Parser<OmpBlockDirective>{}), Parser<OmpClauseList>{})))
-TYPE_PARSER(construct<OmpReductionInitializerExpr>("OMP_PRIV =" >> expr))
-TYPE_PARSER(
- construct<OmpReductionInitializerProc>(Parser<ProcedureDesignator>{},
- parenthesized(many(maybe(","_tok) >> Parser<ActualArgSpec>{}))))
+TYPE_PARSER(construct<OmpInitializerExpr>("OMP_PRIV =" >> expr))
+TYPE_PARSER(construct<OmpInitializerProc>(Parser<ProcedureDesignator>{},
+ parenthesized(many(maybe(","_tok) >> Parser<ActualArgSpec>{}))))
-TYPE_PARSER(construct<OmpReductionInitializerClause>(
- "INITIALIZER" >> parenthesized(construct<OmpReductionInitializerClause>(
- Parser<OmpReductionInitializerExpr>{}) ||
- construct<OmpReductionInitializerClause>(
- Parser<OmpReductionInitializerProc>{}))))
+TYPE_PARSER(construct<OmpInitializerClause>(
+ construct<OmpInitializerClause>(Parser<OmpInitializerExpr>{}) ||
+ construct<OmpInitializerClause>(Parser<OmpInitializerProc>{})))
// 2.16 Declare Reduction Construct
TYPE_PARSER(sourced(construct<OpenMPDeclareReductionConstruct>(
verbatim("DECLARE REDUCTION"_tok),
"(" >> indirect(Parser<OmpReductionSpecifier>{}) / ")",
- maybe(Parser<OmpReductionInitializerClause>{}))))
+ Parser<OmpClauseList>{})))
// declare-target with list
TYPE_PARSER(sourced(construct<OmpDeclareTargetWithList>(
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index e55cc97429b49..c08b8d2127429 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2699,28 +2699,24 @@ class UnparseVisitor {
void Unparse(const OmpDeclareTargetWithList &x) {
Put("("), Walk(x.v), Put(")");
}
- void Unparse(const OmpReductionInitializerProc &x) {
+ void Unparse(const OmpInitializerProc &x) {
Walk(std::get<ProcedureDesignator>(x.t));
Put("(");
Walk(std::get<std::list<ActualArgSpec>>(x.t));
Put(")");
}
- void Unparse(const OmpReductionInitializerExpr &x) {
+ void Unparse(const OmpInitializerExpr &x) {
Word("OMP_PRIV = ");
Walk(x.v);
}
- void Unparse(const OmpReductionInitializerClause &x) {
- Word(" INITIALIZER(");
- Walk(x.u);
- Put(")");
- }
+ void Unparse(const OmpInitializerClause &x) { Walk(x.u); }
void Unparse(const OpenMPDeclareReductionConstruct &x) {
BeginOpenMP();
Word("!$OMP DECLARE REDUCTION ");
Put("(");
Walk(std::get<common::Indirection<OmpReductionSpecifier>>(x.t));
Put(")");
- Walk(std::get<std::optional<OmpReductionInitializerClause>>(x.t));
+ Walk(std::get<OmpClauseList>(x.t));
Put("\n");
EndOpenMP();
}
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 75602ca911429..c6ed211549401 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1678,6 +1678,18 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareMapperConstruct &) {
dirContext_.pop_back();
}
+void OmpStructureChecker::Enter(
+ const parser::OpenMPDeclareReductionConstruct &x) {
+ const auto &dir{std::get<parser::Verbatim>(x.t)};
+ PushContextAndClauseSets(
+ dir.source, llvm::omp::Directive::OMPD_declare_reduction);
+}
+
+void OmpStructureChecker::Leave(
+ const parser::OpenMPDeclareReductionConstruct &) {
+ dirContext_.pop_back();
+}
+
void OmpStructureChecker::Enter(const parser::OpenMPDeclareTargetConstruct &x) {
const auto &dir{std::get<parser::Verbatim>(x.t)};
PushContext(dir.source, llvm::omp::Directive::OMPD_declare_target);
@@ -2990,6 +3002,7 @@ CHECK_SIMPLE_CLAUSE(Grainsize, OMPC_grainsize)
CHECK_SIMPLE_CLAUSE(Hint, OMPC_hint)
CHECK_SIMPLE_CLAUSE(Holds, OMPC_holds)
CHECK_SIMPLE_CLAUSE(Inclusive, OMPC_inclusive)
+CHECK_SIMPLE_CLAUSE(Initializer, OMPC_initializer)
CHECK_SIMPLE_CLAUSE(Match, OMPC_match)
CHECK_SIMPLE_CLAUSE(Nontemporal, OMPC_nontemporal)
CHECK_SIMPLE_CLAUSE(NumTasks, OMPC_num_tasks)
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index 63278616bbf5b..b70ea58cf5578 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -102,6 +102,8 @@ class OmpStructureChecker
void Leave(const parser::OpenMPDeclarativeAllocate &);
void Enter(const parser::OpenMPDeclareMapperConstruct &);
void Leave(const parser::OpenMPDeclareMapperConstruct &);
+ void Enter(const parser::OpenMPDeclareReductionConstruct &);
+ void Leave(const parser::OpenMPDeclareReductionConstruct &);
void Enter(const parser::OpenMPDeclareTargetConstruct &);
void Leave(const parser::OpenMPDeclareTargetConstruct &);
void Enter(const parser::OpenMPDepobjConstruct &);
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index c582b690a293d..cb3a839119b42 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1482,7 +1482,7 @@ class OmpVisitor : public virtual DeclarationVisitor {
return false;
}
- bool Pre(const parser::OmpReductionInitializerProc &x) {
+ bool Pre(const parser::OmpInitializerProc &x) {
auto &procDes = std::get<parser::ProcedureDesignator>(x.t);
auto &name = std::get<parser::Name>(procDes.u);
auto *symbol{FindSymbol(NonDerivedTypeScope(), name)};
@@ -1500,9 +1500,7 @@ class OmpVisitor : public virtual DeclarationVisitor {
ProcessReductionSpecifier(
std::get<Indirection<parser::OmpReductionSpecifier>>(x.t).value(),
emptyList);
- auto &init =
- std::get<std::optional<parser::OmpReductionInitializerClause>>(x.t);
- Walk(init);
+ Walk(std::get<parser::OmpClauseList>(x.t));
return false;
}
bool Pre(const parser::OmpMapClause &);
diff --git a/flang/test/Parser/OpenMP/declare-reduction-unparse.f90 b/flang/test/Parser/OpenMP/declare-reduction-unparse.f90
index e7b15fb3e9d2c..f0ab99f5cfb5f 100644
--- a/flang/test/Parser/OpenMP/declare-reduction-unparse.f90
+++ b/flang/test/Parser/OpenMP/declare-reduction-unparse.f90
@@ -23,7 +23,7 @@ end subroutine initme
!$omp declare reduction(red_add:integer(4):omp_out=omp_out+omp_in) initializer(initme(omp_priv,0))
!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct
!PARSE-TREE: OmpReductionCombiner -> AssignmentStmt = 'omp_out=omp_out+omp_in'
-!PARSE-TREE: OmpReductionInitializerClause -> OmpReductionInitializerProc
+!PARSE-TREE: OmpInitializerClause -> OmpInitializerProc
!PARSE-TREE-NEXT: ProcedureDesignator -> Name = 'initme'
res=init
!$omp simd reduction(red_add:res)
@@ -58,4 +58,4 @@ end program main
!PARSE-TREE: OmpReductionIdentifier -> ProcedureDesignator -> Name = 'my_add_red'
!PARSE-TREE: DeclarationTypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec
!PARSE-TREE: OmpReductionCombiner -> AssignmentStmt = 'omp_out=omp_out+omp_in'
-!PARSE-TREE: OmpReductionInitializerClause -> OmpReductionInitializerExpr -> Expr = '0_4'
+!PARSE-TREE: OmpInitializerClause -> OmpInitializerExpr -> Expr = '0_4'
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index 39fd46bcbd4ee..8a2f30a7995dc 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -244,6 +244,9 @@ def OMPC_Indirect : Clause<"indirect"> {
def OMPC_Init : Clause<"init"> {
let clangClass = "OMPInitClause";
}
+def OMPC_Initializer : Clause<"initializer"> {
+ let flangClass = "OmpInitializerClause";
+}
def OMPC_InReduction : Clause<"in_reduction"> {
let clangClass = "OMPInReductionClause";
let flangClass = "OmpInReductionClause";
@@ -668,6 +671,9 @@ def OMP_DeclareMapper : Directive<"declare mapper"> {
let category = CA_Declarative;
}
def OMP_DeclareReduction : Directive<"declare reduction"> {
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_Initializer>,
+ ];
let association = AS_None;
let category = CA_Declarative;
}
|
@llvm/pr-subscribers-flang-openmp Author: Mats Petersson (Leporacanthicus) ChangesThen use this in the Flang compiler for parsing the OpenMP declare reduction. This has no real functional change to the existing code, it's only moving the declaration itself around. A few tests has been updated, to reflect the new type names. Full diff: https://github.com/llvm/llvm-project/pull/129540.diff 11 Files Affected:
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index 5400d6fac98a9..3b3c6bdc448d7 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -638,9 +638,9 @@ class ParseTreeDumper {
NODE(parser, OmpReductionCombiner)
NODE(parser, OmpTaskReductionClause)
NODE(OmpTaskReductionClause, Modifier)
- NODE(parser, OmpReductionInitializerProc)
- NODE(parser, OmpReductionInitializerExpr)
- NODE(parser, OmpReductionInitializerClause)
+ NODE(parser, OmpInitializerProc)
+ NODE(parser, OmpInitializerExpr)
+ NODE(parser, OmpInitializerClause)
NODE(parser, OmpReductionIdentifier)
NODE(parser, OmpAllocateClause)
NODE(OmpAllocateClause, Modifier)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 2d56a6c9469db..1ad6a9bec40cc 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -4246,6 +4246,20 @@ struct OmpInReductionClause {
std::tuple<MODIFIERS(), OmpObjectList> t;
};
+// declare-reduction -> DECLARE REDUCTION (reduction-identifier : type-list
+// : combiner) [initializer-clause]
+struct OmpInitializerProc {
+ TUPLE_CLASS_BOILERPLATE(OmpInitializerProc);
+ std::tuple<ProcedureDesignator, std::list<ActualArgSpec>> t;
+};
+WRAPPER_CLASS(OmpInitializerExpr, Expr);
+
+// Initialization for declare reduction construct
+struct OmpInitializerClause {
+ UNION_CLASS_BOILERPLATE(OmpInitializerClause);
+ std::variant<OmpInitializerProc, OmpInitializerExpr> u;
+};
+
// Ref: [4.5:199-201], [5.0:288-290], [5.1:321-322], [5.2:115-117]
//
// lastprivate-clause ->
@@ -4627,24 +4641,14 @@ struct OpenMPDeclareMapperConstruct {
std::tuple<Verbatim, OmpMapperSpecifier, OmpClauseList> t;
};
+// ref: 5.2: Section 5.5.11 139-141
// 2.16 declare-reduction -> DECLARE REDUCTION (reduction-identifier : type-list
// : combiner) [initializer-clause]
-struct OmpReductionInitializerProc {
- TUPLE_CLASS_BOILERPLATE(OmpReductionInitializerProc);
- std::tuple<ProcedureDesignator, std::list<ActualArgSpec>> t;
-};
-WRAPPER_CLASS(OmpReductionInitializerExpr, Expr);
-
-struct OmpReductionInitializerClause {
- UNION_CLASS_BOILERPLATE(OmpReductionInitializerClause);
- std::variant<OmpReductionInitializerProc, OmpReductionInitializerExpr> u;
-};
-
struct OpenMPDeclareReductionConstruct {
TUPLE_CLASS_BOILERPLATE(OpenMPDeclareReductionConstruct);
CharBlock source;
std::tuple<Verbatim, common::Indirection<OmpReductionSpecifier>,
- std::optional<OmpReductionInitializerClause>>
+ OmpClauseList>
t;
};
diff --git a/flang/lib/Lower/OpenMP/Clauses.cpp b/flang/lib/Lower/OpenMP/Clauses.cpp
index 831ba23870360..84092b75e0b3c 100644
--- a/flang/lib/Lower/OpenMP/Clauses.cpp
+++ b/flang/lib/Lower/OpenMP/Clauses.cpp
@@ -863,7 +863,10 @@ Init make(const parser::OmpClause::Init &inp,
llvm_unreachable("Empty: init");
}
-// Initializer: missing-in-parser
+Initializer make(const parser::OmpClause::Initializer &inp,
+ semantics::SemanticsContext &semaCtx) {
+ llvm_unreachable("Empty: initializer");
+}
InReduction make(const parser::OmpClause::InReduction &inp,
semantics::SemanticsContext &semaCtx) {
diff --git a/flang/lib/Lower/OpenMP/Clauses.h b/flang/lib/Lower/OpenMP/Clauses.h
index 0f172e0acf626..25385e3c04086 100644
--- a/flang/lib/Lower/OpenMP/Clauses.h
+++ b/flang/lib/Lower/OpenMP/Clauses.h
@@ -231,6 +231,7 @@ using Inbranch = tomp::clause::InbranchT<TypeTy, IdTy, ExprTy>;
using Inclusive = tomp::clause::InclusiveT<TypeTy, IdTy, ExprTy>;
using Indirect = tomp::clause::IndirectT<TypeTy, IdTy, ExprTy>;
using Init = tomp::clause::InitT<TypeTy, IdTy, ExprTy>;
+using Initializer = tomp::clause::InitT<TypeTy, IdTy, ExprTy>;
using InReduction = tomp::clause::InReductionT<TypeTy, IdTy, ExprTy>;
using IsDevicePtr = tomp::clause::IsDevicePtrT<TypeTy, IdTy, ExprTy>;
using Lastprivate = tomp::clause::LastprivateT<TypeTy, IdTy, ExprTy>;
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 6409d9c4908f2..dde82dd2cf16f 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -855,6 +855,8 @@ TYPE_PARSER("ABSENT" >> construct<OmpClause>(construct<OmpClause::Absent>(
"INBRANCH" >> construct<OmpClause>(construct<OmpClause::Inbranch>()) ||
"INCLUSIVE" >> construct<OmpClause>(construct<OmpClause::Inclusive>(
parenthesized(Parser<OmpObjectList>{}))) ||
+ "INITIALIZER" >> construct<OmpClause>(construct<OmpClause::Initializer>(
+ parenthesized(Parser<OmpInitializerClause>{}))) ||
"IS_DEVICE_PTR" >> construct<OmpClause>(construct<OmpClause::IsDevicePtr>(
parenthesized(Parser<OmpObjectList>{}))) ||
"LASTPRIVATE" >> construct<OmpClause>(construct<OmpClause::Lastprivate>(
@@ -1174,22 +1176,19 @@ TYPE_PARSER(construct<OmpBlockDirective>(first(
TYPE_PARSER(sourced(construct<OmpBeginBlockDirective>(
sourced(Parser<OmpBlockDirective>{}), Parser<OmpClauseList>{})))
-TYPE_PARSER(construct<OmpReductionInitializerExpr>("OMP_PRIV =" >> expr))
-TYPE_PARSER(
- construct<OmpReductionInitializerProc>(Parser<ProcedureDesignator>{},
- parenthesized(many(maybe(","_tok) >> Parser<ActualArgSpec>{}))))
+TYPE_PARSER(construct<OmpInitializerExpr>("OMP_PRIV =" >> expr))
+TYPE_PARSER(construct<OmpInitializerProc>(Parser<ProcedureDesignator>{},
+ parenthesized(many(maybe(","_tok) >> Parser<ActualArgSpec>{}))))
-TYPE_PARSER(construct<OmpReductionInitializerClause>(
- "INITIALIZER" >> parenthesized(construct<OmpReductionInitializerClause>(
- Parser<OmpReductionInitializerExpr>{}) ||
- construct<OmpReductionInitializerClause>(
- Parser<OmpReductionInitializerProc>{}))))
+TYPE_PARSER(construct<OmpInitializerClause>(
+ construct<OmpInitializerClause>(Parser<OmpInitializerExpr>{}) ||
+ construct<OmpInitializerClause>(Parser<OmpInitializerProc>{})))
// 2.16 Declare Reduction Construct
TYPE_PARSER(sourced(construct<OpenMPDeclareReductionConstruct>(
verbatim("DECLARE REDUCTION"_tok),
"(" >> indirect(Parser<OmpReductionSpecifier>{}) / ")",
- maybe(Parser<OmpReductionInitializerClause>{}))))
+ Parser<OmpClauseList>{})))
// declare-target with list
TYPE_PARSER(sourced(construct<OmpDeclareTargetWithList>(
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index e55cc97429b49..c08b8d2127429 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2699,28 +2699,24 @@ class UnparseVisitor {
void Unparse(const OmpDeclareTargetWithList &x) {
Put("("), Walk(x.v), Put(")");
}
- void Unparse(const OmpReductionInitializerProc &x) {
+ void Unparse(const OmpInitializerProc &x) {
Walk(std::get<ProcedureDesignator>(x.t));
Put("(");
Walk(std::get<std::list<ActualArgSpec>>(x.t));
Put(")");
}
- void Unparse(const OmpReductionInitializerExpr &x) {
+ void Unparse(const OmpInitializerExpr &x) {
Word("OMP_PRIV = ");
Walk(x.v);
}
- void Unparse(const OmpReductionInitializerClause &x) {
- Word(" INITIALIZER(");
- Walk(x.u);
- Put(")");
- }
+ void Unparse(const OmpInitializerClause &x) { Walk(x.u); }
void Unparse(const OpenMPDeclareReductionConstruct &x) {
BeginOpenMP();
Word("!$OMP DECLARE REDUCTION ");
Put("(");
Walk(std::get<common::Indirection<OmpReductionSpecifier>>(x.t));
Put(")");
- Walk(std::get<std::optional<OmpReductionInitializerClause>>(x.t));
+ Walk(std::get<OmpClauseList>(x.t));
Put("\n");
EndOpenMP();
}
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 75602ca911429..c6ed211549401 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1678,6 +1678,18 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareMapperConstruct &) {
dirContext_.pop_back();
}
+void OmpStructureChecker::Enter(
+ const parser::OpenMPDeclareReductionConstruct &x) {
+ const auto &dir{std::get<parser::Verbatim>(x.t)};
+ PushContextAndClauseSets(
+ dir.source, llvm::omp::Directive::OMPD_declare_reduction);
+}
+
+void OmpStructureChecker::Leave(
+ const parser::OpenMPDeclareReductionConstruct &) {
+ dirContext_.pop_back();
+}
+
void OmpStructureChecker::Enter(const parser::OpenMPDeclareTargetConstruct &x) {
const auto &dir{std::get<parser::Verbatim>(x.t)};
PushContext(dir.source, llvm::omp::Directive::OMPD_declare_target);
@@ -2990,6 +3002,7 @@ CHECK_SIMPLE_CLAUSE(Grainsize, OMPC_grainsize)
CHECK_SIMPLE_CLAUSE(Hint, OMPC_hint)
CHECK_SIMPLE_CLAUSE(Holds, OMPC_holds)
CHECK_SIMPLE_CLAUSE(Inclusive, OMPC_inclusive)
+CHECK_SIMPLE_CLAUSE(Initializer, OMPC_initializer)
CHECK_SIMPLE_CLAUSE(Match, OMPC_match)
CHECK_SIMPLE_CLAUSE(Nontemporal, OMPC_nontemporal)
CHECK_SIMPLE_CLAUSE(NumTasks, OMPC_num_tasks)
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index 63278616bbf5b..b70ea58cf5578 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -102,6 +102,8 @@ class OmpStructureChecker
void Leave(const parser::OpenMPDeclarativeAllocate &);
void Enter(const parser::OpenMPDeclareMapperConstruct &);
void Leave(const parser::OpenMPDeclareMapperConstruct &);
+ void Enter(const parser::OpenMPDeclareReductionConstruct &);
+ void Leave(const parser::OpenMPDeclareReductionConstruct &);
void Enter(const parser::OpenMPDeclareTargetConstruct &);
void Leave(const parser::OpenMPDeclareTargetConstruct &);
void Enter(const parser::OpenMPDepobjConstruct &);
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index c582b690a293d..cb3a839119b42 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1482,7 +1482,7 @@ class OmpVisitor : public virtual DeclarationVisitor {
return false;
}
- bool Pre(const parser::OmpReductionInitializerProc &x) {
+ bool Pre(const parser::OmpInitializerProc &x) {
auto &procDes = std::get<parser::ProcedureDesignator>(x.t);
auto &name = std::get<parser::Name>(procDes.u);
auto *symbol{FindSymbol(NonDerivedTypeScope(), name)};
@@ -1500,9 +1500,7 @@ class OmpVisitor : public virtual DeclarationVisitor {
ProcessReductionSpecifier(
std::get<Indirection<parser::OmpReductionSpecifier>>(x.t).value(),
emptyList);
- auto &init =
- std::get<std::optional<parser::OmpReductionInitializerClause>>(x.t);
- Walk(init);
+ Walk(std::get<parser::OmpClauseList>(x.t));
return false;
}
bool Pre(const parser::OmpMapClause &);
diff --git a/flang/test/Parser/OpenMP/declare-reduction-unparse.f90 b/flang/test/Parser/OpenMP/declare-reduction-unparse.f90
index e7b15fb3e9d2c..f0ab99f5cfb5f 100644
--- a/flang/test/Parser/OpenMP/declare-reduction-unparse.f90
+++ b/flang/test/Parser/OpenMP/declare-reduction-unparse.f90
@@ -23,7 +23,7 @@ end subroutine initme
!$omp declare reduction(red_add:integer(4):omp_out=omp_out+omp_in) initializer(initme(omp_priv,0))
!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct
!PARSE-TREE: OmpReductionCombiner -> AssignmentStmt = 'omp_out=omp_out+omp_in'
-!PARSE-TREE: OmpReductionInitializerClause -> OmpReductionInitializerProc
+!PARSE-TREE: OmpInitializerClause -> OmpInitializerProc
!PARSE-TREE-NEXT: ProcedureDesignator -> Name = 'initme'
res=init
!$omp simd reduction(red_add:res)
@@ -58,4 +58,4 @@ end program main
!PARSE-TREE: OmpReductionIdentifier -> ProcedureDesignator -> Name = 'my_add_red'
!PARSE-TREE: DeclarationTypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec
!PARSE-TREE: OmpReductionCombiner -> AssignmentStmt = 'omp_out=omp_out+omp_in'
-!PARSE-TREE: OmpReductionInitializerClause -> OmpReductionInitializerExpr -> Expr = '0_4'
+!PARSE-TREE: OmpInitializerClause -> OmpInitializerExpr -> Expr = '0_4'
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index 39fd46bcbd4ee..8a2f30a7995dc 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -244,6 +244,9 @@ def OMPC_Indirect : Clause<"indirect"> {
def OMPC_Init : Clause<"init"> {
let clangClass = "OMPInitClause";
}
+def OMPC_Initializer : Clause<"initializer"> {
+ let flangClass = "OmpInitializerClause";
+}
def OMPC_InReduction : Clause<"in_reduction"> {
let clangClass = "OMPInReductionClause";
let flangClass = "OmpInReductionClause";
@@ -668,6 +671,9 @@ def OMP_DeclareMapper : Directive<"declare mapper"> {
let category = CA_Declarative;
}
def OMP_DeclareReduction : Directive<"declare reduction"> {
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_Initializer>,
+ ];
let association = AS_None;
let category = CA_Declarative;
}
|
flang/lib/Lower/OpenMP/Clauses.h
Outdated
@@ -231,6 +231,7 @@ using Inbranch = tomp::clause::InbranchT<TypeTy, IdTy, ExprTy>; | |||
using Inclusive = tomp::clause::InclusiveT<TypeTy, IdTy, ExprTy>; | |||
using Indirect = tomp::clause::IndirectT<TypeTy, IdTy, ExprTy>; | |||
using Init = tomp::clause::InitT<TypeTy, IdTy, ExprTy>; | |||
using Initializer = tomp::clause::InitT<TypeTy, IdTy, ExprTy>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
using Initializer = tomp::clause::InitializerT<...>
There are both init
and initializer
, the former is used in interop, the latter in declare reduction.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Argh, dumb mistake.
struct OpenMPDeclareReductionConstruct { | ||
TUPLE_CLASS_BOILERPLATE(OpenMPDeclareReductionConstruct); | ||
CharBlock source; | ||
std::tuple<Verbatim, common::Indirection<OmpReductionSpecifier>, | ||
std::optional<OmpReductionInitializerClause>> | ||
OmpClauseList> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you make this optional, and use maybe(Parser<OmpClauseList>)
for this? This scheme (i.e. "lists are nonempty, otherwise std::nullopt") is used across the OpenMP parsers, plus empty lists are harder to deal with (the empty list parser will always succeed).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense. So done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, thanks!
Then use this in the Flang compiler for parsing the OpenMP declare reduction. This has no real functional change to the existing code, it's only moving the declaration itself around. A few tests has been updated, to reflect the new type names.
Then use this in the Flang compiler for parsing the OpenMP declare reduction.
This has no real functional change to the existing code, it's only moving the declaration itself around.
A few tests has been updated, to reflect the new type names.