[llvm-branch-commits] [flang] [flang][OpenMP] Use new modifier code in ORDER and SCHEDULE clauses (PR #117081)
Krzysztof Parzyszek via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Nov 20 16:19:05 PST 2024
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.Parzyszek at 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
More information about the llvm-branch-commits
mailing list