diff --git a/flang/examples/FeatureList/FeatureList.cpp b/flang/examples/FeatureList/FeatureList.cpp index e35f120d8661e..ddb9dee5b8a8e 100644 --- a/flang/examples/FeatureList/FeatureList.cpp +++ b/flang/examples/FeatureList/FeatureList.cpp @@ -514,7 +514,7 @@ struct NodeVisitor { READ_FEATURE(OmpReductionClause) READ_FEATURE(OmpInReductionClause) READ_FEATURE(OmpReductionCombiner) - READ_FEATURE(OmpReductionInitializerClause) + READ_FEATURE(OmpInitializerClause) READ_FEATURE(OmpReductionIdentifier) READ_FEATURE(OmpAllocateClause) READ_FEATURE(OmpAllocateClause::Modifier) 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..f11859bb09ddb 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 t; }; +// declare-reduction -> DECLARE REDUCTION (reduction-identifier : type-list +// : combiner) [initializer-clause] +struct OmpInitializerProc { + TUPLE_CLASS_BOILERPLATE(OmpInitializerProc); + std::tuple> t; +}; +WRAPPER_CLASS(OmpInitializerExpr, Expr); + +// Initialization for declare reduction construct +struct OmpInitializerClause { + UNION_CLASS_BOILERPLATE(OmpInitializerClause); + std::variant 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 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> t; -}; -WRAPPER_CLASS(OmpReductionInitializerExpr, Expr); - -struct OmpReductionInitializerClause { - UNION_CLASS_BOILERPLATE(OmpReductionInitializerClause); - std::variant u; -}; - struct OpenMPDeclareReductionConstruct { TUPLE_CLASS_BOILERPLATE(OpenMPDeclareReductionConstruct); CharBlock source; std::tuple, - std::optional> + std::optional> 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..23c984412df3e 100644 --- a/flang/lib/Lower/OpenMP/Clauses.h +++ b/flang/lib/Lower/OpenMP/Clauses.h @@ -231,6 +231,7 @@ using Inbranch = tomp::clause::InbranchT; using Inclusive = tomp::clause::InclusiveT; using Indirect = tomp::clause::IndirectT; using Init = tomp::clause::InitT; +using Initializer = tomp::clause::InitializerT; using InReduction = tomp::clause::InReductionT; using IsDevicePtr = tomp::clause::IsDevicePtrT; using Lastprivate = tomp::clause::LastprivateT; diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index 6409d9c4908f2..43cd2ea1eb0e6 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -855,6 +855,8 @@ TYPE_PARSER("ABSENT" >> construct(construct( "INBRANCH" >> construct(construct()) || "INCLUSIVE" >> construct(construct( parenthesized(Parser{}))) || + "INITIALIZER" >> construct(construct( + parenthesized(Parser{}))) || "IS_DEVICE_PTR" >> construct(construct( parenthesized(Parser{}))) || "LASTPRIVATE" >> construct(construct( @@ -1174,22 +1176,19 @@ TYPE_PARSER(construct(first( TYPE_PARSER(sourced(construct( sourced(Parser{}), Parser{}))) -TYPE_PARSER(construct("OMP_PRIV =" >> expr)) -TYPE_PARSER( - construct(Parser{}, - parenthesized(many(maybe(","_tok) >> Parser{})))) +TYPE_PARSER(construct("OMP_PRIV =" >> expr)) +TYPE_PARSER(construct(Parser{}, + parenthesized(many(maybe(","_tok) >> Parser{})))) -TYPE_PARSER(construct( - "INITIALIZER" >> parenthesized(construct( - Parser{}) || - construct( - Parser{})))) +TYPE_PARSER(construct( + construct(Parser{}) || + construct(Parser{}))) // 2.16 Declare Reduction Construct TYPE_PARSER(sourced(construct( verbatim("DECLARE REDUCTION"_tok), "(" >> indirect(Parser{}) / ")", - maybe(Parser{})))) + maybe(Parser{})))) // declare-target with list TYPE_PARSER(sourced(construct( diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index e55cc97429b49..1df17b6d7382b 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(x.t)); Put("("); Walk(std::get>(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>(x.t)); Put(")"); - Walk(std::get>(x.t)); + Walk(std::get>(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(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(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..848830e831427 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(x.t); auto &name = std::get(procDes.u); auto *symbol{FindSymbol(NonDerivedTypeScope(), name)}; @@ -1496,13 +1496,9 @@ class OmpVisitor : public virtual DeclarationVisitor { bool Pre(const parser::OpenMPDeclareReductionConstruct &x) { AddOmpSourceRange(x.source); - parser::OmpClauseList emptyList{std::list{}}; ProcessReductionSpecifier( std::get>(x.t).value(), - emptyList); - auto &init = - std::get>(x.t); - Walk(init); + std::get>(x.t)); return false; } bool Pre(const parser::OmpMapClause &); @@ -1659,7 +1655,7 @@ class OmpVisitor : public virtual DeclarationVisitor { void ProcessMapperSpecifier(const parser::OmpMapperSpecifier &spec, const parser::OmpClauseList &clauses); void ProcessReductionSpecifier(const parser::OmpReductionSpecifier &spec, - const parser::OmpClauseList &clauses); + const std::optional &clauses); }; bool OmpVisitor::NeedsScope(const parser::OpenMPBlockConstruct &x) { @@ -1754,7 +1750,7 @@ void OmpVisitor::ProcessMapperSpecifier(const parser::OmpMapperSpecifier &spec, void OmpVisitor::ProcessReductionSpecifier( const parser::OmpReductionSpecifier &spec, - const parser::OmpClauseList &clauses) { + const std::optional &clauses) { const auto &id{std::get(spec.t)}; if (auto procDes{std::get_if(&id.u)}) { if (auto *name{std::get_if(&procDes->u)}) { @@ -1796,7 +1792,7 @@ bool OmpVisitor::Pre(const parser::OmpDirectiveSpecification &x) { if (maybeArgs && maybeClauses) { const parser::OmpArgument &first{maybeArgs->front()}; if (auto *spec{std::get_if(&first.u)}) { - ProcessReductionSpecifier(*spec, *maybeClauses); + ProcessReductionSpecifier(*spec, maybeClauses); } } break; 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, + ]; let association = AS_None; let category = CA_Declarative; }