From aa17e9dcf1a5d85cef029b4e1e67dc7d0d8895e7 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Mon, 25 Nov 2024 13:11:50 -0600 Subject: [PATCH 1/7] [flang][OpenMP] Use new modifiers in ALLOCATE clause Again, this simplifies the semantic checks and lowering quite a bit. Update the check for positive alignment to use a more informative message, and to highlight the modifier itsef, not the whole clause. Remove the checks for the allocator expression itself being positive: there is nothing in the spec that says that it should be positive. Remove the "simple" modifier from the AllocateT template, since both simple and complex modifiers are the same thing, only differing in syntax. --- flang/include/flang/Parser/dump-parse-tree.h | 8 +-- flang/include/flang/Parser/parse-tree.h | 52 +++++++++++------ .../flang/Semantics/openmp-modifiers.h | 19 +++++++ flang/lib/Lower/OpenMP/ClauseProcessor.cpp | 6 +- flang/lib/Lower/OpenMP/Clauses.cpp | 56 +++++++------------ flang/lib/Lower/OpenMP/Clauses.h | 5 +- flang/lib/Parser/openmp-parsers.cpp | 45 +++++++-------- flang/lib/Parser/unparse.cpp | 32 +++-------- flang/lib/Semantics/check-omp-structure.cpp | 48 +++++++--------- flang/lib/Semantics/openmp-modifiers.cpp | 50 +++++++++++++++++ flang/lib/Semantics/resolve-directives.cpp | 13 ++--- .../test/Parser/OpenMP/allocators-unparse.f90 | 19 +++---- .../Semantics/OpenMP/allocate-clause01.f90 | 10 +--- flang/test/Semantics/OpenMP/allocators01.f90 | 2 +- flang/test/Semantics/OpenMP/allocators04.f90 | 2 +- flang/test/Semantics/OpenMP/allocators05.f90 | 2 +- flang/test/Semantics/OpenMP/allocators06.f90 | 2 +- flang/test/Semantics/OpenMP/resolve06.f90 | 2 +- llvm/include/llvm/Frontend/OpenMP/ClauseT.h | 6 +- 19 files changed, 205 insertions(+), 174 deletions(-) diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h index 68f9406dc2830..d499b414827d5 100644 --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -586,10 +586,10 @@ class ParseTreeDumper { NODE(parser, OmpReductionInitializerClause) NODE(parser, OmpReductionIdentifier) NODE(parser, OmpAllocateClause) - NODE(OmpAllocateClause, AllocateModifier) - NODE(OmpAllocateClause::AllocateModifier, Allocator) - NODE(OmpAllocateClause::AllocateModifier, ComplexModifier) - NODE(OmpAllocateClause::AllocateModifier, Align) + NODE(OmpAllocateClause, Modifier) + NODE(parser, OmpAlignModifier) + NODE(parser, OmpAllocatorComplexModifier) + NODE(parser, OmpAllocatorSimpleModifier) NODE(parser, OmpScheduleClause) NODE(OmpScheduleClause, Modifier) NODE_ENUM(OmpScheduleClause, Kind) diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index 8d7119a56b7f8..e9a02a8781245 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -3457,6 +3457,30 @@ inline namespace modifier { // ENUM_CLASS(Value, Keyword1, Keyword2); // }; +// Ref: [5.1:184-185], [5.2:178-179] +// +// align-modifier -> +// ALIGN(alignment) // since 5.1 +struct OmpAlignModifier { + WRAPPER_CLASS_BOILERPLATE(OmpAlignModifier, ScalarIntExpr); +}; + +// Ref: [5.0:158-159], [5.1:184-185], [5.2:178-179] +// +// allocator-simple-modifier -> +// allocator // since 5.0 +struct OmpAllocatorSimpleModifier { + WRAPPER_CLASS_BOILERPLATE(OmpAllocatorSimpleModifier, ScalarIntExpr); +}; + +// Ref: [5.1:184-185], [5.2:178-179] +// +// allocator-complex-modifier -> +// ALLOCATOR(allocator) // since 5.1 +struct OmpAllocatorComplexModifier { + WRAPPER_CLASS_BOILERPLATE(OmpAllocatorComplexModifier, ScalarIntExpr); +}; + // Ref: [5.2:252-254] // // chunk-modifier -> @@ -3646,24 +3670,20 @@ struct OmpAlignedClause { std::tuple> t; }; -// OMP 5.0 2.11.4 allocate-clause -> ALLOCATE ([allocator:] variable-name-list) -// OMP 5.2 2.13.4 allocate-clause -> ALLOCATE ([allocate-modifier [, -// allocate-modifier] :] -// variable-name-list) -// allocate-modifier -> allocator | align +// Ref: [5.0:158-159], [5.1:184-185], [5.2:178-179] +// +// allocate-clause -> +// ALLOCATE( +// [allocator-simple-modifier:] list) | // since 5.0 +// ALLOCATE([modifier...:] list) // since 5.1 +// modifier -> +// allocator-simple-modifier | +// allocator-complex-modifier | align-modifier // since 5.1 struct OmpAllocateClause { - struct AllocateModifier { - WRAPPER_CLASS(Allocator, ScalarIntExpr); - WRAPPER_CLASS(Align, ScalarIntExpr); - struct ComplexModifier { - TUPLE_CLASS_BOILERPLATE(ComplexModifier); - std::tuple t; - }; - UNION_CLASS_BOILERPLATE(AllocateModifier); - std::variant u; - }; + MODIFIER_BOILERPLATE(OmpAlignModifier, OmpAllocatorSimpleModifier, + OmpAllocatorComplexModifier); TUPLE_CLASS_BOILERPLATE(OmpAllocateClause); - std::tuple, OmpObjectList> t; + std::tuple t; }; // OMP 5.0 2.4 atomic-default-mem-order-clause -> diff --git a/flang/include/flang/Semantics/openmp-modifiers.h b/flang/include/flang/Semantics/openmp-modifiers.h index 60f116e6f0033..a6316cf7aba56 100644 --- a/flang/include/flang/Semantics/openmp-modifiers.h +++ b/flang/include/flang/Semantics/openmp-modifiers.h @@ -67,6 +67,9 @@ template const OmpModifierDescriptor &OmpGetDescriptor(); #define DECLARE_DESCRIPTOR(name) \ template <> const OmpModifierDescriptor &OmpGetDescriptor() +DECLARE_DESCRIPTOR(parser::OmpAlignModifier); +DECLARE_DESCRIPTOR(parser::OmpAllocatorComplexModifier); +DECLARE_DESCRIPTOR(parser::OmpAllocatorSimpleModifier); DECLARE_DESCRIPTOR(parser::OmpChunkModifier); DECLARE_DESCRIPTOR(parser::OmpDependenceType); DECLARE_DESCRIPTOR(parser::OmpExpectation); @@ -216,10 +219,26 @@ OmpGetRepeatableModifier(const std::optional> &modifiers) { OmpSpecificModifierIterator(items, items->end())); } +// Attempt to prevent creating a range based on an expiring modifier list. template llvm::iterator_range> OmpGetRepeatableModifier(std::optional> &&) = delete; +template +Fortran::parser::CharBlock OmpGetModifierSource( + const std::optional> &modifiers, + const SpecificTy *specific) { + if (!modifiers || !specific) { + return Fortran::parser::CharBlock{}; + } + for (auto &m : *modifiers) { + if (std::get_if(&m.u) == specific) { + return m.source; + } + } + llvm_unreachable("`specific` must be a member of `modifiers`"); +} + namespace detail { template constexpr const T *make_nullptr() { return static_cast(nullptr); diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp index 6baa22a44eafb..8670a5470cdc6 100644 --- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp +++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp @@ -81,12 +81,8 @@ genAllocateClause(lower::AbstractConverter &converter, // Check if allocate clause has allocator specified. If so, add it // to list of allocators, otherwise, add default allocator to // list of allocators. - using SimpleModifier = Allocate::AllocatorSimpleModifier; using ComplexModifier = Allocate::AllocatorComplexModifier; - if (auto &mod = std::get>(clause.t)) { - mlir::Value operand = fir::getBase(converter.genExprValue(*mod, stmtCtx)); - allocatorOperands.append(objects.size(), operand); - } else if (auto &mod = std::get>(clause.t)) { + if (auto &mod = std::get>(clause.t)) { mlir::Value operand = fir::getBase(converter.genExprValue(mod->v, stmtCtx)); allocatorOperands.append(objects.size(), operand); } else { diff --git a/flang/lib/Lower/OpenMP/Clauses.cpp b/flang/lib/Lower/OpenMP/Clauses.cpp index bf20f42bdecaf..ddc91ef2030bd 100644 --- a/flang/lib/Lower/OpenMP/Clauses.cpp +++ b/flang/lib/Lower/OpenMP/Clauses.cpp @@ -415,47 +415,29 @@ Aligned make(const parser::OmpClause::Aligned &inp, Allocate make(const parser::OmpClause::Allocate &inp, semantics::SemanticsContext &semaCtx) { // inp.v -> parser::OmpAllocateClause - using wrapped = parser::OmpAllocateClause; - auto &t0 = std::get>(inp.v.t); + auto &mods = semantics::OmpGetModifiers(inp.v); + auto *m0 = semantics::OmpGetUniqueModifier(mods); + auto *m1 = + semantics::OmpGetUniqueModifier( + mods); + auto *m2 = + semantics::OmpGetUniqueModifier(mods); auto &t1 = std::get(inp.v.t); - if (!t0) { - return Allocate{{/*AllocatorSimpleModifier=*/std::nullopt, - /*AllocatorComplexModifier=*/std::nullopt, - /*AlignModifier=*/std::nullopt, - /*List=*/makeObjects(t1, semaCtx)}}; - } + auto makeAllocator = [&](auto *mod) -> std::optional { + if (mod) + return Allocator{makeExpr(mod->v, semaCtx)}; + return std::nullopt; + }; - using Tuple = decltype(Allocate::t); + auto makeAlign = [&](const parser::ScalarIntExpr &expr) { + return Align{makeExpr(expr, semaCtx)}; + }; - return Allocate{Fortran::common::visit( - common::visitors{ - // simple-modifier - [&](const wrapped::AllocateModifier::Allocator &v) -> Tuple { - return {/*AllocatorSimpleModifier=*/makeExpr(v.v, semaCtx), - /*AllocatorComplexModifier=*/std::nullopt, - /*AlignModifier=*/std::nullopt, - /*List=*/makeObjects(t1, semaCtx)}; - }, - // complex-modifier + align-modifier - [&](const wrapped::AllocateModifier::ComplexModifier &v) -> Tuple { - auto &s0 = std::get(v.t); - auto &s1 = std::get(v.t); - return { - /*AllocatorSimpleModifier=*/std::nullopt, - /*AllocatorComplexModifier=*/Allocator{makeExpr(s0.v, semaCtx)}, - /*AlignModifier=*/Align{makeExpr(s1.v, semaCtx)}, - /*List=*/makeObjects(t1, semaCtx)}; - }, - // align-modifier - [&](const wrapped::AllocateModifier::Align &v) -> Tuple { - return {/*AllocatorSimpleModifier=*/std::nullopt, - /*AllocatorComplexModifier=*/std::nullopt, - /*AlignModifier=*/Align{makeExpr(v.v, semaCtx)}, - /*List=*/makeObjects(t1, semaCtx)}; - }, - }, - t0->u)}; + auto maybeAllocator = m1 ? makeAllocator(m1) : makeAllocator(m2); + return Allocate{{/*AllocatorComplexModifier=*/std::move(maybeAllocator), + /*AlignModifier=*/maybeApplyToV(makeAlign, m0), + /*List=*/makeObjects(t1, semaCtx)}}; } Allocator make(const parser::OmpClause::Allocator &inp, diff --git a/flang/lib/Lower/OpenMP/Clauses.h b/flang/lib/Lower/OpenMP/Clauses.h index 5fac5c2271c3b..562685e43c13b 100644 --- a/flang/lib/Lower/OpenMP/Clauses.h +++ b/flang/lib/Lower/OpenMP/Clauses.h @@ -153,10 +153,11 @@ std::optional maybeApply(FuncTy &&func, return func(*arg); } -template < +template < // typename FuncTy, // typename ArgTy, // - typename ResultTy = std::invoke_result_t> + typename ResultTy = + std::invoke_result_t().v)>> std::optional maybeApplyToV(FuncTy &&func, const ArgTy *arg) { if (!arg) return std::nullopt; diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index 2040a3e7ed5ae..f231290932c12 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -91,6 +91,14 @@ static TypeDeclarationStmt makeIterSpecDecl(std::list &&names) { // --- Parsers for clause modifiers ----------------------------------- +TYPE_PARSER(construct( // + "ALIGN" >> parenthesized(scalarIntExpr))) + +TYPE_PARSER(construct( + "ALLOCATOR" >> parenthesized(scalarIntExpr))) + +TYPE_PARSER(construct(scalarIntExpr)) + TYPE_PARSER(construct( // "SIMD" >> pure(OmpChunkModifier::Value::Simd))) @@ -183,6 +191,16 @@ TYPE_PARSER(construct( "SCALAR" >> pure(OmpVariableCategory::Value::Scalar))) // This could be auto-generated. +TYPE_PARSER(sourced(construct(sourced( + construct(Parser{}) || + construct( + Parser{}) || + construct( + Parser{}))))) + +TYPE_PARSER(sourced( + construct(Parser{}))) + TYPE_PARSER(sourced(construct( sourced(construct(Parser{}) || construct(Parser{}) || @@ -211,9 +229,6 @@ TYPE_PARSER(sourced(construct( construct(Parser{}) || construct(Parser{}))))) -TYPE_PARSER(sourced( - construct(Parser{}))) - // --- Parsers for clauses -------------------------------------------- /// `MOBClause` is a clause that has a @@ -334,29 +349,7 @@ TYPE_PARSER(construct( // variable-name-list) // allocate-modifier -> allocator | align TYPE_PARSER(construct( - maybe( - first( - construct("ALLOCATOR" >> - construct( - parenthesized(construct< - OmpAllocateClause::AllocateModifier::Allocator>( - scalarIntExpr)) / - ",", - "ALIGN" >> parenthesized(construct< - OmpAllocateClause::AllocateModifier::Align>( - scalarIntExpr)))), - construct("ALLOCATOR" >> - parenthesized( - construct( - scalarIntExpr))), - construct("ALIGN" >> - parenthesized( - construct( - scalarIntExpr))), - construct( - construct( - scalarIntExpr))) / - ":"), + maybe(nonemptyList(Parser{}) / ":"), Parser{})) // iteration-offset -> +/- non-negative-constant-expr diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index fe3f6ce7aa629..192917512c17a 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2148,35 +2148,21 @@ class UnparseVisitor { Walk(std::get(x.t)); } void Unparse(const OmpAllocateClause &x) { - Walk( - std::get>(x.t), ":"); + using Modifier = OmpAllocateClause::Modifier; + Walk(std::get>>(x.t), ": "); Walk(std::get(x.t)); } - void Unparse(const OmpAllocateClause::AllocateModifier &x) { - common::visit( - common::visitors{ - [&](const OmpAllocateClause::AllocateModifier::Allocator &y) { - Walk(y); - }, - [&](const OmpAllocateClause::AllocateModifier::ComplexModifier &y) { - Word("ALLOCATOR("); - Walk(std::get( - y.t)); - Put(")"); - Put(","); - Walk(std::get(y.t)); - }, - [&](const OmpAllocateClause::AllocateModifier::Align &y) { - Walk(y); - }, - }, - x.u); - } - void Unparse(const OmpAllocateClause::AllocateModifier::Align &x) { + void Unparse(const OmpAlignModifier &x) { Word("ALIGN("); Walk(x.v); Put(")"); } + void Unparse(const OmpAllocatorSimpleModifier &x) { Walk(x.v); } + void Unparse(const OmpAllocatorComplexModifier &x) { + Word("ALLOCATOR("); + Walk(x.v); + Put(")"); + } void Unparse(const OmpOrderClause &x) { using Modifier = OmpOrderClause::Modifier; Walk(std::get>>(x.t), ":"); diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index 3733ebfaf9492..b49258da506ce 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -1481,34 +1481,26 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Allocator &x) { void OmpStructureChecker::Enter(const parser::OmpClause::Allocate &x) { CheckAllowedClause(llvm::omp::Clause::OMPC_allocate); - if (const auto &modifier{ - std::get>( - x.v.t)}) { - common::visit( - common::visitors{ - [&](const parser::OmpAllocateClause::AllocateModifier::Allocator - &y) { - RequiresPositiveParameter(llvm::omp::Clause::OMPC_allocate, y.v); - isPredefinedAllocator = GetIntValue(y.v).has_value(); - }, - [&](const parser::OmpAllocateClause::AllocateModifier:: - ComplexModifier &y) { - const auto &alloc = std::get< - parser::OmpAllocateClause::AllocateModifier::Allocator>(y.t); - const auto &align = - std::get( - y.t); - RequiresPositiveParameter( - llvm::omp::Clause::OMPC_allocate, alloc.v); - RequiresPositiveParameter( - llvm::omp::Clause::OMPC_allocate, align.v); - isPredefinedAllocator = GetIntValue(alloc.v).has_value(); - }, - [&](const parser::OmpAllocateClause::AllocateModifier::Align &y) { - RequiresPositiveParameter(llvm::omp::Clause::OMPC_allocate, y.v); - }, - }, - modifier->u); + if (OmpVerifyModifiers( + x.v, llvm::omp::OMPC_allocate, GetContext().clauseSource, context_)) { + auto &modifiers{OmpGetModifiers(x.v)}; + if (auto *align{ + OmpGetUniqueModifier(modifiers)}) { + if (const auto &v{GetIntValue(align->v)}; !v || *v <= 0) { + context_.Say(OmpGetModifierSource(modifiers, align), + "The alignment value should be a constant positive integer"_err_en_US); + } + } + // The simple and complex modifiers have the same structure. They only + // differ in their syntax. + if (auto *alloc{OmpGetUniqueModifier( + modifiers)}) { + isPredefinedAllocator = GetIntValue(alloc->v).has_value(); + } + if (auto *alloc{OmpGetUniqueModifier( + modifiers)}) { + isPredefinedAllocator = GetIntValue(alloc->v).has_value(); + } } } diff --git a/flang/lib/Semantics/openmp-modifiers.cpp b/flang/lib/Semantics/openmp-modifiers.cpp index 1fd2358aa594e..18863b7b904a4 100644 --- a/flang/lib/Semantics/openmp-modifiers.cpp +++ b/flang/lib/Semantics/openmp-modifiers.cpp @@ -74,6 +74,56 @@ unsigned OmpModifierDescriptor::since(llvm::omp::Clause id) const { // Note: The intent for these functions is to have them be automatically- // generated in the future. +template <> +const OmpModifierDescriptor &OmpGetDescriptor() { + static const OmpModifierDescriptor desc{ + /*name=*/"align-modifier", + /*props=*/ + { + {51, {OmpProperty::Unique}}, + }, + /*clauses=*/ + { + {51, {Clause::OMPC_allocate}}, + }, + }; + return desc; +} + +template <> +const OmpModifierDescriptor & +OmpGetDescriptor() { + static const OmpModifierDescriptor desc{ + /*name=*/"allocator-complex-modifier", + /*props=*/ + { + {51, {OmpProperty::Unique}}, + }, + /*clauses=*/ + { + {51, {Clause::OMPC_allocate}}, + }, + }; + return desc; +} + +template <> +const OmpModifierDescriptor & +OmpGetDescriptor() { + static const OmpModifierDescriptor desc{ + /*name=*/"allocator-simple-modifier", + /*props=*/ + { + {50, {OmpProperty::Exclusive, OmpProperty::Unique}}, + }, + /*clauses=*/ + { + {50, {Clause::OMPC_allocate}}, + }, + }; + 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 0c3708b3fd29b..4f56356d879a4 100644 --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -2097,17 +2097,16 @@ void OmpAttributeVisitor::Post(const parser::OpenMPAllocatorsConstruct &x) { std::get(alloc->v.t), std::get>(x.t).statement); - const auto &allocMod{ - std::get>( - alloc->v.t)}; + auto &modifiers{OmpGetModifiers(alloc->v)}; + bool hasAllocator{ + OmpGetUniqueModifier(modifiers) || + OmpGetUniqueModifier(modifiers)}; + // TODO: As with allocate directive, exclude the case when a requires // directive with the dynamic_allocators clause is present in // the same compilation unit (OMP5.0 2.11.3). if (IsNestedInDirective(llvm::omp::Directive::OMPD_target) && - (!allocMod.has_value() || - std::holds_alternative< - parser::OmpAllocateClause::AllocateModifier::Align>( - allocMod->u))) { + !hasAllocator) { context_.Say(x.source, "ALLOCATORS directives that appear in a TARGET region " "must specify an allocator"_err_en_US); diff --git a/flang/test/Parser/OpenMP/allocators-unparse.f90 b/flang/test/Parser/OpenMP/allocators-unparse.f90 index 062a48b02635f..5cd0230471fc4 100644 --- a/flang/test/Parser/OpenMP/allocators-unparse.f90 +++ b/flang/test/Parser/OpenMP/allocators-unparse.f90 @@ -18,18 +18,18 @@ subroutine allocate() end subroutine allocate !CHECK: INTEGER, ALLOCATABLE :: arr1(:), arr2(:,:) -!CHECK-NEXT:!$OMP ALLOCATE ALLOCATE(omp_default_mem_alloc:arr1) +!CHECK-NEXT:!$OMP ALLOCATE ALLOCATE(omp_default_mem_alloc: arr1) !CHECK-NEXT: ALLOCATE(arr1(5)) -!CHECK-NEXT:!$OMP ALLOCATE ALLOCATE(ALLOCATOR(omp_default_mem_alloc),ALIGN(32):arr1) ALLOC& -!CHECK-NEXT:!$OMP&ATE(omp_default_mem_alloc:arr2) +!CHECK-NEXT:!$OMP ALLOCATE ALLOCATE(ALLOCATOR(omp_default_mem_alloc), ALIGN(32): arr1) ALL& +!CHECK-NEXT:!$OMP&OCATE(omp_default_mem_alloc: arr2) !CHECK-NEXT: ALLOCATE(arr1(10), arr2(3,2)) -!CHECK-NEXT:!$OMP ALLOCATE ALLOCATE(ALIGN(32):arr2) +!CHECK-NEXT:!$OMP ALLOCATE ALLOCATE(ALIGN(32): arr2) !CHECK-NEXT: ALLOCATE(arr2(5,3)) !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAllocatorsConstruct !PARSE-TREE-NEXT: Verbatim !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Allocate -> OmpAllocateClause -!PARSE-TREE-NEXT: AllocateModifier -> Allocator -> Scalar -> Integer -> Expr -> Designator -> DataRef -> Name = +!PARSE-TREE-NEXT: Modifier -> OmpAllocatorSimpleModifier -> Scalar -> Integer -> Expr -> Designator -> DataRef -> Name = 'omp_default_mem_alloc' !PARSE-TREE-NEXT: OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'arr1' !PARSE-TREE-NEXT: AllocateStmt !PARSE-TREE-NEXT: Allocation @@ -38,12 +38,11 @@ end subroutine allocate !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAllocatorsConstruct !PARSE-TREE-NEXT: Verbatim !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Allocate -> OmpAllocateClause -!PARSE-TREE-NEXT: AllocateModifier -> ComplexModifier -!PARSE-TREE-NEXT: Allocator -> Scalar -> Integer -> Expr -> Designator -> DataRef -> Name = -!PARSE-TREE-NEXT: Align -> Scalar -> Integer -> Expr -> LiteralConstant -> IntLiteralConstant = '32' +!PARSE-TREE-NEXT: Modifier -> OmpAllocatorComplexModifier -> Scalar -> Integer -> Expr -> Designator -> DataRef -> Name = 'omp_default_mem_alloc' +!PARSE-TREE-NEXT: Modifier -> OmpAlignModifier -> Scalar -> Integer -> Expr -> LiteralConstant -> IntLiteralConstant = '32' !PARSE-TREE-NEXT: OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'arr1' !PARSE-TREE-NEXT: OmpClause -> Allocate -> OmpAllocateClause -!PARSE-TREE-NEXT: AllocateModifier -> Allocator -> Scalar -> Integer -> Expr -> Designator -> DataRef -> Name = +!PARSE-TREE-NEXT: Modifier -> OmpAllocatorSimpleModifier -> Scalar -> Integer -> Expr -> Designator -> DataRef -> Name = 'omp_default_mem_alloc' !PARSE-TREE-NEXT: OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'arr2' !PARSE-TREE-NEXT: AllocateStmt !PARSE-TREE-NEXT: Allocation @@ -56,7 +55,7 @@ end subroutine allocate !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAllocatorsConstruct !PARSE-TREE-NEXT: Verbatim !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Allocate -> OmpAllocateClause -!PARSE-TREE-NEXT: AllocateModifier -> Align -> Scalar -> Integer -> Expr -> LiteralConstant -> IntLiteralConstant = '32' +!PARSE-TREE-NEXT: Modifier -> OmpAlignModifier -> Scalar -> Integer -> Expr -> LiteralConstant -> IntLiteralConstant = '32' !PARSE-TREE-NEXT: OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'arr2' !PARSE-TREE-NEXT: AllocateStmt !PARSE-TREE-NEXT: Allocation diff --git a/flang/test/Semantics/OpenMP/allocate-clause01.f90 b/flang/test/Semantics/OpenMP/allocate-clause01.f90 index 2b9a72e928eba..a014b548a8771 100644 --- a/flang/test/Semantics/OpenMP/allocate-clause01.f90 +++ b/flang/test/Semantics/OpenMP/allocate-clause01.f90 @@ -1,6 +1,6 @@ ! REQUIRES: openmp_runtime -! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags +! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=51 ! OpenMP Version 5.2 ! The allocate clause's allocator modifier must be of type allocator_handle ! and the align modifier must be constant, positive integer expression @@ -10,15 +10,11 @@ subroutine allocate() integer, allocatable :: a, b, c - !ERROR: The parameter of the ALLOCATE clause must be a positive integer expression - !$omp allocators allocate(-1: a) - allocate(a) - - !ERROR: The parameter of the ALLOCATE clause must be a positive integer expression + !ERROR: The alignment value should be a constant positive integer !$omp allocators allocate(allocator(-2), align(-3): b) allocate(b) - !ERROR: The parameter of the ALLOCATE clause must be a positive integer expression + !ERROR: The alignment value should be a constant positive integer !$omp allocators allocate(align(-4): c) allocate(c) end subroutine diff --git a/flang/test/Semantics/OpenMP/allocators01.f90 b/flang/test/Semantics/OpenMP/allocators01.f90 index c75c522ecae10..ff92fa3b23463 100644 --- a/flang/test/Semantics/OpenMP/allocators01.f90 +++ b/flang/test/Semantics/OpenMP/allocators01.f90 @@ -1,6 +1,6 @@ ! REQUIRES: openmp_runtime -! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags +! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=50 ! OpenMP Version 5.2 ! 6.7 allocators construct ! A list item that appears in an allocate clause must appear as diff --git a/flang/test/Semantics/OpenMP/allocators04.f90 b/flang/test/Semantics/OpenMP/allocators04.f90 index 1d2e96443a9da..212e48fbd1b26 100644 --- a/flang/test/Semantics/OpenMP/allocators04.f90 +++ b/flang/test/Semantics/OpenMP/allocators04.f90 @@ -1,6 +1,6 @@ ! REQUIRES: openmp_runtime -! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags +! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=50 ! OpenMP Version 5.2 ! Inherited from 2.11.3 allocate Directive ! If list items within the ALLOCATE directive have the SAVE attribute, are a common block name, or are declared in the scope of a diff --git a/flang/test/Semantics/OpenMP/allocators05.f90 b/flang/test/Semantics/OpenMP/allocators05.f90 index d0e11ca5874d7..0e8366a2461e6 100644 --- a/flang/test/Semantics/OpenMP/allocators05.f90 +++ b/flang/test/Semantics/OpenMP/allocators05.f90 @@ -1,6 +1,6 @@ ! REQUIRES: openmp_runtime -! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags +! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=50 ! OpenMP Version 5.2 ! Inherited from 2.11.3 allocate directive ! allocate directives that appear in a target region must specify an diff --git a/flang/test/Semantics/OpenMP/allocators06.f90 b/flang/test/Semantics/OpenMP/allocators06.f90 index a975204c11339..8e63512369e38 100644 --- a/flang/test/Semantics/OpenMP/allocators06.f90 +++ b/flang/test/Semantics/OpenMP/allocators06.f90 @@ -1,6 +1,6 @@ ! REQUIRES: openmp_runtime -! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags +! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=50 ! OpenMP Version 5.2 ! Inherited from 2.11.3 allocate directive ! The allocate directive must appear in the same scope as the declarations of diff --git a/flang/test/Semantics/OpenMP/resolve06.f90 b/flang/test/Semantics/OpenMP/resolve06.f90 index 358b1b1cc2826..cf544dfb73cad 100644 --- a/flang/test/Semantics/OpenMP/resolve06.f90 +++ b/flang/test/Semantics/OpenMP/resolve06.f90 @@ -1,6 +1,6 @@ ! REQUIRES: openmp_runtime -! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags +! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=50 use omp_lib !2.11.4 Allocate Clause !For any list item that is specified in the allocate diff --git a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h index ce09bb5f730a7..07efd6fd4e9da 100644 --- a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h +++ b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h @@ -384,15 +384,13 @@ struct AllocatorT; // V5.2: [6.6] `allocate` clause template // struct AllocateT { - using AllocatorSimpleModifier = E; + // AllocatorSimpleModifier is same as AllocatorComplexModifier. using AllocatorComplexModifier = AllocatorT; using AlignModifier = AlignT; using List = ObjectListT; using TupleTrait = std::true_type; - std::tuple - t; + std::tuple t; }; // V5.2: [6.4] `allocator` clause From af029c812c178c2854f0fd394ccc5654acae233c Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Mon, 25 Nov 2024 15:09:18 -0600 Subject: [PATCH 2/7] fix examples --- flang/examples/FeatureList/FeatureList.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/flang/examples/FeatureList/FeatureList.cpp b/flang/examples/FeatureList/FeatureList.cpp index 6ae92acf20608..f7086b9e82b8d 100644 --- a/flang/examples/FeatureList/FeatureList.cpp +++ b/flang/examples/FeatureList/FeatureList.cpp @@ -516,10 +516,10 @@ struct NodeVisitor { READ_FEATURE(OmpReductionInitializerClause) READ_FEATURE(OmpReductionIdentifier) READ_FEATURE(OmpAllocateClause) - READ_FEATURE(OmpAllocateClause::AllocateModifier) - READ_FEATURE(OmpAllocateClause::AllocateModifier::Allocator) - READ_FEATURE(OmpAllocateClause::AllocateModifier::ComplexModifier) - READ_FEATURE(OmpAllocateClause::AllocateModifier::Align) + READ_FEATURE(OmpAllocateClause::Modifier) + READ_FEATURE(OmpAllocatorSimpleModifier) + READ_FEATURE(OmpAllocatorComplexModifier) + READ_FEATURE(OmpAlignModifier) READ_FEATURE(OmpScheduleClause) READ_FEATURE(OmpScheduleClause::Kind) READ_FEATURE(OmpScheduleClause::Modifier) From 88ac6d0b50c26b69d0872e2b321be80e2584cb27 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Mon, 25 Nov 2024 17:15:09 -0600 Subject: [PATCH 3/7] fix llvm unittests --- .../Frontend/OpenMPDecompositionTest.cpp | 50 ++++++++----------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/llvm/unittests/Frontend/OpenMPDecompositionTest.cpp b/llvm/unittests/Frontend/OpenMPDecompositionTest.cpp index f9541131e4b23..8f195c4f60326 100644 --- a/llvm/unittests/Frontend/OpenMPDecompositionTest.cpp +++ b/llvm/unittests/Frontend/OpenMPDecompositionTest.cpp @@ -686,12 +686,12 @@ TEST_F(OpenMPDecompositionTest, Order1) { std::string Dir3 = stringify(Dec.output[3]); std::string Dir4 = stringify(Dec.output[4]); std::string Dir5 = stringify(Dec.output[5]); - ASSERT_EQ(Dir0, "target"); // (31) - ASSERT_EQ(Dir1, "teams"); // (31) + ASSERT_EQ(Dir0, "target"); // (31) + ASSERT_EQ(Dir1, "teams"); // (31) ASSERT_EQ(Dir2, "distribute order(1, 0)"); // (31) - ASSERT_EQ(Dir3, "parallel"); // (31) - ASSERT_EQ(Dir4, "for order(1, 0)"); // (31) - ASSERT_EQ(Dir5, "simd order(1, 0)"); // (31) + ASSERT_EQ(Dir3, "parallel"); // (31) + ASSERT_EQ(Dir4, "for order(1, 0)"); // (31) + ASSERT_EQ(Dir5, "simd order(1, 0)"); // (31) } // ALLOCATE @@ -708,8 +708,7 @@ TEST_F(OpenMPDecompositionTest, Allocate1) { // Allocate + firstprivate omp::List Clauses{ - {OMPC_allocate, - omp::clause::Allocate{{std::nullopt, std::nullopt, std::nullopt, {x}}}}, + {OMPC_allocate, omp::clause::Allocate{{std::nullopt, std::nullopt, {x}}}}, {OMPC_firstprivate, omp::clause::Firstprivate{{x}}}, }; @@ -719,8 +718,8 @@ TEST_F(OpenMPDecompositionTest, Allocate1) { std::string Dir0 = stringify(Dec.output[0]); std::string Dir1 = stringify(Dec.output[1]); - ASSERT_EQ(Dir0, "parallel shared(x)"); // (33) - ASSERT_EQ(Dir1, "sections firstprivate(x) allocate(, , , (x))"); // (33) + ASSERT_EQ(Dir0, "parallel shared(x)"); // (33) + ASSERT_EQ(Dir1, "sections firstprivate(x) allocate(, , (x))"); // (33) } TEST_F(OpenMPDecompositionTest, Allocate2) { @@ -729,8 +728,7 @@ TEST_F(OpenMPDecompositionTest, Allocate2) { // Allocate + in_reduction omp::List Clauses{ - {OMPC_allocate, - omp::clause::Allocate{{std::nullopt, std::nullopt, std::nullopt, {x}}}}, + {OMPC_allocate, omp::clause::Allocate{{std::nullopt, std::nullopt, {x}}}}, {OMPC_in_reduction, omp::clause::InReduction{{{Add}, {x}}}}, }; @@ -740,8 +738,8 @@ TEST_F(OpenMPDecompositionTest, Allocate2) { std::string Dir0 = stringify(Dec.output[0]); std::string Dir1 = stringify(Dec.output[1]); - ASSERT_EQ(Dir0, "target in_reduction((3), (x)) allocate(, , , (x))"); // (33) - ASSERT_EQ(Dir1, "parallel"); // (33) + ASSERT_EQ(Dir0, "target in_reduction((3), (x)) allocate(, , (x))"); // (33) + ASSERT_EQ(Dir1, "parallel"); // (33) } TEST_F(OpenMPDecompositionTest, Allocate3) { @@ -749,8 +747,7 @@ TEST_F(OpenMPDecompositionTest, Allocate3) { // Allocate + linear omp::List Clauses{ - {OMPC_allocate, - omp::clause::Allocate{{std::nullopt, std::nullopt, std::nullopt, {x}}}}, + {OMPC_allocate, omp::clause::Allocate{{std::nullopt, std::nullopt, {x}}}}, {OMPC_linear, omp::clause::Linear{{std::nullopt, std::nullopt, std::nullopt, {x}}}}, }; @@ -765,7 +762,7 @@ TEST_F(OpenMPDecompositionTest, Allocate3) { // should be fixed eventually. ASSERT_EQ(Dir0, "parallel shared(x) shared(x)"); // (33) ASSERT_EQ(Dir1, "for linear(, , , (x)) firstprivate(x) lastprivate(, (x)) " - "allocate(, , , (x))"); // (33) + "allocate(, , (x))"); // (33) } TEST_F(OpenMPDecompositionTest, Allocate4) { @@ -773,8 +770,7 @@ TEST_F(OpenMPDecompositionTest, Allocate4) { // Allocate + lastprivate omp::List Clauses{ - {OMPC_allocate, - omp::clause::Allocate{{std::nullopt, std::nullopt, std::nullopt, {x}}}}, + {OMPC_allocate, omp::clause::Allocate{{std::nullopt, std::nullopt, {x}}}}, {OMPC_lastprivate, omp::clause::Lastprivate{{std::nullopt, {x}}}}, }; @@ -784,8 +780,8 @@ TEST_F(OpenMPDecompositionTest, Allocate4) { std::string Dir0 = stringify(Dec.output[0]); std::string Dir1 = stringify(Dec.output[1]); - ASSERT_EQ(Dir0, "parallel shared(x)"); // (33) - ASSERT_EQ(Dir1, "sections lastprivate(, (x)) allocate(, , , (x))"); // (33) + ASSERT_EQ(Dir0, "parallel shared(x)"); // (33) + ASSERT_EQ(Dir1, "sections lastprivate(, (x)) allocate(, , (x))"); // (33) } TEST_F(OpenMPDecompositionTest, Allocate5) { @@ -793,8 +789,7 @@ TEST_F(OpenMPDecompositionTest, Allocate5) { // Allocate + private omp::List Clauses{ - {OMPC_allocate, - omp::clause::Allocate{{std::nullopt, std::nullopt, std::nullopt, {x}}}}, + {OMPC_allocate, omp::clause::Allocate{{std::nullopt, std::nullopt, {x}}}}, {OMPC_private, omp::clause::Private{{x}}}, }; @@ -804,8 +799,8 @@ TEST_F(OpenMPDecompositionTest, Allocate5) { std::string Dir0 = stringify(Dec.output[0]); std::string Dir1 = stringify(Dec.output[1]); - ASSERT_EQ(Dir0, "parallel"); // (33) - ASSERT_EQ(Dir1, "sections private(x) allocate(, , , (x))"); // (33) + ASSERT_EQ(Dir0, "parallel"); // (33) + ASSERT_EQ(Dir1, "sections private(x) allocate(, , (x))"); // (33) } TEST_F(OpenMPDecompositionTest, Allocate6) { @@ -814,8 +809,7 @@ TEST_F(OpenMPDecompositionTest, Allocate6) { // Allocate + reduction omp::List Clauses{ - {OMPC_allocate, - omp::clause::Allocate{{std::nullopt, std::nullopt, std::nullopt, {x}}}}, + {OMPC_allocate, omp::clause::Allocate{{std::nullopt, std::nullopt, {x}}}}, {OMPC_reduction, omp::clause::Reduction{{std::nullopt, {Add}, {x}}}}, }; @@ -825,8 +819,8 @@ TEST_F(OpenMPDecompositionTest, Allocate6) { std::string Dir0 = stringify(Dec.output[0]); std::string Dir1 = stringify(Dec.output[1]); - ASSERT_EQ(Dir0, "parallel shared(x)"); // (33) - ASSERT_EQ(Dir1, "sections reduction(, (3), (x)) allocate(, , , (x))"); // (33) + ASSERT_EQ(Dir0, "parallel shared(x)"); // (33) + ASSERT_EQ(Dir1, "sections reduction(, (3), (x)) allocate(, , (x))"); // (33) } // REDUCTION From ee00ecdc5a8b342c80ef34a8e1a1c8bb91855ab8 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Tue, 26 Nov 2024 09:01:49 -0600 Subject: [PATCH 4/7] [flang][OpenMP] Rename some `Type` members in OpenMP clauses The intent is to keep names in sync with the terminology from the OpenMP spec: OmpBindClause::Type -> Binding OmpDefaultClause::Type -> DataSharingAttribute OmpDeviceTypeClause::Type -> DeviceTypeDescription OmpProcBindClause::Type -> AffinityPolicy Add more comments with references to the OpenMP specs. --- flang/include/flang/Parser/dump-parse-tree.h | 8 +- flang/include/flang/Parser/parse-tree.h | 130 +++++++++++++----- flang/lib/Lower/OpenMP/Clauses.cpp | 9 +- flang/lib/Parser/openmp-parsers.cpp | 29 ++-- flang/lib/Parser/unparse.cpp | 9 +- flang/lib/Semantics/check-omp-structure.cpp | 4 +- flang/lib/Semantics/resolve-directives.cpp | 8 +- .../OpenMP/declare_target-device_type.f90 | 6 +- flang/test/Parser/OpenMP/proc-bind.f90 | 2 +- .../Parser/OpenMP/target-loop-unparse.f90 | 2 +- 10 files changed, 133 insertions(+), 74 deletions(-) diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h index d499b414827d5..e67b95ca61e8b 100644 --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -513,7 +513,7 @@ class ParseTreeDumper { NODE(parser, OmpDeclareTargetWithList) NODE(parser, OmpDeclareMapperSpecifier) NODE(parser, OmpDefaultClause) - NODE_ENUM(OmpDefaultClause, Type) + NODE_ENUM(OmpDefaultClause, DataSharingAttribute) NODE(parser, OmpVariableCategory) NODE_ENUM(OmpVariableCategory, Value) NODE(parser, OmpDefaultmapClause) @@ -573,9 +573,9 @@ class ParseTreeDumper { NODE(parser, OmpNumTasksClause) NODE_ENUM(OmpNumTasksClause, Prescriptiveness) NODE(parser, OmpBindClause) - NODE_ENUM(OmpBindClause, Type) + NODE_ENUM(OmpBindClause, Binding) NODE(parser, OmpProcBindClause) - NODE_ENUM(OmpProcBindClause, Type) + NODE_ENUM(OmpProcBindClause, AffinityPolicy) NODE(parser, OmpReductionModifier) NODE_ENUM(OmpReductionModifier, Value) NODE(parser, OmpReductionClause) @@ -596,7 +596,7 @@ class ParseTreeDumper { NODE(parser, OmpDeviceClause) NODE_ENUM(OmpDeviceClause, DeviceModifier) NODE(parser, OmpDeviceTypeClause) - NODE_ENUM(OmpDeviceTypeClause, Type) + NODE_ENUM(OmpDeviceTypeClause, DeviceTypeDescription) NODE(parser, OmpUpdateClause) NODE(parser, OmpChunkModifier) NODE_ENUM(OmpChunkModifier, Value) diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index e9a02a8781245..41b9ad1b7b0d6 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -3686,21 +3686,51 @@ struct OmpAllocateClause { std::tuple t; }; -// OMP 5.0 2.4 atomic-default-mem-order-clause -> -// ATOMIC_DEFAULT_MEM_ORDER (SEQ_CST | ACQ_REL | -// RELAXED) +// Ref: [5.0:60-63], [5.1:83-86], [5.2:210-213] +// +// atomic-default-mem-order-clause -> +// ATOMIC_DEFAULT_MEM_ORDER(memory-order) // since 5.0 +// memory-order -> +// SEQ_CST | ACQ_REL | RELAXED | // since 5.0 +// ACQUIRE | RELEASE // since 5.2 struct OmpAtomicDefaultMemOrderClause { - WRAPPER_CLASS_BOILERPLATE( - OmpAtomicDefaultMemOrderClause, common::OmpAtomicDefaultMemOrderType); + using MemoryOrder = common::OmpAtomicDefaultMemOrderType; + WRAPPER_CLASS_BOILERPLATE(OmpAtomicDefaultMemOrderClause, MemoryOrder); +}; + +// Ref: [5.0:128-131], [5.1:151-154], [5.2:258-259] +// +// bind-clause -> +// BIND(binding) // since 5.0 +// binding -> +// TEAMS | PARALLEL | THREAD // since 5.0 +struct OmpBindClause { + ENUM_CLASS(Binding, Parallel, Teams, Thread) + WRAPPER_CLASS_BOILERPLATE(OmpBindClause, Binding); }; -// 2.15.3.1 default-clause -> DEFAULT (PRIVATE | FIRSTPRIVATE | SHARED | NONE) +// Ref: [4.5:46-50], [5.0:74-78], [5.1:92-96], [5.2:109] +// +// default-clause -> +// DEFAULT(data-sharing-attribute) // since 4.5 +// data-sharing-attribute -> +// SHARED | NONE | // since 4.5 +// PRIVATE | FIRSTPRIVATE // since 5.0 struct OmpDefaultClause { - ENUM_CLASS(Type, Private, Firstprivate, Shared, None) - WRAPPER_CLASS_BOILERPLATE(OmpDefaultClause, Type); + ENUM_CLASS(DataSharingAttribute, Private, Firstprivate, Shared, None) + WRAPPER_CLASS_BOILERPLATE(OmpDefaultClause, DataSharingAttribute); }; -// 2.15.5.2 defaultmap -> DEFAULTMAP (implicit-behavior[:variable-category]) +// Ref: [4.5:103-107], [5.0:324-325], [5.1:357-358], [5.2:161-162] +// +// defaultmap-clause -> +// DEFAULTMAP(implicit-behavior +// [: variable-category]) // since 5.0 +// implicit-behavior -> +// TOFROM | // since 4.5 +// ALLOC | TO | FROM | FIRSTPRIVATE | NONE | +// DEFAULT | // since 5.0 +// PRESENT // since 5.1 struct OmpDefaultmapClause { TUPLE_CLASS_BOILERPLATE(OmpDefaultmapClause); ENUM_CLASS( @@ -3709,23 +3739,35 @@ struct OmpDefaultmapClause { std::tuple t; }; -// 2.13.9 iteration-offset -> +/- non-negative-constant +// Ref: [4.5:169-172], [5.0:255-259], [5.1:288-292], [5.2:91-93] +// +// iteration-offset -> +// +|- non-negative-constant // since 4.5 struct OmpIterationOffset { TUPLE_CLASS_BOILERPLATE(OmpIterationOffset); std::tuple t; }; -// 2.13.9 iteration -> induction-variable [iteration-offset] +// Ref: [4.5:169-172], [5.0:255-259], [5.1:288-292], [5.2:91-93] +// +// iteration -> +// induction-variable [iteration-offset] // since 4.5 struct OmpIteration { TUPLE_CLASS_BOILERPLATE(OmpIteration); std::tuple> t; }; +// Ref: [4.5:169-172], [5.0:255-259], [5.1:288-292], [5.2:91-93] +// +// iteration-vector -> +// [iteration...] // since 4.5 WRAPPER_CLASS(OmpIterationVector, std::list); // Extract this into a separate structure (instead of having it directly in // OmpDoacrossClause), so that the context in TYPE_CONTEXT_PARSER can be set // separately for OmpDependClause and OmpDoacrossClause. +// +// See: depend-clause, doacross-clause struct OmpDoacross { OmpDependenceType::Value GetDepType() const; @@ -3735,15 +3777,15 @@ struct OmpDoacross { std::variant u; }; -// Ref: [4.5:169-170], [5.0:255-256], [5.1:288-289], [5.2:323-324] +// Ref: [4.5:169-172], [5.0:255-259], [5.1:288-292], [5.2:323-326] // // depend-clause -> -// DEPEND(SOURCE) | // since 4.5, until 5.1 -// DEPEND(SINK: iteration-vector) | // since 4.5, until 5.1 +// DEPEND(SOURCE) | // since 4.5, until 5.1 +// DEPEND(SINK: iteration-vector) | // since 4.5, until 5.1 // DEPEND([depend-modifier,] -// task-dependence-type: locator-list) // since 4.5 +// task-dependence-type: locator-list) // since 4.5 // -// depend-modifier -> iterator-modifier // since 5.0 +// depend-modifier -> iterator-modifier // since 5.0 struct OmpDependClause { UNION_CLASS_BOILERPLATE(OmpDependClause); struct TaskDep { @@ -3755,6 +3797,10 @@ struct OmpDependClause { std::variant u; }; +// Ref: [5.2:326-328] +// +// doacross-clause -> +// DOACROSS(dependence-type: iteration-vector) // since 5.2 WRAPPER_CLASS(OmpDoacrossClause, OmpDoacross); // Ref: [5.0:254-255], [5.1:287-288], [5.2:73] @@ -3764,25 +3810,41 @@ WRAPPER_CLASS(OmpDoacrossClause, OmpDoacross); // DESTROY(variable) // since 5.2 WRAPPER_CLASS(OmpDestroyClause, OmpObject); -// device([ device-modifier :] scalar-integer-expression) +// Ref: [5.0:135-140], [5.1:161-166], [5.2:265-266] +// +// detach-clause -> +// DETACH(event-handle) // since 5.0 +struct OmpDetachClause { + WRAPPER_CLASS_BOILERPLATE(OmpDetachClause, OmpObject); +}; + +// Ref: [4.5:103-107], [5.0:170-176], [5.1:197-205], [5.2:276-277] +// +// device-clause -> +// DEVICE(scalar-integer-expression) | // since 4.5 +// DEVICE([device-modifier:] +// scalar-integer-expression) // since 5.0 struct OmpDeviceClause { TUPLE_CLASS_BOILERPLATE(OmpDeviceClause); ENUM_CLASS(DeviceModifier, Ancestor, Device_Num) std::tuple, ScalarIntExpr> t; }; -// device_type(any | host | nohost) +// Ref: [5.0:180-185], [5.1:210-216], [5.2:275] +// +// device-type-clause -> +// DEVICE_TYPE(ANY | HOST | NOHOST) // since 5.0 struct OmpDeviceTypeClause { - ENUM_CLASS(Type, Any, Host, Nohost) - WRAPPER_CLASS_BOILERPLATE(OmpDeviceTypeClause, Type); + ENUM_CLASS(DeviceTypeDescription, Any, Host, Nohost) + WRAPPER_CLASS_BOILERPLATE(OmpDeviceTypeClause, DeviceTypeDescription); }; // Ref: [4.5:107-109], [5.0:176-180], [5.1:205-210], [5.2:167-168] // // from-clause -> // FROM(locator-list) | -// FROM(mapper-modifier: locator-list) | // since 5.0 -// FROM(motion-modifier[,] ...: locator-list) // since 5.1 +// FROM(mapper-modifier: locator-list) | // since 5.0 +// FROM(motion-modifier[,] ...: locator-list) // since 5.1 // motion-modifier -> // PRESENT | mapper-modifier | iterator-modifier struct OmpFromClause { @@ -3806,11 +3868,6 @@ struct OmpIfClause { std::tuple, ScalarLogicalExpr> t; }; -// OpenMPv5.2 12.5.2 detach-clause -> DETACH (event-handle) -struct OmpDetachClause { - WRAPPER_CLASS_BOILERPLATE(OmpDetachClause, OmpObject); -}; - // OMP 5.0 2.19.5.6 in_reduction-clause -> IN_REDUCTION (reduction-identifier: // variable-name-list) struct OmpInReductionClause { @@ -3878,10 +3935,16 @@ struct OmpOrderClause { std::tuple t; }; -// 2.5 proc-bind-clause -> PROC_BIND (MASTER | CLOSE | SPREAD) +// Ref: [4.5:46-50], [5.0:74-78], [5.1:92-96], [5.2:229-230] +// +// proc-bind-clause -> +// PROC_BIND(affinity-policy) // since 4.5 +// affinity-policy -> +// CLOSE | PRIMARY | SPREAD | // since 4.5 +// MASTER // since 4.5, until 5.2 struct OmpProcBindClause { - ENUM_CLASS(Type, Close, Master, Spread, Primary) - WRAPPER_CLASS_BOILERPLATE(OmpProcBindClause, Type); + ENUM_CLASS(AffinityPolicy, Close, Master, Spread, Primary) + WRAPPER_CLASS_BOILERPLATE(OmpProcBindClause, AffinityPolicy); }; // Ref: [4.5:201-207], [5.0:300-302], [5.1:332-334], [5.2:134-137] @@ -3945,13 +4008,6 @@ struct OmpUpdateClause { std::variant u; }; -// OMP 5.2 11.7.1 bind-clause -> -// BIND( PARALLEL | TEAMS | THREAD ) -struct OmpBindClause { - ENUM_CLASS(Type, Parallel, Teams, Thread) - WRAPPER_CLASS_BOILERPLATE(OmpBindClause, Type); -}; - // OpenMP Clauses struct OmpClause { UNION_CLASS_BOILERPLATE(OmpClause); diff --git a/flang/lib/Lower/OpenMP/Clauses.cpp b/flang/lib/Lower/OpenMP/Clauses.cpp index ddc91ef2030bd..6d09cab700fd6 100644 --- a/flang/lib/Lower/OpenMP/Clauses.cpp +++ b/flang/lib/Lower/OpenMP/Clauses.cpp @@ -478,7 +478,7 @@ Bind make(const parser::OmpClause::Bind &inp, using wrapped = parser::OmpBindClause; CLAUSET_ENUM_CONVERT( // - convert, wrapped::Type, Bind::Binding, + convert, wrapped::Binding, Bind::Binding, // clang-format off MS(Teams, Teams) MS(Parallel, Parallel) @@ -523,7 +523,7 @@ Default make(const parser::OmpClause::Default &inp, using wrapped = parser::OmpDefaultClause; CLAUSET_ENUM_CONVERT( // - convert, wrapped::Type, Default::DataSharingAttribute, + convert, wrapped::DataSharingAttribute, Default::DataSharingAttribute, // clang-format off MS(Firstprivate, Firstprivate) MS(None, None) @@ -680,7 +680,8 @@ DeviceType make(const parser::OmpClause::DeviceType &inp, using wrapped = parser::OmpDeviceTypeClause; CLAUSET_ENUM_CONVERT( // - convert, wrapped::Type, DeviceType::DeviceTypeDescription, + convert, wrapped::DeviceTypeDescription, + DeviceType::DeviceTypeDescription, // clang-format off MS(Any, Any) MS(Host, Host) @@ -1142,7 +1143,7 @@ ProcBind make(const parser::OmpClause::ProcBind &inp, using wrapped = parser::OmpProcBindClause; CLAUSET_ENUM_CONVERT( // - convert, wrapped::Type, ProcBind::AffinityPolicy, + convert, wrapped::AffinityPolicy, ProcBind::AffinityPolicy, // clang-format off MS(Close, Close) MS(Master, Master) diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index f231290932c12..873f7e93cd15e 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -255,17 +255,18 @@ TYPE_PARSER(construct( // 2.15.3.1 DEFAULT (PRIVATE | FIRSTPRIVATE | SHARED | NONE) TYPE_PARSER(construct( - "PRIVATE" >> pure(OmpDefaultClause::Type::Private) || - "FIRSTPRIVATE" >> pure(OmpDefaultClause::Type::Firstprivate) || - "SHARED" >> pure(OmpDefaultClause::Type::Shared) || - "NONE" >> pure(OmpDefaultClause::Type::None))) + "PRIVATE" >> pure(OmpDefaultClause::DataSharingAttribute::Private) || + "FIRSTPRIVATE" >> + pure(OmpDefaultClause::DataSharingAttribute::Firstprivate) || + "SHARED" >> pure(OmpDefaultClause::DataSharingAttribute::Shared) || + "NONE" >> pure(OmpDefaultClause::DataSharingAttribute::None))) // 2.5 PROC_BIND (MASTER | CLOSE | PRIMARY | SPREAD) TYPE_PARSER(construct( - "CLOSE" >> pure(OmpProcBindClause::Type::Close) || - "MASTER" >> pure(OmpProcBindClause::Type::Master) || - "PRIMARY" >> pure(OmpProcBindClause::Type::Primary) || - "SPREAD" >> pure(OmpProcBindClause::Type::Spread))) + "CLOSE" >> pure(OmpProcBindClause::AffinityPolicy::Close) || + "MASTER" >> pure(OmpProcBindClause::AffinityPolicy::Master) || + "PRIMARY" >> pure(OmpProcBindClause::AffinityPolicy::Primary) || + "SPREAD" >> pure(OmpProcBindClause::AffinityPolicy::Spread))) TYPE_PARSER(construct( applyFunction(makeMobClause, @@ -311,9 +312,9 @@ TYPE_PARSER(construct( // device_type(any | host | nohost) TYPE_PARSER(construct( - "ANY" >> pure(OmpDeviceTypeClause::Type::Any) || - "HOST" >> pure(OmpDeviceTypeClause::Type::Host) || - "NOHOST" >> pure(OmpDeviceTypeClause::Type::Nohost))) + "ANY" >> pure(OmpDeviceTypeClause::DeviceTypeDescription::Any) || + "HOST" >> pure(OmpDeviceTypeClause::DeviceTypeDescription::Host) || + "NOHOST" >> pure(OmpDeviceTypeClause::DeviceTypeDescription::Nohost))) // 2.12 IF (directive-name-modifier: scalar-logical-expr) TYPE_PARSER(construct( @@ -432,9 +433,9 @@ TYPE_PARSER(construct( // OMP 5.2 11.7.1 BIND ( PARALLEL | TEAMS | THREAD ) TYPE_PARSER(construct( - "PARALLEL" >> pure(OmpBindClause::Type::Parallel) || - "TEAMS" >> pure(OmpBindClause::Type::Teams) || - "THREAD" >> pure(OmpBindClause::Type::Thread))) + "PARALLEL" >> pure(OmpBindClause::Binding::Parallel) || + "TEAMS" >> pure(OmpBindClause::Binding::Teams) || + "THREAD" >> pure(OmpBindClause::Binding::Thread))) TYPE_PARSER( "ACQUIRE" >> construct(construct()) || diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index 192917512c17a..58aaeb64d7ebc 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2820,9 +2820,9 @@ class UnparseVisitor { WALK_NESTED_ENUM(InquireSpec::LogVar, Kind) WALK_NESTED_ENUM(ProcedureStmt, Kind) // R1506 WALK_NESTED_ENUM(UseStmt, ModuleNature) // R1410 - WALK_NESTED_ENUM(OmpProcBindClause, Type) // OMP PROC_BIND - WALK_NESTED_ENUM(OmpDefaultClause, Type) // OMP DEFAULT - WALK_NESTED_ENUM(OmpDefaultmapClause, ImplicitBehavior) // OMP DEFAULTMAP + WALK_NESTED_ENUM(OmpProcBindClause, AffinityPolicy) // OMP proc_bind + WALK_NESTED_ENUM(OmpDefaultClause, DataSharingAttribute) // OMP default + WALK_NESTED_ENUM(OmpDefaultmapClause, ImplicitBehavior) // OMP defaultmap WALK_NESTED_ENUM(OmpVariableCategory, Value) // OMP variable-category WALK_NESTED_ENUM( OmpLastprivateClause, LastprivateModifier) // OMP lastprivate-modifier @@ -2832,7 +2832,8 @@ class UnparseVisitor { WALK_NESTED_ENUM(OmpTaskDependenceType, Value) // OMP task-dependence-type WALK_NESTED_ENUM(OmpScheduleClause, Kind) // OMP schedule-kind WALK_NESTED_ENUM(OmpDeviceClause, DeviceModifier) // OMP device modifier - WALK_NESTED_ENUM(OmpDeviceTypeClause, Type) // OMP DEVICE_TYPE + WALK_NESTED_ENUM( + OmpDeviceTypeClause, DeviceTypeDescription) // OMP device_type WALK_NESTED_ENUM(OmpReductionModifier, Value) // OMP reduction-modifier WALK_NESTED_ENUM(OmpExpectation, Value) // OMP motion-expectation WALK_NESTED_ENUM(OmpIfClause, DirectiveNameModifier) // OMP directive-modifier diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index b49258da506ce..013dcbaf0b0da 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -428,7 +428,7 @@ void OmpStructureChecker::HasInvalidLoopBinding( for (const auto &clause : clauseList.v) { if (const auto *bindClause{ std::get_if(&clause.u)}) { - if (bindClause->v.v != parser::OmpBindClause::Type::Teams) { + if (bindClause->v.v != parser::OmpBindClause::Binding::Teams) { context_.Say(beginDir.source, msg); } } @@ -1644,7 +1644,7 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareTargetConstruct &x) { [&](const parser::OmpClause::DeviceType &deviceTypeClause) { deviceTypeClauseFound = true; if (deviceTypeClause.v.v != - parser::OmpDeviceTypeClause::Type::Host) { + parser::OmpDeviceTypeClause::DeviceTypeDescription::Host) { // Function / subroutine explicitly marked as runnable by the // target device. deviceConstructFound_ = true; diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp index 4f56356d879a4..573f216b848ad 100644 --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -2023,16 +2023,16 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPAllocatorsConstruct &x) { void OmpAttributeVisitor::Post(const parser::OmpDefaultClause &x) { if (!dirContext_.empty()) { switch (x.v) { - case parser::OmpDefaultClause::Type::Private: + case parser::OmpDefaultClause::DataSharingAttribute::Private: SetContextDefaultDSA(Symbol::Flag::OmpPrivate); break; - case parser::OmpDefaultClause::Type::Firstprivate: + case parser::OmpDefaultClause::DataSharingAttribute::Firstprivate: SetContextDefaultDSA(Symbol::Flag::OmpFirstPrivate); break; - case parser::OmpDefaultClause::Type::Shared: + case parser::OmpDefaultClause::DataSharingAttribute::Shared: SetContextDefaultDSA(Symbol::Flag::OmpShared); break; - case parser::OmpDefaultClause::Type::None: + case parser::OmpDefaultClause::DataSharingAttribute::None: SetContextDefaultDSA(Symbol::Flag::OmpNone); break; } diff --git a/flang/test/Parser/OpenMP/declare_target-device_type.f90 b/flang/test/Parser/OpenMP/declare_target-device_type.f90 index 40eb1c2fa4cae..b6903614a628e 100644 --- a/flang/test/Parser/OpenMP/declare_target-device_type.f90 +++ b/flang/test/Parser/OpenMP/declare_target-device_type.f90 @@ -31,7 +31,7 @@ subroutine openmp_declare_target end do !PARSE-TREE: OpenMPDeclarativeConstruct -> OpenMPDeclareTargetConstruct -!PARSE-TREE: OmpDeclareTargetSpecifier -> OmpDeclareTargetWithClause -> OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> Type = Host -!PARSE-TREE: OmpDeclareTargetSpecifier -> OmpDeclareTargetWithClause -> OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> Type = Nohost -!PARSE-TREE: OmpDeclareTargetSpecifier -> OmpDeclareTargetWithClause -> OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> Type = Any +!PARSE-TREE: OmpDeclareTargetSpecifier -> OmpDeclareTargetWithClause -> OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> DeviceTypeDescription = Host +!PARSE-TREE: OmpDeclareTargetSpecifier -> OmpDeclareTargetWithClause -> OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> DeviceTypeDescription = Nohost +!PARSE-TREE: OmpDeclareTargetSpecifier -> OmpDeclareTargetWithClause -> OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> DeviceTypeDescription = Any END subroutine openmp_declare_target diff --git a/flang/test/Parser/OpenMP/proc-bind.f90 b/flang/test/Parser/OpenMP/proc-bind.f90 index 08bcf69e5e765..3115b3771f27d 100644 --- a/flang/test/Parser/OpenMP/proc-bind.f90 +++ b/flang/test/Parser/OpenMP/proc-bind.f90 @@ -6,7 +6,7 @@ ! PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPBlockConstruct ! PARSE-TREE: OmpBeginBlockDirective ! PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = parallel -! PARSE-TREE: OmpClauseList -> OmpClause -> ProcBind -> OmpProcBindClause -> Type = Primary +! PARSE-TREE: OmpClauseList -> OmpClause -> ProcBind -> OmpProcBindClause -> AffinityPolicy = Primary subroutine sb1 !$omp parallel proc_bind(primary) print *, "Hello" diff --git a/flang/test/Parser/OpenMP/target-loop-unparse.f90 b/flang/test/Parser/OpenMP/target-loop-unparse.f90 index b204707049652..ee0013f613403 100644 --- a/flang/test/Parser/OpenMP/target-loop-unparse.f90 +++ b/flang/test/Parser/OpenMP/target-loop-unparse.f90 @@ -19,7 +19,7 @@ subroutine test_loop !PARSE-TREE: OmpBeginLoopDirective !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = loop - !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Bind -> OmpBindClause -> Type = Thread + !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Bind -> OmpBindClause -> Binding = Thread !CHECK: !$omp loop !$omp loop bind(thread) do i=1,10 From 09b1270faf2dc5125c36c7f4cc246b3a922d5b08 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Mon, 25 Nov 2024 14:55:37 -0600 Subject: [PATCH 5/7] [flang][OpenMP] Use new modifiers with AFFINITY/ALIGNED/DEVICE This is a mostly mechanical change from specific modifiers embedded directly in a clause to the Modifier variant. Additional comments and references to the OpenMP specs were added. --- flang/include/flang/Parser/dump-parse-tree.h | 7 ++- flang/include/flang/Parser/parse-tree.h | 45 ++++++++++++++----- .../flang/Semantics/openmp-modifiers.h | 2 + flang/lib/Lower/OpenMP/Clauses.cpp | 20 +++++---- flang/lib/Parser/openmp-parsers.cpp | 27 ++++++++--- flang/lib/Parser/unparse.cpp | 12 ++--- flang/lib/Semantics/check-omp-structure.cpp | 41 ++++++++++------- flang/lib/Semantics/openmp-modifiers.cpp | 32 +++++++++++++ flang/test/Parser/OpenMP/affinity-clause.f90 | 4 +- .../Parser/OpenMP/target_device_parse.f90 | 16 +++---- .../Parser/OpenMP/target_device_unparse.f90 | 8 ++-- .../Semantics/OpenMP/clause-validity01.f90 | 4 +- 12 files changed, 155 insertions(+), 63 deletions(-) diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h index e67b95ca61e8b..3699aa34f4f8a 100644 --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -484,7 +484,10 @@ class ParseTreeDumper { NODE(parser, OmpIteratorSpecifier) NODE(parser, OmpIterator) NODE(parser, OmpAffinityClause) + NODE(OmpAffinityClause, Modifier) + NODE(parser, OmpAlignment) NODE(parser, OmpAlignedClause) + NODE(OmpAlignedClause, Modifier) NODE(parser, OmpAtomic) NODE(parser, OmpAtomicCapture) NODE(OmpAtomicCapture, Stmt1) @@ -594,7 +597,9 @@ class ParseTreeDumper { NODE(OmpScheduleClause, Modifier) NODE_ENUM(OmpScheduleClause, Kind) NODE(parser, OmpDeviceClause) - NODE_ENUM(OmpDeviceClause, DeviceModifier) + NODE(OmpDeviceClause, Modifier) + NODE(parser, OmpDeviceModifier) + NODE_ENUM(OmpDeviceModifier, Value) NODE(parser, OmpDeviceTypeClause) NODE_ENUM(OmpDeviceTypeClause, DeviceTypeDescription) NODE(parser, OmpUpdateClause) diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index 41b9ad1b7b0d6..2143e28045753 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -3457,6 +3457,14 @@ inline namespace modifier { // ENUM_CLASS(Value, Keyword1, Keyword2); // }; +// Ref: [4.5:72-81], [5.0:110-119], [5.1:134-143], [5.2:169-170] +// +// alignment -> +// scalar-integer-expression // since 4.5 +struct OmpAlignment { + WRAPPER_CLASS_BOILERPLATE(OmpAlignment, ScalarIntExpr); +}; + // Ref: [5.1:184-185], [5.2:178-179] // // align-modifier -> @@ -3526,6 +3534,15 @@ struct OmpDependenceType { WRAPPER_CLASS_BOILERPLATE(OmpDependenceType, Value); }; +// Ref: [5.0:170-176], [5.1:197-205], [5.2:276-277] +// +// device-modifier -> +// ANCESTOR | DEVICE_NUM // since 5.0 +struct OmpDeviceModifier { + ENUM_CLASS(Value, Ancestor, Device_Num) + WRAPPER_CLASS_BOILERPLATE(OmpDeviceModifier, Value); +}; + // Ref: [5.1:205-209], [5.2:166-168] // // motion-modifier -> @@ -3656,18 +3673,26 @@ struct OmpVariableCategory { // --- Clauses -// OMP 5.0 2.10.1 affinity([aff-modifier:] locator-list) -// aff-modifier: interator-modifier +// Ref: [5.0:135-140], [5.1:161-166], [5.2:264-265] +// +// affinity-clause -> +// AFFINITY([aff-modifier:] locator-list) // since 5.0 +// aff-modifier -> +// interator-modifier // since 5.0 struct OmpAffinityClause { TUPLE_CLASS_BOILERPLATE(OmpAffinityClause); - std::tuple, OmpObjectList> t; + MODIFIER_BOILERPLATE(OmpIterator); + std::tuple t; }; -// 2.8.1 aligned-clause -> ALIGNED (variable-name-list[ : scalar-constant]) +// Ref: [4.5:72-81], [5.0:110-119], [5.1:134-143], [5.2:169-170] +// +// aligned-clause -> +// ALIGNED(list [: alignment]) // since 4.5 struct OmpAlignedClause { TUPLE_CLASS_BOILERPLATE(OmpAlignedClause); - CharBlock source; - std::tuple> t; + MODIFIER_BOILERPLATE(OmpAlignment); + std::tuple t; }; // Ref: [5.0:158-159], [5.1:184-185], [5.2:178-179] @@ -3806,8 +3831,8 @@ WRAPPER_CLASS(OmpDoacrossClause, OmpDoacross); // Ref: [5.0:254-255], [5.1:287-288], [5.2:73] // // destroy-clause -> -// DESTROY | // since 5.0, until 5.2 -// DESTROY(variable) // since 5.2 +// DESTROY | // since 5.0, until 5.1 +// DESTROY(variable) // since 5.2 WRAPPER_CLASS(OmpDestroyClause, OmpObject); // Ref: [5.0:135-140], [5.1:161-166], [5.2:265-266] @@ -3826,8 +3851,8 @@ struct OmpDetachClause { // scalar-integer-expression) // since 5.0 struct OmpDeviceClause { TUPLE_CLASS_BOILERPLATE(OmpDeviceClause); - ENUM_CLASS(DeviceModifier, Ancestor, Device_Num) - std::tuple, ScalarIntExpr> t; + MODIFIER_BOILERPLATE(OmpDeviceModifier); + std::tuple t; }; // Ref: [5.0:180-185], [5.1:210-216], [5.2:275] diff --git a/flang/include/flang/Semantics/openmp-modifiers.h b/flang/include/flang/Semantics/openmp-modifiers.h index a6316cf7aba56..fab4b38090b04 100644 --- a/flang/include/flang/Semantics/openmp-modifiers.h +++ b/flang/include/flang/Semantics/openmp-modifiers.h @@ -67,11 +67,13 @@ template const OmpModifierDescriptor &OmpGetDescriptor(); #define DECLARE_DESCRIPTOR(name) \ template <> const OmpModifierDescriptor &OmpGetDescriptor() +DECLARE_DESCRIPTOR(parser::OmpAlignment); DECLARE_DESCRIPTOR(parser::OmpAlignModifier); DECLARE_DESCRIPTOR(parser::OmpAllocatorComplexModifier); DECLARE_DESCRIPTOR(parser::OmpAllocatorSimpleModifier); DECLARE_DESCRIPTOR(parser::OmpChunkModifier); DECLARE_DESCRIPTOR(parser::OmpDependenceType); +DECLARE_DESCRIPTOR(parser::OmpDeviceModifier); DECLARE_DESCRIPTOR(parser::OmpExpectation); DECLARE_DESCRIPTOR(parser::OmpIterator); DECLARE_DESCRIPTOR(parser::OmpLinearModifier); diff --git a/flang/lib/Lower/OpenMP/Clauses.cpp b/flang/lib/Lower/OpenMP/Clauses.cpp index 6d09cab700fd6..2792232253879 100644 --- a/flang/lib/Lower/OpenMP/Clauses.cpp +++ b/flang/lib/Lower/OpenMP/Clauses.cpp @@ -384,11 +384,12 @@ Absent make(const parser::OmpClause::Absent &inp, Affinity make(const parser::OmpClause::Affinity &inp, semantics::SemanticsContext &semaCtx) { // inp.v -> parser::OmpAffinityClause - auto &t0 = std::get>(inp.v.t); + auto &mods = semantics::OmpGetModifiers(inp.v); + auto *m0 = semantics::OmpGetUniqueModifier(mods); auto &t1 = std::get(inp.v.t); auto &&maybeIter = - maybeApply([&](auto &&s) { return makeIterator(s, semaCtx); }, t0); + m0 ? makeIterator(*m0, semaCtx) : std::optional{}; return Affinity{{/*Iterator=*/std::move(maybeIter), /*LocatorList=*/makeObjects(t1, semaCtx)}}; @@ -403,11 +404,12 @@ Align make(const parser::OmpClause::Align &inp, Aligned make(const parser::OmpClause::Aligned &inp, semantics::SemanticsContext &semaCtx) { // inp.v -> parser::OmpAlignedClause + auto &mods = semantics::OmpGetModifiers(inp.v); auto &t0 = std::get(inp.v.t); - auto &t1 = std::get>(inp.v.t); + auto *m1 = semantics::OmpGetUniqueModifier(mods); return Aligned{{ - /*Alignment=*/maybeApply(makeExprFn(semaCtx), t1), + /*Alignment=*/maybeApplyToV(makeExprFn(semaCtx), m1), /*List=*/makeObjects(t0, semaCtx), }}; } @@ -659,18 +661,18 @@ Detach make(const parser::OmpClause::Detach &inp, Device make(const parser::OmpClause::Device &inp, semantics::SemanticsContext &semaCtx) { // inp.v -> parser::OmpDeviceClause - using wrapped = parser::OmpDeviceClause; - CLAUSET_ENUM_CONVERT( // - convert, parser::OmpDeviceClause::DeviceModifier, Device::DeviceModifier, + convert, parser::OmpDeviceModifier::Value, Device::DeviceModifier, // clang-format off MS(Ancestor, Ancestor) MS(Device_Num, DeviceNum) // clang-format on ); - auto &t0 = std::get>(inp.v.t); + + auto &mods = semantics::OmpGetModifiers(inp.v); + auto *m0 = semantics::OmpGetUniqueModifier(mods); auto &t1 = std::get(inp.v.t); - return Device{{/*DeviceModifier=*/maybeApply(convert, t0), + return Device{{/*DeviceModifier=*/maybeApplyToV(convert, m0), /*DeviceDescription=*/makeExpr(t1, semaCtx)}}; } diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index 873f7e93cd15e..5b61d053ad162 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -91,6 +91,8 @@ static TypeDeclarationStmt makeIterSpecDecl(std::list &&names) { // --- Parsers for clause modifiers ----------------------------------- +TYPE_PARSER(construct(scalarIntExpr)) + TYPE_PARSER(construct( // "ALIGN" >> parenthesized(scalarIntExpr))) @@ -106,6 +108,10 @@ TYPE_PARSER(construct( "SINK" >> pure(OmpDependenceType::Value::Sink) || "SOURCE" >> pure(OmpDependenceType::Value::Source))) +TYPE_PARSER(construct( + "ANCESTOR" >> pure(OmpDeviceModifier::Value::Ancestor) || + "DEVICE_NUM" >> pure(OmpDeviceModifier::Value::Device_Num))) + TYPE_PARSER(construct( // "PRESENT" >> pure(OmpExpectation::Value::Present))) @@ -191,6 +197,12 @@ TYPE_PARSER(construct( "SCALAR" >> pure(OmpVariableCategory::Value::Scalar))) // This could be auto-generated. +TYPE_PARSER( + sourced(construct(Parser{}))) + +TYPE_PARSER( + sourced(construct(Parser{}))) + TYPE_PARSER(sourced(construct(sourced( construct(Parser{}) || construct( @@ -201,6 +213,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{}) || @@ -251,7 +266,8 @@ static inline MOBClause makeMobClause( // [5.0] 2.10.1 affinity([aff-modifier:] locator-list) // aff-modifier: interator-modifier TYPE_PARSER(construct( - maybe(Parser{} / ":"), Parser{})) + maybe(nonemptyList(Parser{}) / ":"), + Parser{})) // 2.15.3.1 DEFAULT (PRIVATE | FIRSTPRIVATE | SHARED | NONE) TYPE_PARSER(construct( @@ -304,10 +320,7 @@ TYPE_PARSER(construct( // device([ device-modifier :] scalar-integer-expression) TYPE_PARSER(construct( - maybe( - ("ANCESTOR" >> pure(OmpDeviceClause::DeviceModifier::Ancestor) || - "DEVICE_NUM" >> pure(OmpDeviceClause::DeviceModifier::Device_Num)) / - ":"), + maybe(nonemptyList(Parser{}) / ":"), scalarIntExpr)) // device_type(any | host | nohost) @@ -401,8 +414,8 @@ TYPE_CONTEXT_PARSER("Omp LINEAR clause"_en_US, TYPE_PARSER(construct(Parser{})) // 2.8.1 ALIGNED (list: alignment) -TYPE_PARSER(construct( - Parser{}, maybe(":" >> scalarIntConstantExpr))) +TYPE_PARSER(construct(Parser{}, + maybe(":" >> nonemptyList(Parser{})))) TYPE_PARSER(construct( construct(Parser{}) || diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index 58aaeb64d7ebc..80ebd692bd119 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2107,17 +2107,19 @@ class UnparseVisitor { Walk(",", std::get>(x.t)); } void Unparse(const OmpDeviceClause &x) { - Walk(std::get>(x.t), ":"); + using Modifier = OmpDeviceClause::Modifier; + Walk(std::get>>(x.t), ": "); Walk(std::get(x.t)); } void Unparse(const OmpAffinityClause &x) { - Walk(std::get>(x.t), ":"); + using Modifier = OmpAffinityClause::Modifier; + Walk(std::get>>(x.t), ": "); Walk(std::get(x.t)); } void Unparse(const OmpAlignedClause &x) { + using Modifier = OmpAlignedClause::Modifier; Walk(std::get(x.t)); - Put(","); - Walk(std::get>(x.t)); + Walk(": ", std::get>>(x.t)); } void Unparse(const OmpFromClause &x) { using Modifier = OmpFromClause::Modifier; @@ -2831,7 +2833,7 @@ class UnparseVisitor { WALK_NESTED_ENUM(OmpOrderingModifier, Value) // OMP ordering-modifier WALK_NESTED_ENUM(OmpTaskDependenceType, Value) // OMP task-dependence-type WALK_NESTED_ENUM(OmpScheduleClause, Kind) // OMP schedule-kind - WALK_NESTED_ENUM(OmpDeviceClause, DeviceModifier) // OMP device modifier + WALK_NESTED_ENUM(OmpDeviceModifier, Value) // OMP device modifier WALK_NESTED_ENUM( OmpDeviceTypeClause, DeviceTypeDescription) // OMP device_type WALK_NESTED_ENUM(OmpReductionModifier, Value) // OMP reduction-modifier diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index 013dcbaf0b0da..ebcafb6a0e354 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -3372,10 +3372,15 @@ void OmpStructureChecker::Leave(const parser::OmpAtomic &) { // generalized restrictions. void OmpStructureChecker::Enter(const parser::OmpClause::Aligned &x) { CheckAllowedClause(llvm::omp::Clause::OMPC_aligned); - - if (const auto &expr{ - std::get>(x.v.t)}) { - RequiresConstantPositiveParameter(llvm::omp::Clause::OMPC_aligned, *expr); + if (OmpVerifyModifiers( + x.v, llvm::omp::OMPC_aligned, GetContext().clauseSource, context_)) { + auto &modifiers{OmpGetModifiers(x.v)}; + if (auto *align{OmpGetUniqueModifier(modifiers)}) { + if (const auto &v{GetIntValue(align->v)}; !v || *v <= 0) { + context_.Say(OmpGetModifierSource(modifiers, align), + "The alignment value should be a constant positive integer"_err_en_US); + } + } } // 2.8.1 TODO: list-item attribute check } @@ -3597,19 +3602,25 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Schedule &x) { void OmpStructureChecker::Enter(const parser::OmpClause::Device &x) { CheckAllowedClause(llvm::omp::Clause::OMPC_device); - const parser::OmpDeviceClause &deviceClause = x.v; - const auto &device{std::get<1>(deviceClause.t)}; + const parser::OmpDeviceClause &deviceClause{x.v}; + const auto &device{std::get(deviceClause.t)}; RequiresPositiveParameter( llvm::omp::Clause::OMPC_device, device, "device expression"); - std::optional modifier = - std::get<0>(deviceClause.t); - if (modifier && - *modifier == parser::OmpDeviceClause::DeviceModifier::Ancestor) { - if (GetContext().directive != llvm::omp::OMPD_target) { - context_.Say(GetContext().clauseSource, - "The ANCESTOR device-modifier must not appear on the DEVICE clause on" - " any directive other than the TARGET construct. Found on %s construct."_err_en_US, - parser::ToUpperCaseLetters(getDirectiveName(GetContext().directive))); + llvm::omp::Directive dir{GetContext().directive}; + + if (OmpVerifyModifiers(deviceClause, llvm::omp::OMPC_device, + GetContext().clauseSource, context_)) { + auto &modifiers{OmpGetModifiers(deviceClause)}; + + if (auto *deviceMod{ + OmpGetUniqueModifier(modifiers)}) { + using Value = parser::OmpDeviceModifier::Value; + if (dir != llvm::omp::OMPD_target && deviceMod->v == Value::Ancestor) { + auto name{OmpGetDescriptor().name}; + context_.Say(OmpGetModifierSource(modifiers, deviceMod), + "The ANCESTOR %s must not appear on the DEVICE clause on any directive other than the TARGET construct. Found on %s construct."_err_en_US, + name.str(), parser::ToUpperCaseLetters(getDirectiveName(dir))); + } } } } diff --git a/flang/lib/Semantics/openmp-modifiers.cpp b/flang/lib/Semantics/openmp-modifiers.cpp index 18863b7b904a4..97227bfef0ea5 100644 --- a/flang/lib/Semantics/openmp-modifiers.cpp +++ b/flang/lib/Semantics/openmp-modifiers.cpp @@ -74,6 +74,22 @@ unsigned OmpModifierDescriptor::since(llvm::omp::Clause id) const { // Note: The intent for these functions is to have them be automatically- // generated in the future. +template <> +const OmpModifierDescriptor &OmpGetDescriptor() { + static const OmpModifierDescriptor desc{ + /*name=*/"alignment", + /*props=*/ + { + {45, {OmpProperty::Unique, OmpProperty::Ultimate, OmpProperty::Post}}, + }, + /*clauses=*/ + { + {45, {Clause::OMPC_aligned}}, + }, + }; + return desc; +} + template <> const OmpModifierDescriptor &OmpGetDescriptor() { static const OmpModifierDescriptor desc{ @@ -158,6 +174,22 @@ const OmpModifierDescriptor &OmpGetDescriptor() { return desc; } +template <> +const OmpModifierDescriptor &OmpGetDescriptor() { + static const OmpModifierDescriptor desc{ + /*name=*/"device-modifier", + /*props=*/ + { + {45, {OmpProperty::Unique}}, + }, + /*clauses=*/ + { + {45, {Clause::OMPC_device}}, + }, + }; + return desc; +} + template <> const OmpModifierDescriptor &OmpGetDescriptor() { static const OmpModifierDescriptor desc{ diff --git a/flang/test/Parser/OpenMP/affinity-clause.f90 b/flang/test/Parser/OpenMP/affinity-clause.f90 index 5e9e0a2194bab..642af6aeb7e49 100644 --- a/flang/test/Parser/OpenMP/affinity-clause.f90 +++ b/flang/test/Parser/OpenMP/affinity-clause.f90 @@ -55,7 +55,7 @@ subroutine f02(x) !UNPARSE: SUBROUTINE f02 (x) !UNPARSE: INTEGER x(10_4) -!UNPARSE: !$OMP TASK AFFINITY(ITERATOR(INTEGER i = 1_4:3_4):x(i)) +!UNPARSE: !$OMP TASK AFFINITY(ITERATOR(INTEGER i = 1_4:3_4): x(i)) !UNPARSE: x=x+1_4 !UNPARSE: !$OMP END TASK !UNPARSE: END SUBROUTINE @@ -63,7 +63,7 @@ subroutine f02(x) !PARSE-TREE: OmpBeginBlockDirective !PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = task !PARSE-TREE: | OmpClauseList -> OmpClause -> Affinity -> OmpAffinityClause -!PARSE-TREE: | | OmpIterator -> OmpIteratorSpecifier +!PARSE-TREE: | | Modifier -> OmpIterator -> OmpIteratorSpecifier !PARSE-TREE: | | | TypeDeclarationStmt !PARSE-TREE: | | | | DeclarationTypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec -> !PARSE-TREE: | | | | EntityDecl diff --git a/flang/test/Parser/OpenMP/target_device_parse.f90 b/flang/test/Parser/OpenMP/target_device_parse.f90 index 30464c5b08ab8..7f5bee3793b2e 100644 --- a/flang/test/Parser/OpenMP/target_device_parse.f90 +++ b/flang/test/Parser/OpenMP/target_device_parse.f90 @@ -96,7 +96,7 @@ PROGRAM main !------------------------------------------------------ ! Check Device Ancestor clause with a constant argument !------------------------------------------------------ -!CHECK: !$OMP TARGET DEVICE(ANCESTOR:1) +!CHECK: !$OMP TARGET DEVICE(ANCESTOR: 1) !$OMP TARGET DEVICE(ANCESTOR: 1) M = M + 1 !CHECK: !$OMP END TARGET @@ -105,7 +105,7 @@ PROGRAM main !PARSE-TREE: OmpBeginBlockDirective !PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target !PARSE-TREE: OmpClauseList -> OmpClause -> Device -> OmpDeviceClause -!PARSE-TREE: DeviceModifier = Ancestor +!PARSE-TREE: OmpDeviceModifier -> Value = Ancestor !PARSE-TREE: Scalar -> Integer -> Expr = '1_4' !PARSE-TREE: LiteralConstant -> IntLiteralConstant = '1' !PARSE-TREE: OmpEndBlockDirective @@ -116,7 +116,7 @@ PROGRAM main !-------------------------------------------------------- ! Check Device Devive-Num clause with a constant argument !-------------------------------------------------------- -!CHECK: !$OMP TARGET DEVICE(DEVICE_NUM:2) +!CHECK: !$OMP TARGET DEVICE(DEVICE_NUM: 2) !$OMP TARGET DEVICE(DEVICE_NUM: 2) M = M + 1 !CHECK: !$OMP END TARGET @@ -125,7 +125,7 @@ PROGRAM main !PARSE-TREE: OmpBeginBlockDirective !PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target !PARSE-TREE: OmpClauseList -> OmpClause -> Device -> OmpDeviceClause -!PARSE-TREE: DeviceModifier = Device_Num +!PARSE-TREE: OmpDeviceModifier -> Value = Device_Num !PARSE-TREE: Scalar -> Integer -> Expr = '2_4' !PARSE-TREE: LiteralConstant -> IntLiteralConstant = '2' !PARSE-TREE: OmpEndBlockDirective @@ -136,7 +136,7 @@ PROGRAM main !------------------------------------------------------------------- ! Check Device Ancestor clause with a variable expression argument !------------------------------------------------------------------- -!CHECK: !$OMP TARGET DEVICE(ANCESTOR:X+Y) +!CHECK: !$OMP TARGET DEVICE(ANCESTOR: X+Y) !$OMP TARGET DEVICE(ANCESTOR: X + Y) M = M + 1 !CHECK: !$OMP END TARGET @@ -145,7 +145,7 @@ PROGRAM main !PARSE-TREE: OmpBeginBlockDirective !PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target !PARSE-TREE: OmpClauseList -> OmpClause -> Device -> OmpDeviceClause -!PARSE-TREE: DeviceModifier = Ancestor +!PARSE-TREE: OmpDeviceModifier -> Value = Ancestor !PARSE-TREE: Scalar -> Integer -> Expr = 'x+y' !PARSE-TREE: Add !PARSE-TREE: Expr = 'x' @@ -160,7 +160,7 @@ PROGRAM main !------------------------------------------------------------------- ! Check Device Devive-Num clause with a variable expression argument !------------------------------------------------------------------- -!CHECK: !$OMP TARGET DEVICE(DEVICE_NUM:X-Y) +!CHECK: !$OMP TARGET DEVICE(DEVICE_NUM: X-Y) !$OMP TARGET DEVICE(DEVICE_NUM: X - Y) M = M + 1 !CHECK: !$OMP END TARGET @@ -169,7 +169,7 @@ PROGRAM main !PARSE-TREE: OmpBeginBlockDirective !PARSE-TREE: OmpBlockDirective -> llvm::omp::Directive = target !PARSE-TREE: OmpClauseList -> OmpClause -> Device -> OmpDeviceClause -!PARSE-TREE: DeviceModifier = Device_Num +!PARSE-TREE: OmpDeviceModifier -> Value = Device_Num !PARSE-TREE: Scalar -> Integer -> Expr = 'x-y' !PARSE-TREE: Subtract !PARSE-TREE: Expr = 'x' diff --git a/flang/test/Parser/OpenMP/target_device_unparse.f90 b/flang/test/Parser/OpenMP/target_device_unparse.f90 index 605c2baf1b06b..403b64887e747 100644 --- a/flang/test/Parser/OpenMP/target_device_unparse.f90 +++ b/flang/test/Parser/OpenMP/target_device_unparse.f90 @@ -45,7 +45,7 @@ PROGRAM main !-------------------------------------------- ! Ancestor followed by constant argument !-------------------------------------------- -!CHECK: !$OMP TARGET DEVICE(ANCESTOR:0) +!CHECK: !$OMP TARGET DEVICE(ANCESTOR: 0) !CHECK: !$OMP END TARGET !$OMP TARGET DEVICE(ANCESTOR: 0) M = M + 1 @@ -54,7 +54,7 @@ PROGRAM main !-------------------------------------------- ! Device_Num followed by constant argument !-------------------------------------------- -!CHECK: !$OMP TARGET DEVICE(DEVICE_NUM:1) +!CHECK: !$OMP TARGET DEVICE(DEVICE_NUM: 1) !CHECK: !$OMP END TARGET !$OMP TARGET DEVICE(DEVICE_NUM: 1) M = M + 1 @@ -63,7 +63,7 @@ PROGRAM main !-------------------------------------------- ! Ancestor followed by variable expression argument !-------------------------------------------- -!CHECK: !$OMP TARGET DEVICE(ANCESTOR:X+Y) +!CHECK: !$OMP TARGET DEVICE(ANCESTOR: X+Y) !CHECK: !$OMP END TARGET !$OMP TARGET DEVICE(ANCESTOR: X + Y) M = M + 1 @@ -72,7 +72,7 @@ PROGRAM main !-------------------------------------------- ! Device_Num followed by variable expression argument !-------------------------------------------- -!CHECK: !$OMP TARGET DEVICE(DEVICE_NUM:X-Y) +!CHECK: !$OMP TARGET DEVICE(DEVICE_NUM: X-Y) !CHECK: !$OMP END TARGET !$OMP TARGET DEVICE(DEVICE_NUM: X - Y) M = M + 1 diff --git a/flang/test/Semantics/OpenMP/clause-validity01.f90 b/flang/test/Semantics/OpenMP/clause-validity01.f90 index 8dd6d10200cd3..bc9d2d37060fc 100644 --- a/flang/test/Semantics/OpenMP/clause-validity01.f90 +++ b/flang/test/Semantics/OpenMP/clause-validity01.f90 @@ -376,7 +376,7 @@ a = 3.14 enddo - !ERROR: The parameter of the ALIGNED clause must be a constant positive integer expression + !ERROR: The alignment value should be a constant positive integer !$omp simd aligned(cpt:-2) do i = 1, N a = 3.14 @@ -572,7 +572,7 @@ allocate(allc) !ERROR: The parameter of the SIMDLEN clause must be a constant positive integer expression - !ERROR: The parameter of the ALIGNED clause must be a constant positive integer expression + !ERROR: The alignment value should be a constant positive integer !$omp taskloop simd simdlen(-1) aligned(allc:-2) do i = 1, N allc = 3.14 From d520f1e23c72190ce807306f05f899f106be3070 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Tue, 26 Nov 2024 16:03:56 -0600 Subject: [PATCH 6/7] fix examples --- flang/examples/FeatureList/FeatureList.cpp | 6 +++--- flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp | 8 +++++--- flang/examples/FlangOmpReport/FlangOmpReportVisitor.h | 6 +++--- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/flang/examples/FeatureList/FeatureList.cpp b/flang/examples/FeatureList/FeatureList.cpp index f7086b9e82b8d..ab309b15e4541 100644 --- a/flang/examples/FeatureList/FeatureList.cpp +++ b/flang/examples/FeatureList/FeatureList.cpp @@ -465,7 +465,7 @@ struct NodeVisitor { READ_FEATURE(OmpDeclareTargetWithClause) READ_FEATURE(OmpDeclareTargetWithList) READ_FEATURE(OmpDefaultClause) - READ_FEATURE(OmpDefaultClause::Type) + READ_FEATURE(OmpDefaultClause::DataSharingAttribute) READ_FEATURE(OmpDefaultmapClause) READ_FEATURE(OmpDefaultmapClause::ImplicitBehavior) READ_FEATURE(OmpVariableCategory::Value) @@ -508,7 +508,7 @@ struct NodeVisitor { READ_FEATURE(OmpOrderModifier) READ_FEATURE(OmpOrderModifier::Value) READ_FEATURE(OmpProcBindClause) - READ_FEATURE(OmpProcBindClause::Type) + READ_FEATURE(OmpProcBindClause::AffinityPolicy) READ_FEATURE(OmpReductionClause) READ_FEATURE(OmpInReductionClause) READ_FEATURE(OmpReductionCombiner) @@ -526,7 +526,7 @@ struct NodeVisitor { READ_FEATURE(OmpDeviceClause) READ_FEATURE(OmpDeviceClause::DeviceModifier) READ_FEATURE(OmpDeviceTypeClause) - READ_FEATURE(OmpDeviceTypeClause::Type) + READ_FEATURE(OmpDeviceTypeClause::DeviceTypeDescription) READ_FEATURE(OmpChunkModifier) READ_FEATURE(OmpChunkModifier::Value) READ_FEATURE(OmpOrderingModifier) diff --git a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp index 5bd8c76199278..afabd564ad5bd 100644 --- a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp +++ b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp @@ -190,15 +190,17 @@ void OpenMPCounterVisitor::PostConstructsCommon() { delete curConstruct; } -void OpenMPCounterVisitor::Post(const OmpProcBindClause::Type &c) { +void OpenMPCounterVisitor::Post(const OmpProcBindClause::AffinityPolicy &c) { clauseDetails += "type=" + std::string{OmpProcBindClause::EnumToString(c)} + ";"; } -void OpenMPCounterVisitor::Post(const OmpDefaultClause::Type &c) { +void OpenMPCounterVisitor::Post( + const OmpDefaultClause::DataSharingAttribute &c) { clauseDetails += "type=" + std::string{OmpDefaultClause::EnumToString(c)} + ";"; } -void OpenMPCounterVisitor::Post(const OmpDeviceTypeClause::Type &c) { +void OpenMPCounterVisitor::Post( + const OmpDeviceTypeClause::DeviceTypeDescription &c) { clauseDetails += "type=" + std::string{OmpDeviceTypeClause::EnumToString(c)} + ";"; } diff --git a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.h b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.h index 7e9ae94bef297..ed202e8ed2a4c 100644 --- a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.h +++ b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.h @@ -66,11 +66,11 @@ struct OpenMPCounterVisitor { void Post(const OpenMPConstruct &); void PostConstructsCommon(); - void Post(const OmpProcBindClause::Type &c); - void Post(const OmpDefaultClause::Type &c); + void Post(const OmpProcBindClause::AffinityPolicy &c); + void Post(const OmpDefaultClause::DataSharingAttribute &c); void Post(const OmpDefaultmapClause::ImplicitBehavior &c); void Post(const OmpVariableCategory::Value &c); - void Post(const OmpDeviceTypeClause::Type &c); + void Post(const OmpDeviceTypeClause::DeviceTypeDescription &c); void Post(const OmpChunkModifier::Value &c); void Post(const OmpLinearModifier::Value &c); void Post(const OmpOrderingModifier::Value &c); From 923638f04160c6c4a5fdf7afa309dcea3ec9fb7e Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Tue, 26 Nov 2024 16:18:27 -0600 Subject: [PATCH 7/7] fix examples --- flang/examples/FeatureList/FeatureList.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/flang/examples/FeatureList/FeatureList.cpp b/flang/examples/FeatureList/FeatureList.cpp index ab309b15e4541..2e90f19dc2e62 100644 --- a/flang/examples/FeatureList/FeatureList.cpp +++ b/flang/examples/FeatureList/FeatureList.cpp @@ -523,8 +523,9 @@ struct NodeVisitor { READ_FEATURE(OmpScheduleClause) READ_FEATURE(OmpScheduleClause::Kind) READ_FEATURE(OmpScheduleClause::Modifier) + READ_FEATURE(OmpDeviceModifier) READ_FEATURE(OmpDeviceClause) - READ_FEATURE(OmpDeviceClause::DeviceModifier) + READ_FEATURE(OmpDeviceClause::Modifier) READ_FEATURE(OmpDeviceTypeClause) READ_FEATURE(OmpDeviceTypeClause::DeviceTypeDescription) READ_FEATURE(OmpChunkModifier)