diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h index 23e35d106c077..69acd31f3753f 100644 --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -581,6 +581,8 @@ class ParseTreeDumper { NODE(parser, OmpDependClause) NODE(OmpDependClause, TaskDep) NODE(OmpDependClause::TaskDep, Modifier) + NODE(parser, OmpAutomapModifier) + NODE_ENUM(OmpAutomapModifier, Value) NODE(parser, OmpDetachClause) NODE(parser, OmpDoacrossClause) NODE(parser, OmpDestroyClause) @@ -588,6 +590,8 @@ class ParseTreeDumper { NODE(parser, OmpEndCriticalDirective) NODE(parser, OmpEndLoopDirective) NODE(parser, OmpEndSectionsDirective) + NODE(parser, OmpEnterClause) + NODE(OmpEnterClause, Modifier) NODE(parser, OmpFailClause) NODE(parser, OmpFromClause) NODE(OmpFromClause, Modifier) diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index 3a28f6f9731c3..a822cae393a3a 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -3769,6 +3769,16 @@ struct OmpAlwaysModifier { WRAPPER_CLASS_BOILERPLATE(OmpAlwaysModifier, Value); }; +// Ref: [6.0:289-290] +// +// automap-modifier -> +// automap // since 6.0 +// +struct OmpAutomapModifier { + ENUM_CLASS(Value, Automap); + WRAPPER_CLASS_BOILERPLATE(OmpAutomapModifier, Value); +}; + // Ref: [5.2:252-254] // // chunk-modifier -> @@ -4350,6 +4360,17 @@ struct OmpDeviceTypeClause { WRAPPER_CLASS_BOILERPLATE(OmpDeviceTypeClause, DeviceTypeDescription); }; +// Ref: [5.2:158-159], [6.0:289-290] +// +// enter-clause -> +// ENTER(locator-list) | +// ENTER(automap-modifier: locator-list) | // since 6.0 +struct OmpEnterClause { + TUPLE_CLASS_BOILERPLATE(OmpEnterClause); + MODIFIER_BOILERPLATE(OmpAutomapModifier); + std::tuple t; +}; + // OMP 5.2 15.8.3 extended-atomic, fail-clause -> // FAIL(memory-order) struct OmpFailClause { diff --git a/flang/include/flang/Semantics/openmp-modifiers.h b/flang/include/flang/Semantics/openmp-modifiers.h index a9fe911ef8807..e0eae984731c7 100644 --- a/flang/include/flang/Semantics/openmp-modifiers.h +++ b/flang/include/flang/Semantics/openmp-modifiers.h @@ -72,6 +72,7 @@ DECLARE_DESCRIPTOR(parser::OmpAlignModifier); DECLARE_DESCRIPTOR(parser::OmpAllocatorComplexModifier); DECLARE_DESCRIPTOR(parser::OmpAllocatorSimpleModifier); DECLARE_DESCRIPTOR(parser::OmpAlwaysModifier); +DECLARE_DESCRIPTOR(parser::OmpAutomapModifier); DECLARE_DESCRIPTOR(parser::OmpChunkModifier); DECLARE_DESCRIPTOR(parser::OmpCloseModifier); DECLARE_DESCRIPTOR(parser::OmpContextSelector); diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp index 594f95ecdda63..8eabf4f499604 100644 --- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp +++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp @@ -1519,10 +1519,14 @@ bool ClauseProcessor::processTo( bool ClauseProcessor::processEnter( llvm::SmallVectorImpl &result) const { return findRepeatableClause( - [&](const omp::clause::Enter &clause, const parser::CharBlock &) { + [&](const omp::clause::Enter &clause, const parser::CharBlock &source) { + mlir::Location currentLocation = converter.genLocation(source); + if (std::get>(clause.t)) + TODO(currentLocation, "Declare target enter AUTOMAP modifier"); // Case: declare target enter(func, var1, var2)... - gatherFuncAndVarSyms( - clause.v, mlir::omp::DeclareTargetCaptureClause::enter, result); + gatherFuncAndVarSyms(std::get(clause.t), + mlir::omp::DeclareTargetCaptureClause::enter, + result); }); } diff --git a/flang/lib/Lower/OpenMP/Clauses.cpp b/flang/lib/Lower/OpenMP/Clauses.cpp index 686fba0154f44..7f75aae09def1 100644 --- a/flang/lib/Lower/OpenMP/Clauses.cpp +++ b/flang/lib/Lower/OpenMP/Clauses.cpp @@ -772,8 +772,19 @@ Doacross make(const parser::OmpClause::Doacross &inp, Enter make(const parser::OmpClause::Enter &inp, semantics::SemanticsContext &semaCtx) { - // inp.v -> parser::OmpObjectList - return Enter{makeObjects(/*List=*/inp.v, semaCtx)}; + // inp.v -> parser::OmpEnterClause + CLAUSET_ENUM_CONVERT( // + convert, parser::OmpAutomapModifier::Value, Enter::Modifier, + // clang-format off + MS(Automap, Automap) + // clang-format on + ); + auto &mods = semantics::OmpGetModifiers(inp.v); + auto *mod = semantics::OmpGetUniqueModifier(mods); + auto &objList = std::get(inp.v.t); + + return Enter{{/*Modifier=*/maybeApplyToV(convert, mod), + /*List=*/makeObjects(objList, semaCtx)}}; } Exclusive make(const parser::OmpClause::Exclusive &inp, diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index 1c626148a03ae..bbe08bd82c5bd 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -449,6 +449,9 @@ TYPE_PARSER(construct(scalarIntExpr)) TYPE_PARSER(construct( // "ALWAYS" >> pure(OmpAlwaysModifier::Value::Always))) +TYPE_PARSER(construct( + "AUTOMAP" >> pure(OmpAutomapModifier::Value::Automap))) + TYPE_PARSER(construct( // "SIMD" >> pure(OmpChunkModifier::Value::Simd))) @@ -601,6 +604,9 @@ TYPE_PARSER(sourced(construct(sourced( TYPE_PARSER( sourced(construct(Parser{}))) +TYPE_PARSER( + sourced(construct(Parser{}))) + TYPE_PARSER(sourced(construct( sourced(construct(Parser{}) || construct(Parser{}) || @@ -735,6 +741,10 @@ TYPE_PARSER(construct( Parser{}) || construct(indirect(Parser{})))) +TYPE_PARSER(construct( + maybe(nonemptyList(Parser{}) / ":"), + Parser{})) + TYPE_PARSER(construct( "ACQ_REL" >> pure(common::OmpMemoryOrderType::Acq_Rel) || "ACQUIRE" >> pure(common::OmpMemoryOrderType::Acquire) || @@ -1023,7 +1033,7 @@ TYPE_PARSER( // "DYNAMIC_ALLOCATORS" >> construct(construct()) || "ENTER" >> construct(construct( - parenthesized(Parser{}))) || + parenthesized(Parser{}))) || "EXCLUSIVE" >> construct(construct( parenthesized(Parser{}))) || "FAIL" >> construct(construct( diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index fc15d46a8c727..3c14e154edc69 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2250,6 +2250,11 @@ class UnparseVisitor { Walk(std::get(x.t)); Walk(": ", std::get>>(x.t)); } + void Unparse(const OmpEnterClause &x) { + using Modifier = OmpEnterClause::Modifier; + Walk(std::get>>(x.t), ": "); + Walk(std::get(x.t)); + } void Unparse(const OmpFromClause &x) { using Modifier = OmpFromClause::Modifier; Walk(std::get>>(x.t), ": "); @@ -2986,6 +2991,7 @@ class UnparseVisitor { WALK_NESTED_ENUM(UseStmt, ModuleNature) // R1410 WALK_NESTED_ENUM(OmpAdjustArgsClause::OmpAdjustOp, Value) // OMP adjustop WALK_NESTED_ENUM(OmpAtClause, ActionTime) // OMP at + WALK_NESTED_ENUM(OmpAutomapModifier, Value) // OMP automap-modifier WALK_NESTED_ENUM(OmpBindClause, Binding) // OMP bind WALK_NESTED_ENUM(OmpProcBindClause, AffinityPolicy) // OMP proc_bind WALK_NESTED_ENUM(OmpDefaultClause, DataSharingAttribute) // OMP default diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index d214d222e7c90..693f4b18cd0fd 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -1568,9 +1568,10 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareTargetConstruct &x) { }, [&](const parser::OmpClause::Enter &enterClause) { enterClauseFound = true; - CheckSymbolNames(dir.source, enterClause.v); - CheckVarIsNotPartOfAnotherVar(dir.source, enterClause.v); - CheckThreadprivateOrDeclareTargetVar(enterClause.v); + auto &objList{std::get(enterClause.v.t)}; + CheckSymbolNames(dir.source, objList); + CheckVarIsNotPartOfAnotherVar(dir.source, objList); + CheckThreadprivateOrDeclareTargetVar(objList); }, [&](const parser::OmpClause::DeviceType &deviceTypeClause) { deviceTypeClauseFound = true; @@ -4028,7 +4029,11 @@ void OmpStructureChecker::Enter(const parser::OmpClause::HasDeviceAddr &x) { void OmpStructureChecker::Enter(const parser::OmpClause::Enter &x) { CheckAllowedClause(llvm::omp::Clause::OMPC_enter); - const parser::OmpObjectList &objList{x.v}; + if (!OmpVerifyModifiers( + x.v, llvm::omp::OMPC_enter, GetContext().clauseSource, context_)) { + return; + } + const parser::OmpObjectList &objList{std::get(x.v.t)}; SymbolSourceMap symbols; GetSymbolsInObjectList(objList, symbols); for (const auto &[symbol, source] : symbols) { @@ -4488,17 +4493,18 @@ const parser::OmpObjectList *OmpStructureChecker::GetOmpObjectList( const parser::OmpClause &clause) { // Clauses with OmpObjectList as its data member - using MemberObjectListClauses = std::tuple; + using MemberObjectListClauses = + std::tuple; // Clauses with OmpObjectList in the tuple - using TupleObjectListClauses = std::tuple; + using TupleObjectListClauses = + std::tuple; // TODO:: Generate the tuples using TableGen. // Handle other constructs with OmpObjectList such as OpenMPThreadprivate. diff --git a/flang/lib/Semantics/openmp-modifiers.cpp b/flang/lib/Semantics/openmp-modifiers.cpp index 336ce4beb24ba..af4000c4934ea 100644 --- a/flang/lib/Semantics/openmp-modifiers.cpp +++ b/flang/lib/Semantics/openmp-modifiers.cpp @@ -156,6 +156,22 @@ const OmpModifierDescriptor &OmpGetDescriptor() { return desc; } +template <> +const OmpModifierDescriptor &OmpGetDescriptor() { + static const OmpModifierDescriptor desc{ + /*name=*/"automap-modifier", + /*props=*/ + { + {60, {OmpProperty::Unique}}, + }, + /*clauses=*/ + { + {60, {Clause::OMPC_enter}}, + }, + }; + return desc; +} + template <> const OmpModifierDescriptor &OmpGetDescriptor() { static const OmpModifierDescriptor desc{ diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp index 4c3e509b5a36d..cbd232a884af8 100644 --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -2152,7 +2152,8 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPDeclareTargetConstruct &x) { ResolveOmpObjectList(linkClause->v, Symbol::Flag::OmpDeclareTarget); } else if (const auto *enterClause{ std::get_if(&clause.u)}) { - ResolveOmpObjectList(enterClause->v, Symbol::Flag::OmpDeclareTarget); + ResolveOmpObjectList(std::get(enterClause->v.t), + Symbol::Flag::OmpDeclareTarget); } } } diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index d08c669377cb2..2611470183e96 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -1646,7 +1646,8 @@ class OmpVisitor : public virtual DeclarationVisitor { populateDeclareTargetNames(linkClause->v); } else if (const auto *enterClause{ std::get_if(&clause.u)}) { - populateDeclareTargetNames(enterClause->v); + populateDeclareTargetNames( + std::get(enterClause->v.t)); } } } diff --git a/flang/test/Parser/OpenMP/enter-automap-modifier.f90 b/flang/test/Parser/OpenMP/enter-automap-modifier.f90 new file mode 100644 index 0000000000000..1f361ca5c2f06 --- /dev/null +++ b/flang/test/Parser/OpenMP/enter-automap-modifier.f90 @@ -0,0 +1,16 @@ +!RUN: %flang_fc1 -fdebug-unparse -fopenmp -fopenmp-version=60 %s | FileCheck %s --check-prefix=UNPARSE +!RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=60 %s | FileCheck %s --check-prefix=PARSE-TREE + +program automap + integer :: x + !$omp declare target enter(automap: x) +end program + +!UNPARSE: PROGRAM AUTOMAP +!UNPARSE: INTEGER x +!UNPARSE: !$OMP DECLARE TARGET ENTER(AUTOMAP: x) +!UNPARSE: END PROGRAM + +!PARSE-TREE: OmpClauseList -> OmpClause -> Enter -> OmpEnterClause +!PARSE-TREE-NEXT: | Modifier -> OmpAutomapModifier -> Value = Automap +!PARSE-TREE-NEXT: | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x' diff --git a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h index 7919f7a8b0c34..ce1cedc188fbf 100644 --- a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h +++ b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h @@ -578,8 +578,9 @@ struct DynamicAllocatorsT { template // struct EnterT { using List = ObjectListT; - using WrapperTrait = std::true_type; - List v; + ENUM(Modifier, Automap); + using TupleTrait = std::true_type; + std::tuple t; }; // V5.2: [5.6.2] `exclusive` clause diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td index 1b94657dfae1e..f11eccc215bc2 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMP.td +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td @@ -179,7 +179,7 @@ def OMPC_DynamicAllocators : Clause<[Spelling<"dynamic_allocators">]> { let clangClass = "OMPDynamicAllocatorsClause"; } def OMPC_Enter : Clause<[Spelling<"enter">]> { - let flangClass = "OmpObjectList"; + let flangClass = "OmpEnterClause"; } def OMPC_Exclusive : Clause<[Spelling<"exclusive">]> { let clangClass = "OMPExclusiveClause";