diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h index ded97c3fb02f9..bd2337d676b2a 100644 --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -480,6 +480,13 @@ class ParseTreeDumper { NODE(parser, OldParameterStmt) NODE(parser, OmpTypeSpecifier) NODE(parser, OmpTypeNameList) + NODE(parser, OmpAdjustArgsClause) + NODE(OmpAdjustArgsClause, OmpAdjustOp) + NODE_ENUM(OmpAdjustArgsClause::OmpAdjustOp, Value) + NODE(parser, OmpInteropType) + NODE_ENUM(OmpInteropType, Value) + NODE(parser, OmpAppendArgsClause) + NODE(OmpAppendArgsClause, OmpAppendOp) NODE(parser, OmpLocator) NODE(parser, OmpLocatorList) NODE(parser, OmpReductionSpecifier) @@ -693,6 +700,7 @@ class ParseTreeDumper { NODE(parser, OpenMPCriticalConstruct) NODE(parser, OpenMPDeclarativeAllocate) NODE(parser, OpenMPDeclarativeConstruct) + NODE(parser, OmpDeclareVariantDirective) NODE(parser, OpenMPDeclareReductionConstruct) NODE(parser, OpenMPDeclareSimdConstruct) NODE(parser, OpenMPDeclareTargetConstruct) diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index cd0be4453ac33..c7bdc8503bc4a 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -3974,6 +3974,15 @@ struct OmpAbsentClause { WRAPPER_CLASS_BOILERPLATE(OmpAbsentClause, OmpDirectiveList); }; +struct OmpAdjustArgsClause { + TUPLE_CLASS_BOILERPLATE(OmpAdjustArgsClause); + struct OmpAdjustOp { + ENUM_CLASS(Value, Nothing, NeedDevicePtr) + WRAPPER_CLASS_BOILERPLATE(OmpAdjustOp, Value); + }; + std::tuple t; +}; + // Ref: [5.0:135-140], [5.1:161-166], [5.2:264-265] // // affinity-clause -> @@ -4017,6 +4026,19 @@ struct OmpAllocateClause { std::tuple t; }; +// InteropType -> target || targetsync +struct OmpInteropType { + ENUM_CLASS(Value, Target, TargetSync) + WRAPPER_CLASS_BOILERPLATE(OmpInteropType, Value); +}; + +struct OmpAppendArgsClause { + struct OmpAppendOp { + WRAPPER_CLASS_BOILERPLATE(OmpAppendOp, std::list); + }; + WRAPPER_CLASS_BOILERPLATE(OmpAppendArgsClause, std::list); +}; + // Ref: [5.2:216-217 (sort of, as it's only mentioned in passing) // AT(compilation|execution) struct OmpAtClause { @@ -4625,6 +4647,12 @@ struct OmpBlockDirective { CharBlock source; }; +struct OmpDeclareVariantDirective { + TUPLE_CLASS_BOILERPLATE(OmpDeclareVariantDirective); + CharBlock source; + std::tuple, Name, OmpClauseList> t; +}; + // 2.10.6 declare-target -> DECLARE TARGET (extended-list) | // DECLARE TARGET [declare-target-clause[ [,] // declare-target-clause]...] @@ -4703,8 +4731,8 @@ struct OpenMPDeclarativeConstruct { std::variant + OmpDeclareVariantDirective, OpenMPThreadprivate, OpenMPRequiresConstruct, + OpenMPUtilityConstruct, OmpMetadirectiveDirective> u; }; diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index ca161bc2ba337..33376ba33fe3f 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -3126,6 +3126,13 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable, TODO(converter.getCurrentLocation(), "OpenMP ASSUMES declaration"); } +static void +genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable, + semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval, + const parser::OmpDeclareVariantDirective &declareVariantDirective) { + TODO(converter.getCurrentLocation(), "OpenMPDeclareVariantDirective"); +} + 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 dd43ede796b98..8777359fb64cb 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -550,6 +550,18 @@ TYPE_PARSER(sourced(construct( TYPE_PARSER(sourced(construct( // Parser{}))) +TYPE_PARSER(construct( + "TARGETSYNC" >> pure(OmpInteropType::Value::TargetSync) || + "TARGET" >> pure(OmpInteropType::Value::Target))) + +TYPE_PARSER(construct( + "INTEROP" >> parenthesized(nonemptyList(Parser{})))) + +TYPE_PARSER(construct( + "NOTHING" >> pure(OmpAdjustArgsClause::OmpAdjustOp::Value::Nothing) || + "NEED_DEVICE_PTR" >> + pure(OmpAdjustArgsClause::OmpAdjustOp::Value::NeedDevicePtr))) + // --- Parsers for clauses -------------------------------------------- /// `MOBClause` is a clause that has a @@ -569,12 +581,19 @@ static inline MOBClause makeMobClause( } } +TYPE_PARSER(construct( + (Parser{} / ":"), + Parser{})) + // [5.0] 2.10.1 affinity([aff-modifier:] locator-list) // aff-modifier: interator-modifier TYPE_PARSER(construct( maybe(nonemptyList(Parser{}) / ":"), Parser{})) +TYPE_PARSER(construct( + parenthesized(nonemptyList(Parser{})))) + // 2.15.3.1 DEFAULT (PRIVATE | FIRSTPRIVATE | SHARED | NONE) TYPE_PARSER(construct( "PRIVATE" >> pure(OmpDefaultClause::DataSharingAttribute::Private) || @@ -808,6 +827,8 @@ TYPE_PARSER("ABSENT" >> construct(construct( parenthesized(Parser{}))) || "ACQUIRE" >> construct(construct()) || "ACQ_REL" >> construct(construct()) || + "ADJUST_ARGS" >> construct(construct( + parenthesized(Parser{}))) || "AFFINITY" >> construct(construct( parenthesized(Parser{}))) || "ALIGN" >> construct(construct( @@ -816,6 +837,8 @@ TYPE_PARSER("ABSENT" >> construct(construct( parenthesized(Parser{}))) || "ALLOCATE" >> construct(construct( parenthesized(Parser{}))) || + "APPEND_ARGS" >> construct(construct( + parenthesized(Parser{}))) || "ALLOCATOR" >> construct(construct( parenthesized(scalarIntExpr))) || "AT" >> construct(construct( @@ -1209,6 +1232,11 @@ TYPE_PARSER(construct( construct(Parser{}) || construct(Parser{}))) +// OpenMP 5.2: 7.5.4 Declare Variant directive +TYPE_PARSER(sourced( + construct(verbatim("DECLARE VARIANT"_tok), + "(" >> maybe(name / ":"), name / ")", Parser{}))) + // 2.16 Declare Reduction Construct TYPE_PARSER(sourced(construct( verbatim("DECLARE REDUCTION"_tok), @@ -1380,6 +1408,8 @@ TYPE_PARSER( Parser{}) || construct( Parser{}) || + construct( + Parser{}) || construct( Parser{}) || construct( diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index 4a4ff623e8323..7a5be38b95d04 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -1604,6 +1604,16 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareSimdConstruct &) { dirContext_.pop_back(); } +void OmpStructureChecker::Enter(const parser::OmpDeclareVariantDirective &x) { + const auto &dir{std::get(x.t)}; + PushContextAndClauseSets( + dir.source, llvm::omp::Directive::OMPD_declare_variant); +} + +void OmpStructureChecker::Leave(const parser::OmpDeclareVariantDirective &) { + dirContext_.pop_back(); +} + void OmpStructureChecker::Enter(const parser::OpenMPDepobjConstruct &x) { const auto &dir{std::get(x.t)}; PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_depobj); diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h index 496915aa44496..d38030e9857c8 100644 --- a/flang/lib/Semantics/check-omp-structure.h +++ b/flang/lib/Semantics/check-omp-structure.h @@ -96,6 +96,8 @@ class OmpStructureChecker void Enter(const parser::OmpEndSectionsDirective &); void Leave(const parser::OmpEndSectionsDirective &); + void Enter(const parser::OmpDeclareVariantDirective &); + void Leave(const parser::OmpDeclareVariantDirective &); void Enter(const parser::OpenMPDeclareSimdConstruct &); void Leave(const parser::OpenMPDeclareSimdConstruct &); void Enter(const parser::OpenMPDeclarativeAllocate &); diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index e57abf8ac0912..a9b6f637f7b6e 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -1494,6 +1494,25 @@ class OmpVisitor : public virtual DeclarationVisitor { return true; } + bool Pre(const parser::OmpDeclareVariantDirective &x) { + AddOmpSourceRange(x.source); + auto FindSymbolOrError = [&](const parser::Name &procName) { + auto *symbol{FindSymbol(NonDerivedTypeScope(), procName)}; + if (!symbol) { + context().Say(procName.source, + "Implicit subroutine declaration '%s' in !$OMP DECLARE VARIANT"_err_en_US, + procName.source); + } + }; + auto &baseProcName = std::get>(x.t); + if (baseProcName) { + FindSymbolOrError(*baseProcName); + } + auto &varProcName = std::get(x.t); + FindSymbolOrError(varProcName); + return true; + } + bool Pre(const parser::OpenMPDeclareReductionConstruct &x) { AddOmpSourceRange(x.source); ProcessReductionSpecifier( diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td index c5d03d554616e..8002d0e7b46a5 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMP.td +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td @@ -43,6 +43,7 @@ def OMPC_AcqRel : Clause<"acq_rel"> { let clangClass = "OMPAcqRelClause"; } def OMPC_AdjustArgs : Clause<"adjust_args"> { + let flangClass = "OmpAdjustArgsClause"; } def OMPC_Affinity : Clause<"affinity"> { let clangClass = "OMPAffinityClause"; @@ -65,6 +66,7 @@ def OMPC_Allocator : Clause<"allocator"> { let flangClass = "ScalarIntExpr"; } def OMPC_AppendArgs : Clause<"append_args"> { + let flangClass = "OmpAppendArgsClause"; } def OMPC_At : Clause<"at"> { let clangClass = "OMPAtClause"; @@ -712,10 +714,10 @@ def OMP_EndDeclareTarget : Directive<"end declare target"> { } def OMP_DeclareVariant : Directive<"declare variant"> { let allowedClauses = [ - VersionedClause, - ]; - let allowedExclusiveClauses = [ VersionedClause, + ]; + let allowedOnceClauses = [ + VersionedClause, VersionedClause, ]; let association = AS_Declaration;