diff --git a/flang/examples/FeatureList/FeatureList.cpp b/flang/examples/FeatureList/FeatureList.cpp index 753ecb918a9cc..7e024dc387516 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) @@ -522,16 +522,16 @@ struct NodeVisitor { READ_FEATURE(OmpAllocateClause::AllocateModifier::ComplexModifier) READ_FEATURE(OmpAllocateClause::AllocateModifier::Align) READ_FEATURE(OmpScheduleClause) - READ_FEATURE(OmpScheduleClause::ScheduleType) + READ_FEATURE(OmpScheduleClause::Kind) + READ_FEATURE(OmpScheduleClause::Modifier) READ_FEATURE(OmpDeviceClause) 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 a9ff163f8243c..a3d9b0cfdc79b 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 83bd3644577e1..86f206ba85c6d 100644 --- a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.h +++ b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.h @@ -71,11 +71,12 @@ 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); + void Post(const OmpScheduleClause::Kind &c); void Post(const OmpIfClause::DirectiveNameModifier &c); void Post(const OmpCancelType::Type &c); void Post(const OmpClause &c); diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h index e9c149758c149..6d1e7329d5cce 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 32ebaa7fbffca..de179f47be8fc 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, Type> t; + ENUM_CLASS(Ordering, Concurrent) + MODIFIER_BOILERPLATE(OmpOrderModifier); + std::tuple t; }; // 2.5 proc-bind-clause -> PROC_BIND (MASTER | CLOSE | SPREAD) @@ -3816,27 +3851,19 @@ struct OmpReductionClause { std::tuple 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> 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, ScheduleType, - std::optional> - t; + ENUM_CLASS(Kind, Static, Dynamic, Guided, Auto, Runtime) + MODIFIER_BOILERPLATE(OmpOrderingModifier, OmpChunkModifier); + std::tuple> 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 d51c186261043..beab4c9b46a21 100644 --- a/flang/include/flang/Semantics/openmp-modifiers.h +++ b/flang/include/flang/Semantics/openmp-modifiers.h @@ -61,6 +61,8 @@ struct OmpModifierDescriptor { template const OmpModifierDescriptor &OmpGetDescriptor(); +template <> +const OmpModifierDescriptor &OmpGetDescriptor(); template <> const OmpModifierDescriptor &OmpGetDescriptor(); template <> @@ -68,6 +70,10 @@ const OmpModifierDescriptor &OmpGetDescriptor(); template <> const OmpModifierDescriptor &OmpGetDescriptor(); template <> +const OmpModifierDescriptor &OmpGetDescriptor(); +template <> +const OmpModifierDescriptor &OmpGetDescriptor(); +template <> const OmpModifierDescriptor &OmpGetDescriptor(); template <> const OmpModifierDescriptor &OmpGetDescriptor(); diff --git a/flang/lib/Lower/OpenMP/Clauses.cpp b/flang/lib/Lower/OpenMP/Clauses.cpp index 4f9e7a7c1d78c..8639d08827f4e 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>(inp.v.t); - auto &t1 = std::get(inp.v.t); + auto &mods = semantics::OmpGetModifiers(inp.v); + auto *t0 = semantics::OmpGetUniqueModifier(mods); + auto &t1 = std::get(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(mods); auto &t2 = std::get(inp.v.t); + assert(t1 && "OmpReductionIdentifier is required"); + return Reduction{ - {/*ReductionModifier=*/t0 - ? std::make_optional(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>(inp.v.t); - auto &t1 = std::get(inp.v.t); - auto &t2 = std::get>(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(t0->t); - auto &m2 = - std::get>(t0->t); - - std::optional omod; - std::optional 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(mods); + auto *t1 = semantics::OmpGetUniqueModifier(mods); + auto &t2 = std::get(inp.v.t); + auto &t3 = std::get>(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(mods); auto &t1 = std::get(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 ada50e0488837..9c053e2213c67 100644 --- a/flang/lib/Lower/OpenMP/Clauses.h +++ b/flang/lib/Lower/OpenMP/Clauses.h @@ -153,6 +153,16 @@ std::optional maybeApply(FuncTy &&func, return std::move(func(*arg)); } +template < + typename FuncTy, // + typename ArgTy, // + typename ResultTy = std::invoke_result_t> +std::optional maybeApplyToV(FuncTy &&func, const ArgTy *arg) { + if (!arg) + return std::nullopt; + return std::move(func(arg->v)); +} + std::optional getBaseObject(const Object &object, semantics::SemanticsContext &semaCtx); diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index a1d368d73ab83..ceae20270d13d 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -228,6 +228,18 @@ TYPE_PARSER(construct( // TYPE_PARSER(construct(Parser{}) || construct(Parser{})) +TYPE_PARSER(construct( // + "SIMD" >> pure(OmpChunkModifier::Value::Simd))) + +TYPE_PARSER(construct( + "REPRODUCIBLE" >> pure(OmpOrderModifier::Value::Reproducible) || + "UNCONSTRAINED" >> pure(OmpOrderModifier::Value::Unconstrained))) + +TYPE_PARSER(construct( + "MONOTONIC" >> pure(OmpOrderingModifier::Value::Monotonic) || + "NONMONOTONIC" >> pure(OmpOrderingModifier::Value::Nonmonotonic) || + "SIMD" >> pure(OmpOrderingModifier::Value::Simd))) + TYPE_PARSER(construct( "INSCAN" >> pure(OmpReductionModifier::Value::Inscan) || "TASK" >> pure(OmpReductionModifier::Value::Task) || @@ -241,12 +253,6 @@ TYPE_PARSER(construct( "MUTEXINOUTSET" >> pure(OmpTaskDependenceType::Value::Mutexinoutset) || "OUT" >> pure(OmpTaskDependenceType::Value::Out))) -// This could be auto-generated. -TYPE_PARSER(sourced(construct(sourced( - construct(Parser{}) || - construct( - Parser{}))))) - TYPE_PARSER(construct( "AGGREGATE" >> pure(OmpVariableCategory::Value::Aggregate) || "ALL"_id >> pure(OmpVariableCategory::Value::All) || @@ -254,6 +260,19 @@ TYPE_PARSER(construct( "POINTER" >> pure(OmpVariableCategory::Value::Pointer) || "SCALAR" >> pure(OmpVariableCategory::Value::Scalar))) +// This could be auto-generated. +TYPE_PARSER( + sourced(construct(Parser{}))) + +TYPE_PARSER(sourced(construct(sourced( + construct(Parser{}) || + construct( + Parser{}))))) + +TYPE_PARSER(sourced(construct(sourced( + construct(Parser{}) || + construct(Parser{}))))) + TYPE_PARSER(sourced( construct(Parser{}))) @@ -336,25 +355,16 @@ TYPE_PARSER(construct( "DEFAULT" >> pure(OmpDefaultmapClause::ImplicitBehavior::Default)), maybe(":" >> nonemptyList(Parser{})))) -// 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( - "MONOTONIC" >> pure(OmpScheduleModifierType::ModType::Monotonic) || - "NONMONOTONIC" >> pure(OmpScheduleModifierType::ModType::Nonmonotonic) || - "SIMD" >> pure(OmpScheduleModifierType::ModType::Simd))) - -TYPE_PARSER(construct(Parser{}, - maybe("," >> Parser{}) / ":")) - -TYPE_PARSER(construct(maybe(Parser{}), - "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( + "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( + maybe(nonemptyList(Parser{}) / ":"), + Parser{}, maybe("," >> scalarIntExpr))) // device([ device-modifier :] scalar-integer-expression) TYPE_PARSER(construct( @@ -497,14 +507,9 @@ TYPE_PARSER(construct( construct(Parser{}) || construct(Parser{}))) -// 2.9.5 ORDER ([order-modifier :]concurrent) -TYPE_PARSER(construct( - "REPRODUCIBLE" >> pure(OmpOrderModifier::Kind::Reproducible)) || - construct( - "UNCONSTRAINED" >> pure(OmpOrderModifier::Kind::Unconstrained))) - -TYPE_PARSER(construct(maybe(Parser{} / ":"), - "CONCURRENT" >> pure(OmpOrderClause::Type::Concurrent))) +TYPE_PARSER(construct( + maybe(nonemptyList(Parser{}) / ":"), + "CONCURRENT" >> pure(OmpOrderClause::Ordering::Concurrent))) // OMP 5.2 12.6.1 grainsize([ prescriptiveness :] scalar-integer-expression) TYPE_PARSER(construct( diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index 72123ae0d318d..4881da848c347 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2133,13 +2133,10 @@ class UnparseVisitor { } Walk(std::get(x.t)); } - void Unparse(const OmpScheduleModifier &x) { - Walk(std::get(x.t)); - Walk(",", std::get>(x.t)); - } void Unparse(const OmpScheduleClause &x) { - Walk(std::get>(x.t), ":"); - Walk(std::get(x.t)); + using Modifier = OmpScheduleClause::Modifier; + Walk(std::get>>(x.t), ":"); + Walk(std::get(x.t)); Walk(",", std::get>(x.t)); } void Unparse(const OmpDeviceClause &x) { @@ -2230,8 +2227,9 @@ class UnparseVisitor { Put(")"); } void Unparse(const OmpOrderClause &x) { - Walk(std::get>(x.t), ":"); - Walk(std::get(x.t)); + using Modifier = OmpOrderClause::Modifier; + Walk(std::get>>(x.t), ":"); + Walk(std::get(x.t)); } void Unparse(const OmpGrainsizeClause &x) { Walk(std::get>(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 079d0fd17bfac..e6398a39d9791 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(clause->u)}; - if (ScheduleModifierHasType(schedClause.v, - parser::OmpScheduleModifierType::ModType::Nonmonotonic)) { + auto &modifiers{OmpGetModifiers(schedClause.v)}; + auto *ordering{ + OmpGetUniqueModifier(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(o_clause->u)}; - if (std::get(orderClause.v.t) == - parser::OmpOrderClause::Type::Concurrent) { + if (std::get(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); @@ -2868,45 +2865,41 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Reduction &x) { bool OmpStructureChecker::CheckReductionOperators( const parser::OmpClause::Reduction &x) { + bool ok = false; auto &modifiers{OmpGetModifiers(x.v)}; - const auto *definedOp{ - OmpGetUniqueModifier(modifiers)}; - if (!definedOp) { - return false; + if (const auto *ident{ + OmpGetUniqueModifier(modifiers)}) { + + auto visitOperator{[&](const parser::DefinedOperator &dOpr) { + if (const auto *intrinsicOp{ + std::get_if( + &dOpr.u)}) { + ok = CheckIntrinsicOperator(*intrinsicOp); + } else { + context_.Say(GetContext().clauseSource, + "Invalid reduction operator in REDUCTION clause."_err_en_US, + ContextDirectiveAsFortran()); + } + }}; + + auto visitDesignator{[&](const parser::ProcedureDesignator &procD) { + const parser::Name *name{std::get_if(&procD.u)}; + if (name && name->symbol) { + const SourceName &realName{name->symbol->GetUltimate().name()}; + if (realName == "max" || realName == "min" || realName == "iand" || + realName == "ior" || realName == "ieor") { + ok = true; + } + } + if (!ok) { + context_.Say(GetContext().clauseSource, + "Invalid reduction identifier in REDUCTION " + "clause."_err_en_US, + ContextDirectiveAsFortran()); + } + }}; + common::visit(common::visitors{visitOperator, visitDesignator}, ident->u); } - bool ok = false; - common::visit( - common::visitors{ - [&](const parser::DefinedOperator &dOpr) { - if (const auto *intrinsicOp{ - std::get_if( - &dOpr.u)}) { - ok = CheckIntrinsicOperator(*intrinsicOp); - } else { - context_.Say(GetContext().clauseSource, - "Invalid reduction operator in REDUCTION clause."_err_en_US, - ContextDirectiveAsFortran()); - } - }, - [&](const parser::ProcedureDesignator &procD) { - const parser::Name *name{std::get_if(&procD.u)}; - if (name && name->symbol) { - const SourceName &realName{name->symbol->GetUltimate().name()}; - if (realName == "max" || realName == "min" || - realName == "iand" || realName == "ior" || - realName == "ieor") { - ok = true; - } - } - if (!ok) { - context_.Say(GetContext().clauseSource, - "Invalid reduction identifier in REDUCTION " - "clause."_err_en_US, - ContextDirectiveAsFortran()); - } - }, - }, - definedOp->u); return ok; } @@ -3553,34 +3546,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>(x.t)}; - if (modifier) { - const auto &modType1{ - std::get(modifier->t)}; - const auto &modType2{ - std::get>( - 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(scheduleClause.t)}; + auto &chunk{ + std::get>(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 +3576,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(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 af61215ecc403..cd0a475937613 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 &); 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 a425eec76a36d..e0d73e605c73b 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() { + static const OmpModifierDescriptor desc{ + /*name=*/"chunk-modifier", + /*props=*/ + { + {45, {OmpProperty::Unique}}, + }, + /*clauses=*/ + { + {45, {Clause::OMPC_schedule}}, + }, + }; + return desc; +} + template <> const OmpModifierDescriptor &OmpGetDescriptor() { static const OmpModifierDescriptor desc{ @@ -108,6 +124,38 @@ const OmpModifierDescriptor &OmpGetDescriptor() { return desc; } +template <> +const OmpModifierDescriptor &OmpGetDescriptor() { + static const OmpModifierDescriptor desc{ + /*name=*/"order-modifier", + /*props=*/ + { + {51, {OmpProperty::Unique}}, + }, + /*clauses=*/ + { + {51, {Clause::OMPC_order}}, + }, + }; + return desc; +} + +template <> +const OmpModifierDescriptor &OmpGetDescriptor() { + static const OmpModifierDescriptor desc{ + /*name=*/"ordering-modifier", + /*props=*/ + { + {45, {OmpProperty::Unique}}, + }, + /*clauses=*/ + { + {45, {Clause::OMPC_schedule}}, + }, + }; + return desc; +} + template <> const OmpModifierDescriptor & OmpGetDescriptor() { diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp index c75808a8963b3..107bd3b09019a 100644 --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -522,49 +522,47 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor { const auto &objList{std::get(x.v.t)}; ResolveOmpObjectList(objList, Symbol::Flag::OmpReduction); - auto &modifiers{OmpGetModifiers(x.v)}; - if (!modifiers) { - return false; - } - - auto createDummyProcSymbol = [&](const parser::Name *name) { - // If name resolution failed, create a dummy symbol - const auto namePair{ - currScope().try_emplace(name->source, Attrs{}, ProcEntityDetails{})}; - auto &newSymbol{*namePair.first->second}; - if (context_.intrinsics().IsIntrinsic(name->ToString())) { - newSymbol.attrs().set(Attr::INTRINSIC); - } - name->symbol = &newSymbol; - }; + if (auto &modifiers{OmpGetModifiers(x.v)}) { + auto createDummyProcSymbol = [&](const parser::Name *name) { + // If name resolution failed, create a dummy symbol + const auto namePair{currScope().try_emplace( + name->source, Attrs{}, ProcEntityDetails{})}; + auto &newSymbol{*namePair.first->second}; + if (context_.intrinsics().IsIntrinsic(name->ToString())) { + newSymbol.attrs().set(Attr::INTRINSIC); + } + name->symbol = &newSymbol; + }; - for (auto &mod : *modifiers) { - if (!std::holds_alternative(mod.u)) { - continue; - } - auto &opr{std::get(mod.u)}; - if (auto *procD{parser::Unwrap(opr.u)}) { - if (auto *name{parser::Unwrap(procD->u)}) { - if (!name->symbol) { - if (!ResolveName(name)) { - createDummyProcSymbol(name); + for (auto &mod : *modifiers) { + if (!std::holds_alternative(mod.u)) { + continue; + } + auto &opr{std::get(mod.u)}; + if (auto *procD{parser::Unwrap(opr.u)}) { + if (auto *name{parser::Unwrap(procD->u)}) { + if (!name->symbol) { + if (!ResolveName(name)) { + createDummyProcSymbol(name); + } } } - } - if (auto *procRef{parser::Unwrap(procD->u)}) { - if (!procRef->v.thing.component.symbol) { - if (!ResolveName(&procRef->v.thing.component)) { - createDummyProcSymbol(&procRef->v.thing.component); + if (auto *procRef{ + parser::Unwrap(procD->u)}) { + if (!procRef->v.thing.component.symbol) { + if (!ResolveName(&procRef->v.thing.component)) { + createDummyProcSymbol(&procRef->v.thing.component); + } } } } } - } - using ReductionModifier = parser::OmpReductionModifier; - if (auto *maybeModifier{ - OmpGetUniqueModifier(modifiers)}) { - if (maybeModifier->v == ReductionModifier::Value::Inscan) { - ResolveOmpObjectList(objList, Symbol::Flag::OmpInScanReduction); + using ReductionModifier = parser::OmpReductionModifier; + if (auto *maybeModifier{ + OmpGetUniqueModifier(modifiers)}) { + if (maybeModifier->v == ReductionModifier::Value::Inscan) { + ResolveOmpObjectList(objList, Symbol::Flag::OmpInScanReduction); + } } } return false; diff --git a/flang/test/Parser/OpenMP/order-clause01.f90 b/flang/test/Parser/OpenMP/order-clause01.f90 index 41e131f9b5428..f810eb74ee29d 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