https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/117081
This actually simplifies the AST node for the schedule clause: the two allowed modifiers can be easily classified as the ordering-modifier and the chunk-modifier during parsing without the need to create additional classes. >From 43bdfcdb48328fcdfe762734bd5a4c1df3987c4b Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek <krzysztof.parzys...@amd.com> Date: Mon, 18 Nov 2024 13:01:30 -0600 Subject: [PATCH] [flang][OpenMP] Use new modifier code in ORDER and SCHEDULE clauses This actually simplifies the AST node for the schedule clause: the two allowed modifiers can be easily classified as the ordering-modifier and the chunk-modifier during parsing without the need to create additional classes. --- flang/examples/FeatureList/FeatureList.cpp | 13 ++- .../FlangOmpReport/FlangOmpReportVisitor.cpp | 10 ++- .../FlangOmpReport/FlangOmpReportVisitor.h | 3 +- flang/include/flang/Parser/dump-parse-tree.h | 17 ++-- flang/include/flang/Parser/parse-tree.h | 81 ++++++++++++------- .../flang/Semantics/openmp-modifiers.h | 6 ++ flang/lib/Lower/OpenMP/Clauses.cpp | 75 ++++++----------- flang/lib/Lower/OpenMP/Clauses.h | 10 +++ flang/lib/Parser/openmp-parsers.cpp | 71 ++++++++-------- flang/lib/Parser/unparse.cpp | 23 +++--- flang/lib/Semantics/check-omp-structure.cpp | 58 ++++++------- flang/lib/Semantics/check-omp-structure.h | 2 - flang/lib/Semantics/openmp-modifiers.cpp | 48 +++++++++++ flang/test/Parser/OpenMP/order-clause01.f90 | 50 ++++++------ 14 files changed, 263 insertions(+), 204 deletions(-) diff --git a/flang/examples/FeatureList/FeatureList.cpp b/flang/examples/FeatureList/FeatureList.cpp index 753ecb918a9ccb..e1c42586c62c94 100644 --- a/flang/examples/FeatureList/FeatureList.cpp +++ b/flang/examples/FeatureList/FeatureList.cpp @@ -505,9 +505,9 @@ struct NodeVisitor { READ_FEATURE(OmpObject) READ_FEATURE(OmpObjectList) READ_FEATURE(OmpOrderClause) - READ_FEATURE(OmpOrderClause::Type) + READ_FEATURE(OmpOrderClause::Ordering) READ_FEATURE(OmpOrderModifier) - READ_FEATURE(OmpOrderModifier::Kind) + READ_FEATURE(OmpOrderModifier::Value) READ_FEATURE(OmpProcBindClause) READ_FEATURE(OmpProcBindClause::Type) READ_FEATURE(OmpReductionClause) @@ -527,11 +527,10 @@ struct NodeVisitor { READ_FEATURE(OmpDeviceClause::DeviceModifier) READ_FEATURE(OmpDeviceTypeClause) READ_FEATURE(OmpDeviceTypeClause::Type) - READ_FEATURE(OmpScheduleModifier) - READ_FEATURE(OmpScheduleModifier::Modifier1) - READ_FEATURE(OmpScheduleModifier::Modifier2) - READ_FEATURE(OmpScheduleModifierType) - READ_FEATURE(OmpScheduleModifierType::ModType) + READ_FEATURE(OmpChunkModifier) + READ_FEATURE(OmpChunkModifier::Value) + READ_FEATURE(OmpOrderingModifier) + READ_FEATURE(OmpOrderingModifier::Value) READ_FEATURE(OmpSectionBlocks) READ_FEATURE(OmpSectionsDirective) READ_FEATURE(OmpSimpleStandaloneDirective) diff --git a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp index a9ff163f8243ce..a3d9b0cfdc79b8 100644 --- a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp +++ b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp @@ -213,14 +213,18 @@ void OpenMPCounterVisitor::Post(const OmpVariableCategory::Value &c) { "variable_category=" + std::string{OmpVariableCategory::EnumToString(c)} + ";"; } -void OpenMPCounterVisitor::Post(const OmpScheduleModifierType::ModType &c) { +void OpenMPCounterVisitor::Post(const OmpChunkModifier::Value &c) { clauseDetails += - "modifier=" + std::string{OmpScheduleModifierType::EnumToString(c)} + ";"; + "modifier=" + std::string{OmpChunkModifier::EnumToString(c)} + ";"; } void OpenMPCounterVisitor::Post(const OmpLinearModifier::Value &c) { clauseDetails += "modifier=" + std::string{OmpLinearModifier::EnumToString(c)} + ";"; } +void OpenMPCounterVisitor::Post(const OmpOrderingModifier::Value &c) { + clauseDetails += + "modifier=" + std::string{OmpOrderingModifier::EnumToString(c)} + ";"; +} void OpenMPCounterVisitor::Post(const OmpTaskDependenceType::Value &c) { clauseDetails += "type=" + std::string{OmpTaskDependenceType::EnumToString(c)} + ";"; @@ -228,7 +232,7 @@ void OpenMPCounterVisitor::Post(const OmpTaskDependenceType::Value &c) { void OpenMPCounterVisitor::Post(const OmpMapClause::Type &c) { clauseDetails += "type=" + std::string{OmpMapClause::EnumToString(c)} + ";"; } -void OpenMPCounterVisitor::Post(const OmpScheduleClause::ScheduleType &c) { +void OpenMPCounterVisitor::Post(const OmpScheduleClause::Kind &c) { clauseDetails += "type=" + std::string{OmpScheduleClause::EnumToString(c)} + ";"; } diff --git a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.h b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.h index 83bd3644577e1c..608cb5a2241b83 100644 --- a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.h +++ b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.h @@ -71,8 +71,9 @@ struct OpenMPCounterVisitor { void Post(const OmpDefaultmapClause::ImplicitBehavior &c); void Post(const OmpVariableCategory::Value &c); void Post(const OmpDeviceTypeClause::Type &c); - void Post(const OmpScheduleModifierType::ModType &c); + void Post(const OmpChunkModifier::Value &c); void Post(const OmpLinearModifier::Value &c); + void Post(const OmpOrderingModifier::Value &c); void Post(const OmpTaskDependenceType::Value &c); void Post(const OmpMapClause::Type &c); void Post(const OmpScheduleClause::ScheduleType &c); diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h index e9c149758c1493..6d1e7329d5cce8 100644 --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -559,9 +559,10 @@ class ParseTreeDumper { NODE(parser, OmpObject) NODE(parser, OmpObjectList) NODE(parser, OmpOrderClause) - NODE_ENUM(OmpOrderClause, Type) + NODE(OmpOrderClause, Modifier) + NODE_ENUM(OmpOrderClause, Ordering) NODE(parser, OmpOrderModifier) - NODE_ENUM(OmpOrderModifier, Kind) + NODE_ENUM(OmpOrderModifier, Value) NODE(parser, OmpGrainsizeClause) NODE_ENUM(OmpGrainsizeClause, Prescriptiveness) NODE(parser, OmpNumTasksClause) @@ -585,17 +586,17 @@ class ParseTreeDumper { NODE(OmpAllocateClause::AllocateModifier, ComplexModifier) NODE(OmpAllocateClause::AllocateModifier, Align) NODE(parser, OmpScheduleClause) - NODE_ENUM(OmpScheduleClause, ScheduleType) + NODE(OmpScheduleClause, Modifier) + NODE_ENUM(OmpScheduleClause, Kind) NODE(parser, OmpDeviceClause) NODE_ENUM(OmpDeviceClause, DeviceModifier) NODE(parser, OmpDeviceTypeClause) NODE_ENUM(OmpDeviceTypeClause, Type) NODE(parser, OmpUpdateClause) - NODE(parser, OmpScheduleModifier) - NODE(OmpScheduleModifier, Modifier1) - NODE(OmpScheduleModifier, Modifier2) - NODE(parser, OmpScheduleModifierType) - NODE_ENUM(OmpScheduleModifierType, ModType) + NODE(parser, OmpChunkModifier) + NODE_ENUM(OmpChunkModifier, Value) + NODE(parser, OmpOrderingModifier) + NODE_ENUM(OmpOrderingModifier, Value) NODE(parser, OmpSectionBlocks) NODE(parser, OmpSectionsDirective) NODE(parser, OmpSimpleStandaloneDirective) diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index 32ebaa7fbffcae..de179f47be8fca 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -3457,6 +3457,17 @@ inline namespace modifier { // ENUM_CLASS(Value, Keyword1, Keyword2); // }; +// Ref: [5.2:252-254] +// +// chunk-modifier -> +// SIMD // since 5.2 +// +// Prior to 5.2 "chunk-modifier" was a part of "modifier" on SCHEDULE clause. +struct OmpChunkModifier { + ENUM_CLASS(Value, Simd) + WRAPPER_CLASS_BOILERPLATE(OmpChunkModifier, Value); +}; + // Ref: [5.0:47-49], [5.1:49-51], [5.2:67-69] // // iterator-specifier -> @@ -3508,6 +3519,30 @@ struct OmpLinearModifier { WRAPPER_CLASS_BOILERPLATE(OmpLinearModifier, Value); }; +// Ref: [4.5:56-63], [5.0:101-109], [5.1:126-133], [5.2:252-254] +// +// modifier -> +// MONOTONIC | NONMONOTONIC | SIMD // since 4.5, until 5.1 +// ordering-modifier -> +// MONOTONIC | NONMONOTONIC // since 5.2 +// +// Until 5.1, the SCHEDULE clause accepted up to two instances of "modifier". +// Since 5.2 "modifier" was replaced with "ordering-modifier" and "chunk- +// modifier". +struct OmpOrderingModifier { + ENUM_CLASS(Value, Monotonic, Nonmonotonic, Simd) + WRAPPER_CLASS_BOILERPLATE(OmpOrderingModifier, Value); +}; + +// Ref: [5.1:125-126], [5.2:233-234] +// +// order-modifier -> +// REPRODUCIBLE | UNCONSTRAINED // since 5.1 +struct OmpOrderModifier { + ENUM_CLASS(Value, Reproducible, Unconstrained) + WRAPPER_CLASS_BOILERPLATE(OmpOrderModifier, Value); +}; + // Ref: [4.5:201-207], [5.0:293-299], [5.1:325-331], [5.2:124] // // reduction-identifier -> @@ -3786,16 +3821,16 @@ struct OmpMapClause { t; }; -// 2.9.5 order-clause -> ORDER ([order-modifier :]concurrent) -struct OmpOrderModifier { - ENUM_CLASS(Kind, Reproducible, Unconstrained) - WRAPPER_CLASS_BOILERPLATE(OmpOrderModifier, Kind); -}; - +// Ref: [5.0:101-109], [5.1:126-134], [5.2:233-234] +// +// order-clause -> +// ORDER(CONCURRENT) | // since 5.0 +// ORDER([order-modifier:] CONCURRENT) // since 5.1 struct OmpOrderClause { TUPLE_CLASS_BOILERPLATE(OmpOrderClause); - ENUM_CLASS(Type, Concurrent) - std::tuple<std::optional<OmpOrderModifier>, Type> t; + ENUM_CLASS(Ordering, Concurrent) + MODIFIER_BOILERPLATE(OmpOrderModifier); + std::tuple<MODIFIERS(), Ordering> t; }; // 2.5 proc-bind-clause -> PROC_BIND (MASTER | CLOSE | SPREAD) @@ -3816,27 +3851,19 @@ struct OmpReductionClause { std::tuple<MODIFIERS(), OmpObjectList> t; }; -// 2.7.1 sched-modifier -> MONOTONIC | NONMONOTONIC | SIMD -struct OmpScheduleModifierType { - ENUM_CLASS(ModType, Monotonic, Nonmonotonic, Simd) - WRAPPER_CLASS_BOILERPLATE(OmpScheduleModifierType, ModType); -}; - -struct OmpScheduleModifier { - TUPLE_CLASS_BOILERPLATE(OmpScheduleModifier); - WRAPPER_CLASS(Modifier1, OmpScheduleModifierType); - WRAPPER_CLASS(Modifier2, OmpScheduleModifierType); - std::tuple<Modifier1, std::optional<Modifier2>> t; -}; - -// 2.7.1 schedule-clause -> SCHEDULE ([sched-modifier1] [, sched-modifier2]:] -// kind[, chunk_size]) +// Ref: [4.5:56-63], [5.0:101-109], [5.1:126-133], [5.2:252-254] +// +// schedule-clause -> +// SCHEDULE([modifier[, modifier]:] +// kind[, chunk-size]) // since 4.5, until 5.1 +// schedule-clause -> +// SCHEDULE([ordering-modifier], chunk-modifier], +// kind[, chunk_size]) // since 5.2 struct OmpScheduleClause { TUPLE_CLASS_BOILERPLATE(OmpScheduleClause); - ENUM_CLASS(ScheduleType, Static, Dynamic, Guided, Auto, Runtime) - std::tuple<std::optional<OmpScheduleModifier>, ScheduleType, - std::optional<ScalarIntExpr>> - t; + ENUM_CLASS(Kind, Static, Dynamic, Guided, Auto, Runtime) + MODIFIER_BOILERPLATE(OmpOrderingModifier, OmpChunkModifier); + std::tuple<MODIFIERS(), Kind, std::optional<ScalarIntExpr>> t; }; // Ref: [4.5:107-109], [5.0:176-180], [5.1:205-210], [5.2:167-168] diff --git a/flang/include/flang/Semantics/openmp-modifiers.h b/flang/include/flang/Semantics/openmp-modifiers.h index 28fec7314cd8b5..fd6bd86fb280d8 100644 --- a/flang/include/flang/Semantics/openmp-modifiers.h +++ b/flang/include/flang/Semantics/openmp-modifiers.h @@ -61,6 +61,8 @@ struct OmpModifierDescriptor { template <typename SpecificTy> const OmpModifierDescriptor &OmpGetDescriptor(); +template <> +const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpChunkModifier>(); template <> const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpDependenceType>(); template <> @@ -68,6 +70,10 @@ const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpIterator>(); template <> const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpLinearModifier>(); template <> +const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpOrderModifier>(); +template <> +const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpOrderingModifier>(); +template <> const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpReductionIdentifier>(); template <> const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpReductionModifier>(); diff --git a/flang/lib/Lower/OpenMP/Clauses.cpp b/flang/lib/Lower/OpenMP/Clauses.cpp index 4f9e7a7c1d78c3..8639d08827f4ed 100644 --- a/flang/lib/Lower/OpenMP/Clauses.cpp +++ b/flang/lib/Lower/OpenMP/Clauses.cpp @@ -1109,7 +1109,7 @@ Order make(const parser::OmpClause::Order &inp, using wrapped = parser::OmpOrderClause; CLAUSET_ENUM_CONVERT( // - convert1, parser::OmpOrderModifier::Kind, Order::OrderModifier, + convert1, parser::OmpOrderModifier::Value, Order::OrderModifier, // clang-format off MS(Reproducible, Reproducible) MS(Unconstrained, Unconstrained) @@ -1117,20 +1117,18 @@ Order make(const parser::OmpClause::Order &inp, ); CLAUSET_ENUM_CONVERT( // - convert2, wrapped::Type, Order::Ordering, + convert2, wrapped::Ordering, Order::Ordering, // clang-format off MS(Concurrent, Concurrent) // clang-format on ); - auto &t0 = std::get<std::optional<parser::OmpOrderModifier>>(inp.v.t); - auto &t1 = std::get<wrapped::Type>(inp.v.t); + auto &mods = semantics::OmpGetModifiers(inp.v); + auto *t0 = semantics::OmpGetUniqueModifier<parser::OmpOrderModifier>(mods); + auto &t1 = std::get<wrapped::Ordering>(inp.v.t); - auto convert3 = [&](const parser::OmpOrderModifier &s) { - return convert1(s.v); - }; - return Order{ - {/*OrderModifier=*/maybeApply(convert3, t0), /*Ordering=*/convert2(t1)}}; + return Order{{/*OrderModifier=*/maybeApplyToV(convert1, t0), + /*Ordering=*/convert2(t1)}}; } Ordered make(const parser::OmpClause::Ordered &inp, @@ -1197,10 +1195,10 @@ Reduction make(const parser::OmpClause::Reduction &inp, auto *t1 = semantics::OmpGetUniqueModifier<parser::OmpReductionIdentifier>(mods); auto &t2 = std::get<parser::OmpObjectList>(inp.v.t); + assert(t1 && "OmpReductionIdentifier is required"); + return Reduction{ - {/*ReductionModifier=*/t0 - ? std::make_optional<Reduction::ReductionModifier>(convert(t0->v)) - : std::nullopt, + {/*ReductionModifier=*/maybeApplyToV(convert, t0), /*ReductionIdentifiers=*/{makeReductionOperator(*t1, semaCtx)}, /*List=*/makeObjects(t2, semaCtx)}}; } @@ -1221,7 +1219,7 @@ Schedule make(const parser::OmpClause::Schedule &inp, using wrapped = parser::OmpScheduleClause; CLAUSET_ENUM_CONVERT( // - convert1, wrapped::ScheduleType, Schedule::Kind, + convert1, wrapped::Kind, Schedule::Kind, // clang-format off MS(Static, Static) MS(Dynamic, Dynamic) @@ -1232,8 +1230,7 @@ Schedule make(const parser::OmpClause::Schedule &inp, ); CLAUSET_ENUM_CONVERT( // - convert2, parser::OmpScheduleModifierType::ModType, - Schedule::OrderingModifier, + convert2, parser::OmpOrderingModifier::Value, Schedule::OrderingModifier, // clang-format off MS(Monotonic, Monotonic) MS(Nonmonotonic, Nonmonotonic) @@ -1241,48 +1238,22 @@ Schedule make(const parser::OmpClause::Schedule &inp, ); CLAUSET_ENUM_CONVERT( // - convert3, parser::OmpScheduleModifierType::ModType, - Schedule::ChunkModifier, + convert3, parser::OmpChunkModifier::Value, Schedule::ChunkModifier, // clang-format off MS(Simd, Simd) // clang-format on ); - auto &t0 = std::get<std::optional<parser::OmpScheduleModifier>>(inp.v.t); - auto &t1 = std::get<wrapped::ScheduleType>(inp.v.t); - auto &t2 = std::get<std::optional<parser::ScalarIntExpr>>(inp.v.t); - - if (!t0) { - return Schedule{{/*Kind=*/convert1(t1), /*OrderingModifier=*/std::nullopt, - /*ChunkModifier=*/std::nullopt, - /*ChunkSize=*/maybeApply(makeExprFn(semaCtx), t2)}}; - } - - // The members of parser::OmpScheduleModifier correspond to OrderingModifier, - // and ChunkModifier, but they can appear in any order. - auto &m1 = std::get<parser::OmpScheduleModifier::Modifier1>(t0->t); - auto &m2 = - std::get<std::optional<parser::OmpScheduleModifier::Modifier2>>(t0->t); - - std::optional<Schedule::OrderingModifier> omod; - std::optional<Schedule::ChunkModifier> cmod; - - if (m1.v.v == parser::OmpScheduleModifierType::ModType::Simd) { - // m1 is chunk-modifier - cmod = convert3(m1.v.v); - if (m2) - omod = convert2(m2->v.v); - } else { - // m1 is ordering-modifier - omod = convert2(m1.v.v); - if (m2) - cmod = convert3(m2->v.v); - } + auto &mods = semantics::OmpGetModifiers(inp.v); + auto *t0 = semantics::OmpGetUniqueModifier<parser::OmpOrderingModifier>(mods); + auto *t1 = semantics::OmpGetUniqueModifier<parser::OmpChunkModifier>(mods); + auto &t2 = std::get<wrapped::Kind>(inp.v.t); + auto &t3 = std::get<std::optional<parser::ScalarIntExpr>>(inp.v.t); - return Schedule{{/*Kind=*/convert1(t1), - /*OrderingModifier=*/omod, - /*ChunkModifier=*/cmod, - /*ChunkSize=*/maybeApply(makeExprFn(semaCtx), t2)}}; + return Schedule{{/*Kind=*/convert1(t2), + /*OrderingModifier=*/maybeApplyToV(convert2, t0), + /*ChunkModifier=*/maybeApplyToV(convert3, t1), + /*ChunkSize=*/maybeApply(makeExprFn(semaCtx), t3)}}; } // SeqCst: empty @@ -1326,6 +1297,8 @@ TaskReduction make(const parser::OmpClause::TaskReduction &inp, auto *t0 = semantics::OmpGetUniqueModifier<parser::OmpReductionIdentifier>(mods); auto &t1 = std::get<parser::OmpObjectList>(inp.v.t); + assert(t0 && "OmpReductionIdentifier is required"); + return TaskReduction{ {/*ReductionIdentifiers=*/{makeReductionOperator(*t0, semaCtx)}, /*List=*/makeObjects(t1, semaCtx)}}; diff --git a/flang/lib/Lower/OpenMP/Clauses.h b/flang/lib/Lower/OpenMP/Clauses.h index ada50e0488837b..9c053e2213c675 100644 --- a/flang/lib/Lower/OpenMP/Clauses.h +++ b/flang/lib/Lower/OpenMP/Clauses.h @@ -153,6 +153,16 @@ std::optional<ResultTy> maybeApply(FuncTy &&func, return std::move(func(*arg)); } +template < + typename FuncTy, // + typename ArgTy, // + typename ResultTy = std::invoke_result_t<FuncTy, typename ArgTy::Value>> +std::optional<ResultTy> maybeApplyToV(FuncTy &&func, const ArgTy *arg) { + if (!arg) + return std::nullopt; + return std::move(func(arg->v)); +} + std::optional<Object> getBaseObject(const Object &object, semantics::SemanticsContext &semaCtx); diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index a1d368d73ab83a..ceae20270d13d0 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -228,6 +228,18 @@ TYPE_PARSER(construct<OmpLinearModifier>( // TYPE_PARSER(construct<OmpReductionIdentifier>(Parser<DefinedOperator>{}) || construct<OmpReductionIdentifier>(Parser<ProcedureDesignator>{})) +TYPE_PARSER(construct<OmpChunkModifier>( // + "SIMD" >> pure(OmpChunkModifier::Value::Simd))) + +TYPE_PARSER(construct<OmpOrderModifier>( + "REPRODUCIBLE" >> pure(OmpOrderModifier::Value::Reproducible) || + "UNCONSTRAINED" >> pure(OmpOrderModifier::Value::Unconstrained))) + +TYPE_PARSER(construct<OmpOrderingModifier>( + "MONOTONIC" >> pure(OmpOrderingModifier::Value::Monotonic) || + "NONMONOTONIC" >> pure(OmpOrderingModifier::Value::Nonmonotonic) || + "SIMD" >> pure(OmpOrderingModifier::Value::Simd))) + TYPE_PARSER(construct<OmpReductionModifier>( "INSCAN" >> pure(OmpReductionModifier::Value::Inscan) || "TASK" >> pure(OmpReductionModifier::Value::Task) || @@ -241,12 +253,6 @@ TYPE_PARSER(construct<OmpTaskDependenceType>( "MUTEXINOUTSET" >> pure(OmpTaskDependenceType::Value::Mutexinoutset) || "OUT" >> pure(OmpTaskDependenceType::Value::Out))) -// This could be auto-generated. -TYPE_PARSER(sourced(construct<OmpReductionClause::Modifier>(sourced( - construct<OmpReductionClause::Modifier>(Parser<OmpReductionModifier>{}) || - construct<OmpReductionClause::Modifier>( - Parser<OmpReductionIdentifier>{}))))) - TYPE_PARSER(construct<OmpVariableCategory>( "AGGREGATE" >> pure(OmpVariableCategory::Value::Aggregate) || "ALL"_id >> pure(OmpVariableCategory::Value::All) || @@ -254,6 +260,19 @@ TYPE_PARSER(construct<OmpVariableCategory>( "POINTER" >> pure(OmpVariableCategory::Value::Pointer) || "SCALAR" >> pure(OmpVariableCategory::Value::Scalar))) +// This could be auto-generated. +TYPE_PARSER( + sourced(construct<OmpOrderClause::Modifier>(Parser<OmpOrderModifier>{}))) + +TYPE_PARSER(sourced(construct<OmpReductionClause::Modifier>(sourced( + construct<OmpReductionClause::Modifier>(Parser<OmpReductionModifier>{}) || + construct<OmpReductionClause::Modifier>( + Parser<OmpReductionIdentifier>{}))))) + +TYPE_PARSER(sourced(construct<OmpScheduleClause::Modifier>(sourced( + construct<OmpScheduleClause::Modifier>(Parser<OmpChunkModifier>{}) || + construct<OmpScheduleClause::Modifier>(Parser<OmpOrderingModifier>{}))))) + TYPE_PARSER(sourced( construct<OmpDefaultmapClause::Modifier>(Parser<OmpVariableCategory>{}))) @@ -336,25 +355,16 @@ TYPE_PARSER(construct<OmpDefaultmapClause>( "DEFAULT" >> pure(OmpDefaultmapClause::ImplicitBehavior::Default)), maybe(":" >> nonemptyList(Parser<OmpDefaultmapClause::Modifier>{})))) -// 2.7.1 SCHEDULE ([modifier1 [, modifier2]:]kind[, chunk_size]) -// Modifier -> MONITONIC | NONMONOTONIC | SIMD -// kind -> STATIC | DYNAMIC | GUIDED | AUTO | RUNTIME -// chunk_size -> ScalarIntExpr -TYPE_PARSER(construct<OmpScheduleModifierType>( - "MONOTONIC" >> pure(OmpScheduleModifierType::ModType::Monotonic) || - "NONMONOTONIC" >> pure(OmpScheduleModifierType::ModType::Nonmonotonic) || - "SIMD" >> pure(OmpScheduleModifierType::ModType::Simd))) - -TYPE_PARSER(construct<OmpScheduleModifier>(Parser<OmpScheduleModifierType>{}, - maybe("," >> Parser<OmpScheduleModifierType>{}) / ":")) - -TYPE_PARSER(construct<OmpScheduleClause>(maybe(Parser<OmpScheduleModifier>{}), - "STATIC" >> pure(OmpScheduleClause::ScheduleType::Static) || - "DYNAMIC" >> pure(OmpScheduleClause::ScheduleType::Dynamic) || - "GUIDED" >> pure(OmpScheduleClause::ScheduleType::Guided) || - "AUTO" >> pure(OmpScheduleClause::ScheduleType::Auto) || - "RUNTIME" >> pure(OmpScheduleClause::ScheduleType::Runtime), - maybe("," >> scalarIntExpr))) +TYPE_PARSER(construct<OmpScheduleClause::Kind>( + "STATIC" >> pure(OmpScheduleClause::Kind::Static) || + "DYNAMIC" >> pure(OmpScheduleClause::Kind::Dynamic) || + "GUIDED" >> pure(OmpScheduleClause::Kind::Guided) || + "AUTO" >> pure(OmpScheduleClause::Kind::Auto) || + "RUNTIME" >> pure(OmpScheduleClause::Kind::Runtime))) + +TYPE_PARSER(construct<OmpScheduleClause>( + maybe(nonemptyList(Parser<OmpScheduleClause::Modifier>{}) / ":"), + Parser<OmpScheduleClause::Kind>{}, maybe("," >> scalarIntExpr))) // device([ device-modifier :] scalar-integer-expression) TYPE_PARSER(construct<OmpDeviceClause>( @@ -497,14 +507,9 @@ TYPE_PARSER(construct<OmpUpdateClause>( construct<OmpUpdateClause>(Parser<OmpDependenceType>{}) || construct<OmpUpdateClause>(Parser<OmpTaskDependenceType>{}))) -// 2.9.5 ORDER ([order-modifier :]concurrent) -TYPE_PARSER(construct<OmpOrderModifier>( - "REPRODUCIBLE" >> pure(OmpOrderModifier::Kind::Reproducible)) || - construct<OmpOrderModifier>( - "UNCONSTRAINED" >> pure(OmpOrderModifier::Kind::Unconstrained))) - -TYPE_PARSER(construct<OmpOrderClause>(maybe(Parser<OmpOrderModifier>{} / ":"), - "CONCURRENT" >> pure(OmpOrderClause::Type::Concurrent))) +TYPE_PARSER(construct<OmpOrderClause>( + maybe(nonemptyList(Parser<OmpOrderClause::Modifier>{}) / ":"), + "CONCURRENT" >> pure(OmpOrderClause::Ordering::Concurrent))) // OMP 5.2 12.6.1 grainsize([ prescriptiveness :] scalar-integer-expression) TYPE_PARSER(construct<OmpGrainsizeClause>( diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index 72123ae0d318d1..4881da848c3473 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2133,13 +2133,10 @@ class UnparseVisitor { } Walk(std::get<OmpObjectList>(x.t)); } - void Unparse(const OmpScheduleModifier &x) { - Walk(std::get<OmpScheduleModifier::Modifier1>(x.t)); - Walk(",", std::get<std::optional<OmpScheduleModifier::Modifier2>>(x.t)); - } void Unparse(const OmpScheduleClause &x) { - Walk(std::get<std::optional<OmpScheduleModifier>>(x.t), ":"); - Walk(std::get<OmpScheduleClause::ScheduleType>(x.t)); + using Modifier = OmpScheduleClause::Modifier; + Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ":"); + Walk(std::get<OmpScheduleClause::Kind>(x.t)); Walk(",", std::get<std::optional<ScalarIntExpr>>(x.t)); } void Unparse(const OmpDeviceClause &x) { @@ -2230,8 +2227,9 @@ class UnparseVisitor { Put(")"); } void Unparse(const OmpOrderClause &x) { - Walk(std::get<std::optional<OmpOrderModifier>>(x.t), ":"); - Walk(std::get<OmpOrderClause::Type>(x.t)); + using Modifier = OmpOrderClause::Modifier; + Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ":"); + Walk(std::get<OmpOrderClause::Ordering>(x.t)); } void Unparse(const OmpGrainsizeClause &x) { Walk(std::get<std::optional<OmpGrainsizeClause::Prescriptiveness>>(x.t), @@ -2907,18 +2905,19 @@ class UnparseVisitor { WALK_NESTED_ENUM(OmpVariableCategory, Value) // OMP variable-category WALK_NESTED_ENUM( OmpLastprivateClause, LastprivateModifier) // OMP lastprivate-modifier - WALK_NESTED_ENUM(OmpScheduleModifierType, ModType) // OMP schedule-modifier + WALK_NESTED_ENUM(OmpChunkModifier, Value) // OMP chunk-modifier WALK_NESTED_ENUM(OmpLinearModifier, Value) // OMP linear-modifier + WALK_NESTED_ENUM(OmpOrderingModifier, Value) // OMP ordering-modifier WALK_NESTED_ENUM(OmpTaskDependenceType, Value) // OMP task-dependence-type - WALK_NESTED_ENUM(OmpScheduleClause, ScheduleType) // OMP schedule-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(OmpReductionModifier, Value) // OMP reduction-modifier WALK_NESTED_ENUM(OmpFromClause, Expectation) // OMP motion-expectation WALK_NESTED_ENUM(OmpIfClause, DirectiveNameModifier) // OMP directive-modifier WALK_NESTED_ENUM(OmpCancelType, Type) // OMP cancel-type - WALK_NESTED_ENUM(OmpOrderClause, Type) // OMP order-type - WALK_NESTED_ENUM(OmpOrderModifier, Kind) // OMP order-modifier + WALK_NESTED_ENUM(OmpOrderClause, Ordering) // OMP ordering + WALK_NESTED_ENUM(OmpOrderModifier, Value) // OMP order-modifier WALK_NESTED_ENUM( OmpGrainsizeClause, Prescriptiveness) // OMP grainsize-modifier WALK_NESTED_ENUM(OmpNumTasksClause, Prescriptiveness) // OMP numtasks-modifier diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index 079d0fd17bfac1..a4af1ce5771a89 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -2576,19 +2576,16 @@ void OmpStructureChecker::Leave(const parser::OmpClauseList &) { if (auto *clause{FindClause(llvm::omp::Clause::OMPC_schedule)}) { // only one schedule clause is allowed const auto &schedClause{std::get<parser::OmpClause::Schedule>(clause->u)}; - if (ScheduleModifierHasType(schedClause.v, - parser::OmpScheduleModifierType::ModType::Nonmonotonic)) { + auto &modifiers{OmpGetModifiers(schedClause.v)}; + auto *ordering{ + OmpGetUniqueModifier<parser::OmpOrderingModifier>(modifiers)}; + if (ordering && + ordering->v == parser::OmpOrderingModifier::Value::Nonmonotonic) { if (FindClause(llvm::omp::Clause::OMPC_ordered)) { context_.Say(clause->source, "The NONMONOTONIC modifier cannot be specified " "if an ORDERED clause is specified"_err_en_US); } - if (ScheduleModifierHasType(schedClause.v, - parser::OmpScheduleModifierType::ModType::Monotonic)) { - context_.Say(clause->source, - "The MONOTONIC and NONMONOTONIC modifiers " - "cannot be both specified"_err_en_US); - } } } @@ -2648,8 +2645,8 @@ void OmpStructureChecker::Leave(const parser::OmpClauseList &) { if (auto *o_clause{FindClause(llvm::omp::Clause::OMPC_order)}) { const auto &orderClause{ std::get<parser::OmpClause::Order>(o_clause->u)}; - if (std::get<parser::OmpOrderClause::Type>(orderClause.v.t) == - parser::OmpOrderClause::Type::Concurrent) { + if (std::get<parser::OmpOrderClause::Ordering>(orderClause.v.t) == + parser::OmpOrderClause::Ordering::Concurrent) { context_.Say(sl_clause->source, "The `SAFELEN` clause cannot appear in the `SIMD` directive " "with `ORDER(CONCURRENT)` clause"_err_en_US); @@ -3553,34 +3550,23 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Map &x) { } } -bool OmpStructureChecker::ScheduleModifierHasType( - const parser::OmpScheduleClause &x, - const parser::OmpScheduleModifierType::ModType &type) { - const auto &modifier{ - std::get<std::optional<parser::OmpScheduleModifier>>(x.t)}; - if (modifier) { - const auto &modType1{ - std::get<parser::OmpScheduleModifier::Modifier1>(modifier->t)}; - const auto &modType2{ - std::get<std::optional<parser::OmpScheduleModifier::Modifier2>>( - modifier->t)}; - if (modType1.v.v == type || (modType2 && modType2->v.v == type)) { - return true; - } - } - return false; -} void OmpStructureChecker::Enter(const parser::OmpClause::Schedule &x) { CheckAllowedClause(llvm::omp::Clause::OMPC_schedule); const parser::OmpScheduleClause &scheduleClause = x.v; + if (!OmpVerifyModifiers( + scheduleClause, GetContext().clauseSource, context_)) { + return; + } // 2.7 Loop Construct Restriction if (llvm::omp::allDoSet.test(GetContext().directive)) { - const auto &kind{std::get<1>(scheduleClause.t)}; - const auto &chunk{std::get<2>(scheduleClause.t)}; + auto &modifiers{OmpGetModifiers(scheduleClause)}; + auto kind{std::get<parser::OmpScheduleClause::Kind>(scheduleClause.t)}; + auto &chunk{ + std::get<std::optional<parser::ScalarIntExpr>>(scheduleClause.t)}; if (chunk) { - if (kind == parser::OmpScheduleClause::ScheduleType::Runtime || - kind == parser::OmpScheduleClause::ScheduleType::Auto) { + if (kind == parser::OmpScheduleClause::Kind::Runtime || + kind == parser::OmpScheduleClause::Kind::Auto) { context_.Say(GetContext().clauseSource, "When SCHEDULE clause has %s specified, " "it must not have chunk size specified"_err_en_US, @@ -3594,10 +3580,12 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Schedule &x) { } } - if (ScheduleModifierHasType(scheduleClause, - parser::OmpScheduleModifierType::ModType::Nonmonotonic)) { - if (kind != parser::OmpScheduleClause::ScheduleType::Dynamic && - kind != parser::OmpScheduleClause::ScheduleType::Guided) { + auto *ordering{ + OmpGetUniqueModifier<parser::OmpOrderingModifier>(modifiers)}; + if (ordering && + ordering->v == parser::OmpOrderingModifier::Value::Nonmonotonic) { + if (kind != parser::OmpScheduleClause::Kind::Dynamic && + kind != parser::OmpScheduleClause::Kind::Guided) { context_.Say(GetContext().clauseSource, "The NONMONOTONIC modifier can only be specified with " "SCHEDULE(DYNAMIC) or SCHEDULE(GUIDED)"_err_en_US); diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h index af61215ecc403d..cd0a4759376130 100644 --- a/flang/lib/Semantics/check-omp-structure.h +++ b/flang/lib/Semantics/check-omp-structure.h @@ -161,8 +161,6 @@ class OmpStructureChecker void HasInvalidDistributeNesting(const parser::OpenMPLoopConstruct &x); void HasInvalidLoopBinding(const parser::OpenMPLoopConstruct &x); // specific clause related - bool ScheduleModifierHasType(const parser::OmpScheduleClause &, - const parser::OmpScheduleModifierType::ModType &); void CheckAllowedMapTypes(const parser::OmpMapClause::Type &, const std::list<parser::OmpMapClause::Type> &); llvm::StringRef getClauseName(llvm::omp::Clause clause) override; diff --git a/flang/lib/Semantics/openmp-modifiers.cpp b/flang/lib/Semantics/openmp-modifiers.cpp index a425eec76a36d8..e0d73e605c73b0 100644 --- a/flang/lib/Semantics/openmp-modifiers.cpp +++ b/flang/lib/Semantics/openmp-modifiers.cpp @@ -55,6 +55,22 @@ const OmpClauses &OmpModifierDescriptor::clauses(unsigned version) const { // Note: The intent for these functions is to have them be automatically- // generated in the future. +template <> +const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpChunkModifier>() { + static const OmpModifierDescriptor desc{ + /*name=*/"chunk-modifier", + /*props=*/ + { + {45, {OmpProperty::Unique}}, + }, + /*clauses=*/ + { + {45, {Clause::OMPC_schedule}}, + }, + }; + return desc; +} + template <> const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpDependenceType>() { static const OmpModifierDescriptor desc{ @@ -108,6 +124,38 @@ const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpLinearModifier>() { return desc; } +template <> +const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpOrderModifier>() { + static const OmpModifierDescriptor desc{ + /*name=*/"order-modifier", + /*props=*/ + { + {51, {OmpProperty::Unique}}, + }, + /*clauses=*/ + { + {51, {Clause::OMPC_order}}, + }, + }; + return desc; +} + +template <> +const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpOrderingModifier>() { + static const OmpModifierDescriptor desc{ + /*name=*/"ordering-modifier", + /*props=*/ + { + {45, {OmpProperty::Unique}}, + }, + /*clauses=*/ + { + {45, {Clause::OMPC_schedule}}, + }, + }; + return desc; +} + template <> const OmpModifierDescriptor & OmpGetDescriptor<parser::OmpReductionIdentifier>() { diff --git a/flang/test/Parser/OpenMP/order-clause01.f90 b/flang/test/Parser/OpenMP/order-clause01.f90 index 41e131f9b5428e..f810eb74ee29d0 100644 --- a/flang/test/Parser/OpenMP/order-clause01.f90 +++ b/flang/test/Parser/OpenMP/order-clause01.f90 @@ -17,7 +17,7 @@ subroutine test_do_order() !PARSE-TREE-NEXT: OmpBeginLoopDirective !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = do !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause -!PARSE-TREE-NEXT: Type = Concurrent +!PARSE-TREE-NEXT: Ordering = Concurrent subroutine test_simd_order_reproducible() integer :: i, j = 1 @@ -33,8 +33,8 @@ subroutine test_simd_order_reproducible() !PARSE-TREE-NEXT: OmpBeginLoopDirective !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = simd !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause -!PARSE-TREE-NEXT: Kind = Reproducible -!PARSE-TREE-NEXT: Type = Concurrent +!PARSE-TREE-NEXT: OmpOrderModifier -> Value = Reproducible +!PARSE-TREE-NEXT: Ordering = Concurrent subroutine test_do_simd_order_unconstrained() integer :: i, j = 1 @@ -50,8 +50,8 @@ subroutine test_do_simd_order_unconstrained() !PARSE-TREE-NEXT: OmpBeginLoopDirective !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = do simd !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause -!PARSE-TREE-NEXT: Kind = Unconstrained -!PARSE-TREE-NEXT: Type = Concurrent +!PARSE-TREE-NEXT: OmpOrderModifier -> Value = Unconstrained +!PARSE-TREE-NEXT: Ordering = Concurrent subroutine test_parallel_do_order() integer :: i, j = 1 @@ -67,7 +67,7 @@ subroutine test_parallel_do_order() !PARSE-TREE-NEXT: OmpBeginLoopDirective !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = parallel do !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause -!PARSE-TREE-NEXT: Type = Concurrent +!PARSE-TREE-NEXT: Ordering = Concurrent subroutine test_parallel_do_simd_order_reproducible() integer :: i, j = 1 @@ -83,8 +83,8 @@ subroutine test_parallel_do_simd_order_reproducible() !PARSE-TREE-NEXT: OmpBeginLoopDirective !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = parallel do simd !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause -!PARSE-TREE-NEXT: Kind = Reproducible -!PARSE-TREE-NEXT: Type = Concurrent +!PARSE-TREE-NEXT: OmpOrderModifier -> Value = Reproducible +!PARSE-TREE-NEXT: Ordering = Concurrent subroutine test_target_simd_order_unconstrained() integer :: i, j = 1 @@ -100,8 +100,8 @@ subroutine test_target_simd_order_unconstrained() !PARSE-TREE-NEXT: OmpBeginLoopDirective !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = target simd !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause -!PARSE-TREE-NEXT: Kind = Unconstrained -!PARSE-TREE-NEXT: Type = Concurrent +!PARSE-TREE-NEXT: OmpOrderModifier -> Value = Unconstrained +!PARSE-TREE-NEXT: Ordering = Concurrent subroutine test_target_parallel_do_order() integer :: i, j = 1 @@ -117,7 +117,7 @@ subroutine test_target_parallel_do_order() !PARSE-TREE-NEXT: OmpBeginLoopDirective !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = target parallel do !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause -!PARSE-TREE-NEXT: Type = Concurrent +!PARSE-TREE-NEXT: Ordering = Concurrent subroutine test_target_parallel_do_simd_order_reproducible() integer :: i, j = 1 @@ -133,8 +133,8 @@ subroutine test_target_parallel_do_simd_order_reproducible() !PARSE-TREE-NEXT: OmpBeginLoopDirective !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = target parallel do simd !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause -!PARSE-TREE-NEXT: Kind = Reproducible -!PARSE-TREE-NEXT: Type = Concurrent +!PARSE-TREE-NEXT: OmpOrderModifier -> Value = Reproducible +!PARSE-TREE-NEXT: Ordering = Concurrent subroutine test_teams_distribute_simd_order_unconstrained() integer :: i, j = 1 @@ -150,8 +150,8 @@ subroutine test_teams_distribute_simd_order_unconstrained() !PARSE-TREE-NEXT: OmpBeginLoopDirective !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = teams distribute simd !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause -!PARSE-TREE-NEXT: Kind = Unconstrained -!PARSE-TREE-NEXT: Type = Concurrent +!PARSE-TREE-NEXT: OmpOrderModifier -> Value = Unconstrained +!PARSE-TREE-NEXT: Ordering = Concurrent subroutine test_teams_distribute_parallel_do_order() integer :: i, j = 1 @@ -167,7 +167,7 @@ subroutine test_teams_distribute_parallel_do_order() !PARSE-TREE-NEXT: OmpBeginLoopDirective !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = teams distribute parallel do !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause -!PARSE-TREE-NEXT: Type = Concurrent +!PARSE-TREE-NEXT: Ordering = Concurrent subroutine test_teams_distribute_parallel_do_simd_order_reproducible() integer :: i, j = 1 @@ -183,8 +183,8 @@ subroutine test_teams_distribute_parallel_do_simd_order_reproducible() !PARSE-TREE-NEXT: OmpBeginLoopDirective !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = teams distribute parallel do simd !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause -!PARSE-TREE-NEXT: Kind = Reproducible -!PARSE-TREE-NEXT: Type = Concurrent +!PARSE-TREE-NEXT: OmpOrderModifier -> Value = Reproducible +!PARSE-TREE-NEXT: Ordering = Concurrent subroutine test_target_teams_distribute_simd_order_unconstrained() integer :: i, j = 1 @@ -200,8 +200,8 @@ subroutine test_target_teams_distribute_simd_order_unconstrained() !PARSE-TREE-NEXT: OmpBeginLoopDirective !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = target teams distribute simd !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause -!PARSE-TREE-NEXT: Kind = Unconstrained -!PARSE-TREE-NEXT: Type = Concurrent +!PARSE-TREE-NEXT: OmpOrderModifier -> Value = Unconstrained +!PARSE-TREE-NEXT: Ordering = Concurrent subroutine test_target_teams_distribute_parallel_do_order() integer :: i, j = 1 @@ -217,7 +217,7 @@ subroutine test_target_teams_distribute_parallel_do_order() !PARSE-TREE-NEXT: OmpBeginLoopDirective !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = target teams distribute parallel do !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause -!PARSE-TREE-NEXT: Type = Concurrent +!PARSE-TREE-NEXT: Ordering = Concurrent subroutine test_target_teams_distribute_parallel_do_simd_order_reproducible() integer :: i, j = 1 @@ -233,8 +233,8 @@ subroutine test_target_teams_distribute_parallel_do_simd_order_reproducible() !PARSE-TREE-NEXT: OmpBeginLoopDirective !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = target teams distribute parallel do simd !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause -!PARSE-TREE-NEXT: Kind = Reproducible -!PARSE-TREE-NEXT: Type = Concurrent +!PARSE-TREE-NEXT: OmpOrderModifier -> Value = Reproducible +!PARSE-TREE-NEXT: Ordering = Concurrent subroutine test_taskloop_simd_order_unconstrained() integer :: i, j = 1 @@ -250,5 +250,5 @@ subroutine test_taskloop_simd_order_unconstrained() !PARSE-TREE-NEXT: OmpBeginLoopDirective !PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = taskloop simd !PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause -!PARSE-TREE-NEXT: Kind = Unconstrained -!PARSE-TREE-NEXT: Type = Concurrent +!PARSE-TREE-NEXT: OmpOrderModifier -> Value = Unconstrained +!PARSE-TREE-NEXT: Ordering = Concurrent _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits