[flang-commits] [flang] bde79c0 - [flang][OpenMP] Use new modifiers in DEPEND/GRAINSIZE/NUM_TASKS (#117917)
via flang-commits
flang-commits at lists.llvm.org
Mon Dec 2 13:22:09 PST 2024
Author: Krzysztof Parzyszek
Date: 2024-12-02T15:22:05-06:00
New Revision: bde79c0e27fd0fb1e31c9b8b34ae71716c51a8e8
URL: https://github.com/llvm/llvm-project/commit/bde79c0e27fd0fb1e31c9b8b34ae71716c51a8e8
DIFF: https://github.com/llvm/llvm-project/commit/bde79c0e27fd0fb1e31c9b8b34ae71716c51a8e8.diff
LOG: [flang][OpenMP] Use new modifiers in DEPEND/GRAINSIZE/NUM_TASKS (#117917)
The usual changes, added more references to OpenMP specs.
Added:
Modified:
flang/examples/FeatureList/FeatureList.cpp
flang/include/flang/Parser/dump-parse-tree.h
flang/include/flang/Parser/parse-tree.h
flang/include/flang/Semantics/openmp-modifiers.h
flang/lib/Lower/OpenMP/Clauses.cpp
flang/lib/Lower/OpenMP/Clauses.h
flang/lib/Parser/openmp-parsers.cpp
flang/lib/Parser/parse-tree.cpp
flang/lib/Parser/unparse.cpp
flang/lib/Semantics/check-omp-structure.cpp
flang/lib/Semantics/openmp-modifiers.cpp
flang/test/Parser/OpenMP/depobj-construct.f90
flang/test/Parser/OpenMP/taskloop.f90
flang/test/Semantics/OpenMP/depend05.f90
llvm/include/llvm/Frontend/OpenMP/ClauseT.h
Removed:
################################################################################
diff --git a/flang/examples/FeatureList/FeatureList.cpp b/flang/examples/FeatureList/FeatureList.cpp
index 2e90f19dc2e62c..c5cb8c8fdf40bb 100644
--- a/flang/examples/FeatureList/FeatureList.cpp
+++ b/flang/examples/FeatureList/FeatureList.cpp
@@ -488,7 +488,9 @@ struct NodeVisitor {
READ_FEATURE(OmpEndLoopDirective)
READ_FEATURE(OmpEndSectionsDirective)
READ_FEATURE(OmpGrainsizeClause)
- READ_FEATURE(OmpGrainsizeClause::Prescriptiveness)
+ READ_FEATURE(OmpGrainsizeClause::Modifier)
+ READ_FEATURE(OmpPrescriptiveness)
+ READ_FEATURE(OmpPrescriptiveness::Value)
READ_FEATURE(OmpIfClause)
READ_FEATURE(OmpIfClause::DirectiveNameModifier)
READ_FEATURE(OmpLinearClause)
@@ -500,7 +502,7 @@ struct NodeVisitor {
READ_FEATURE(OmpMapClause)
READ_FEATURE(OmpMapClause::Modifier)
READ_FEATURE(OmpNumTasksClause)
- READ_FEATURE(OmpNumTasksClause::Prescriptiveness)
+ READ_FEATURE(OmpNumTasksClause::Modifier)
READ_FEATURE(OmpObject)
READ_FEATURE(OmpObjectList)
READ_FEATURE(OmpOrderClause)
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index 958793d62338a8..1144a6b946c70f 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -536,6 +536,7 @@ class ParseTreeDumper {
NODE(OmpDoacross, Source)
NODE(parser, OmpDependClause)
NODE(OmpDependClause, TaskDep)
+ NODE(OmpDependClause::TaskDep, Modifier)
NODE(parser, OmpDetachClause)
NODE(parser, OmpDoacrossClause)
NODE(parser, OmpDestroyClause)
@@ -574,9 +575,11 @@ class ParseTreeDumper {
NODE(parser, OmpOrderModifier)
NODE_ENUM(OmpOrderModifier, Value)
NODE(parser, OmpGrainsizeClause)
- NODE_ENUM(OmpGrainsizeClause, Prescriptiveness)
+ NODE(OmpGrainsizeClause, Modifier)
+ NODE(parser, OmpPrescriptiveness)
+ NODE_ENUM(OmpPrescriptiveness, Value)
NODE(parser, OmpNumTasksClause)
- NODE_ENUM(OmpNumTasksClause, Prescriptiveness)
+ NODE(OmpNumTasksClause, Modifier)
NODE(parser, OmpBindClause)
NODE_ENUM(OmpBindClause, Binding)
NODE(parser, OmpProcBindClause)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index d093cb5ffcfb6e..40781fd0779d6f 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -3642,6 +3642,15 @@ struct OmpOrderModifier {
WRAPPER_CLASS_BOILERPLATE(OmpOrderModifier, Value);
};
+// Ref: [5.1:166-171], [5.2:269-270]
+//
+// prescriptiveness ->
+// STRICT // since 5.1
+struct OmpPrescriptiveness {
+ ENUM_CLASS(Value, Strict)
+ WRAPPER_CLASS_BOILERPLATE(OmpPrescriptiveness, Value);
+};
+
// Ref: [4.5:201-207], [5.0:293-299], [5.1:325-331], [5.2:124]
//
// reduction-identifier ->
@@ -3831,8 +3840,8 @@ struct OmpDependClause {
struct TaskDep {
OmpTaskDependenceType::Value GetTaskDepType() const;
TUPLE_CLASS_BOILERPLATE(TaskDep);
- std::tuple<std::optional<OmpIterator>, OmpTaskDependenceType, OmpObjectList>
- t;
+ MODIFIER_BOILERPLATE(OmpIterator, OmpTaskDependenceType);
+ std::tuple<MODIFIERS(), OmpObjectList> t;
};
std::variant<TaskDep, OmpDoacross> u;
};
@@ -3893,11 +3902,15 @@ struct OmpFromClause {
std::tuple<MODIFIERS(), OmpObjectList, bool> t;
};
-// OMP 5.2 12.6.1 grainsize-clause -> grainsize ([prescriptiveness :] value)
+// Ref: [4.5:87-91], [5.0:140-146], [5.1:166-171], [5.2:269]
+//
+// grainsize-clause ->
+// GRAINSIZE(grain-size) | // since 4.5
+// GRAINSIZE([prescriptiveness:] grain-size) // since 5.1
struct OmpGrainsizeClause {
TUPLE_CLASS_BOILERPLATE(OmpGrainsizeClause);
- ENUM_CLASS(Prescriptiveness, Strict);
- std::tuple<std::optional<Prescriptiveness>, ScalarIntExpr> t;
+ MODIFIER_BOILERPLATE(OmpPrescriptiveness);
+ std::tuple<MODIFIERS(), ScalarIntExpr> t;
};
// 2.12 if-clause -> IF ([ directive-name-modifier :] scalar-logical-expr)
@@ -3963,6 +3976,17 @@ struct OmpMapClause {
std::tuple<MODIFIERS(), OmpObjectList, bool> t;
};
+// Ref: [4.5:87-91], [5.0:140-146], [5.1:166-171], [5.2:270]
+//
+// num-tasks-clause ->
+// NUM_TASKS(num-tasks) | // since 4.5
+// NUM_TASKS([prescriptiveness:] num-tasks) // since 5.1
+struct OmpNumTasksClause {
+ TUPLE_CLASS_BOILERPLATE(OmpNumTasksClause);
+ MODIFIER_BOILERPLATE(OmpPrescriptiveness);
+ std::tuple<MODIFIERS(), ScalarIntExpr> t;
+};
+
// Ref: [5.0:101-109], [5.1:126-134], [5.2:233-234]
//
// order-clause ->
@@ -4030,13 +4054,6 @@ struct OmpToClause {
std::tuple<MODIFIERS(), OmpObjectList, bool> t;
};
-// OMP 5.2 12.6.2 num_tasks-clause -> num_tasks ([prescriptiveness :] value)
-struct OmpNumTasksClause {
- TUPLE_CLASS_BOILERPLATE(OmpNumTasksClause);
- ENUM_CLASS(Prescriptiveness, Strict);
- std::tuple<std::optional<Prescriptiveness>, ScalarIntExpr> t;
-};
-
// Ref: [5.0:254-255], [5.1:287-288], [5.2:321-322]
//
// update-clause ->
@@ -4045,6 +4062,7 @@ struct OmpNumTasksClause {
// UPDATE(task-dependence-type) // since 5.2
struct OmpUpdateClause {
UNION_CLASS_BOILERPLATE(OmpUpdateClause);
+ // The dependence type is an argument here, not a modifier.
std::variant<OmpDependenceType, OmpTaskDependenceType> u;
};
diff --git a/flang/include/flang/Semantics/openmp-modifiers.h b/flang/include/flang/Semantics/openmp-modifiers.h
index fab4b38090b049..dbc554198df21f 100644
--- a/flang/include/flang/Semantics/openmp-modifiers.h
+++ b/flang/include/flang/Semantics/openmp-modifiers.h
@@ -82,6 +82,7 @@ DECLARE_DESCRIPTOR(parser::OmpMapType);
DECLARE_DESCRIPTOR(parser::OmpMapTypeModifier);
DECLARE_DESCRIPTOR(parser::OmpOrderModifier);
DECLARE_DESCRIPTOR(parser::OmpOrderingModifier);
+DECLARE_DESCRIPTOR(parser::OmpPrescriptiveness);
DECLARE_DESCRIPTOR(parser::OmpReductionIdentifier);
DECLARE_DESCRIPTOR(parser::OmpReductionModifier);
DECLARE_DESCRIPTOR(parser::OmpTaskDependenceType);
diff --git a/flang/lib/Lower/OpenMP/Clauses.cpp b/flang/lib/Lower/OpenMP/Clauses.cpp
index 2792232253879f..ff2667983d4367 100644
--- a/flang/lib/Lower/OpenMP/Clauses.cpp
+++ b/flang/lib/Lower/OpenMP/Clauses.cpp
@@ -369,6 +369,15 @@ clause::DependenceType makeDepType(const parser::OmpTaskDependenceType &inp) {
llvm_unreachable("Unexpected task dependence type");
}
+clause::Prescriptiveness
+makePrescriptiveness(parser::OmpPrescriptiveness::Value v) {
+ switch (v) {
+ case parser::OmpPrescriptiveness::Value::Strict:
+ return clause::Prescriptiveness::Strict;
+ }
+ llvm_unreachable("Unexpected prescriptiveness");
+}
+
// --------------------------------------------------------------------
// Actual clauses. Each T (where tomp::T exists in ClauseT) has its "make".
@@ -615,15 +624,18 @@ Depend make(const parser::OmpClause::Depend &inp,
using Variant = decltype(Depend::u);
auto visitTaskDep = [&](const wrapped::TaskDep &s) -> Variant {
- auto &t0 = std::get<std::optional<parser::OmpIterator>>(s.t);
- auto &t1 = std::get<parser::OmpTaskDependenceType>(s.t);
- auto &t2 = std::get<parser::OmpObjectList>(s.t);
+ auto &mods = semantics::OmpGetModifiers(s);
+ auto *m0 = semantics::OmpGetUniqueModifier<parser::OmpIterator>(mods);
+ auto *m1 =
+ semantics::OmpGetUniqueModifier<parser::OmpTaskDependenceType>(mods);
+ auto &t1 = std::get<parser::OmpObjectList>(s.t);
+ assert(m1 && "expecting task dependence type");
auto &&maybeIter =
- maybeApply([&](auto &&s) { return makeIterator(s, semaCtx); }, t0);
- return Depend::TaskDep{{/*DependenceType=*/makeDepType(t1),
+ m0 ? makeIterator(*m0, semaCtx) : std::optional<Iterator>{};
+ return Depend::TaskDep{{/*DependenceType=*/makeDepType(*m1),
/*Iterator=*/std::move(maybeIter),
- /*LocatorList=*/makeObjects(t2, semaCtx)}};
+ /*LocatorList=*/makeObjects(t1, semaCtx)}};
};
return Depend{common::visit( //
@@ -785,19 +797,12 @@ From make(const parser::OmpClause::From &inp,
Grainsize make(const parser::OmpClause::Grainsize &inp,
semantics::SemanticsContext &semaCtx) {
// inp.v -> parser::OmpGrainsizeClause
- using wrapped = parser::OmpGrainsizeClause;
-
- CLAUSET_ENUM_CONVERT( //
- convert, parser::OmpGrainsizeClause::Prescriptiveness,
- Grainsize::Prescriptiveness,
- // clang-format off
- MS(Strict, Strict)
- // clang-format on
- );
- auto &t0 = std::get<std::optional<wrapped::Prescriptiveness>>(inp.v.t);
+ auto &mods = semantics::OmpGetModifiers(inp.v);
+ auto *m0 = semantics::OmpGetUniqueModifier<parser::OmpPrescriptiveness>(mods);
auto &t1 = std::get<parser::ScalarIntExpr>(inp.v.t);
- return Grainsize{{/*Prescriptiveness=*/maybeApply(convert, t0),
- /*Grainsize=*/makeExpr(t1, semaCtx)}};
+ return Grainsize{
+ {/*Prescriptiveness=*/maybeApplyToV(makePrescriptiveness, m0),
+ /*Grainsize=*/makeExpr(t1, semaCtx)}};
}
HasDeviceAddr make(const parser::OmpClause::HasDeviceAddr &inp,
@@ -1047,18 +1052,10 @@ Novariants make(const parser::OmpClause::Novariants &inp,
NumTasks make(const parser::OmpClause::NumTasks &inp,
semantics::SemanticsContext &semaCtx) {
// inp.v -> parser::OmpNumTasksClause
- using wrapped = parser::OmpNumTasksClause;
-
- CLAUSET_ENUM_CONVERT( //
- convert, parser::OmpNumTasksClause::Prescriptiveness,
- NumTasks::Prescriptiveness,
- // clang-format off
- MS(Strict, Strict)
- // clang-format on
- );
- auto &t0 = std::get<std::optional<wrapped::Prescriptiveness>>(inp.v.t);
+ auto &mods = semantics::OmpGetModifiers(inp.v);
+ auto *m0 = semantics::OmpGetUniqueModifier<parser::OmpPrescriptiveness>(mods);
auto &t1 = std::get<parser::ScalarIntExpr>(inp.v.t);
- return NumTasks{{/*Prescriptiveness=*/maybeApply(convert, t0),
+ return NumTasks{{/*Prescriptiveness=*/maybeApplyToV(makePrescriptiveness, m0),
/*NumTasks=*/makeExpr(t1, semaCtx)}};
}
diff --git a/flang/lib/Lower/OpenMP/Clauses.h b/flang/lib/Lower/OpenMP/Clauses.h
index 562685e43c13bf..65282d243d87af 100644
--- a/flang/lib/Lower/OpenMP/Clauses.h
+++ b/flang/lib/Lower/OpenMP/Clauses.h
@@ -176,6 +176,7 @@ using DefinedOperator = tomp::type::DefinedOperatorT<IdTy, ExprTy>;
using ProcedureDesignator = tomp::type::ProcedureDesignatorT<IdTy, ExprTy>;
using ReductionOperator = tomp::type::ReductionIdentifierT<IdTy, ExprTy>;
using DependenceType = tomp::type::DependenceType;
+using Prescriptiveness = tomp::type::Prescriptiveness;
// "Requires" clauses are handled early on, and the aggregated information
// is stored in the Symbol details of modules, programs, and subprograms.
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 686f1c5d69c2ea..023cbb31fb9b65 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -176,6 +176,9 @@ TYPE_PARSER(construct<OmpOrderingModifier>(
"NONMONOTONIC" >> pure(OmpOrderingModifier::Value::Nonmonotonic) ||
"SIMD" >> pure(OmpOrderingModifier::Value::Simd)))
+TYPE_PARSER(construct<OmpPrescriptiveness>(
+ "STRICT" >> pure(OmpPrescriptiveness::Value::Strict)))
+
TYPE_PARSER(construct<OmpReductionModifier>(
"INSCAN" >> pure(OmpReductionModifier::Value::Inscan) ||
"TASK" >> pure(OmpReductionModifier::Value::Task) ||
@@ -213,6 +216,11 @@ TYPE_PARSER(sourced(construct<OmpAllocateClause::Modifier>(sourced(
TYPE_PARSER(sourced(
construct<OmpDefaultmapClause::Modifier>(Parser<OmpVariableCategory>{})))
+TYPE_PARSER(sourced(construct<OmpDependClause::TaskDep::Modifier>(sourced(
+ construct<OmpDependClause::TaskDep::Modifier>(Parser<OmpIterator>{}) ||
+ construct<OmpDependClause::TaskDep::Modifier>(
+ Parser<OmpTaskDependenceType>{})))))
+
TYPE_PARSER(
sourced(construct<OmpDeviceClause::Modifier>(Parser<OmpDeviceModifier>{})))
@@ -221,6 +229,9 @@ TYPE_PARSER(sourced(construct<OmpFromClause::Modifier>(
construct<OmpFromClause::Modifier>(Parser<OmpMapper>{}) ||
construct<OmpFromClause::Modifier>(Parser<OmpIterator>{})))))
+TYPE_PARSER(sourced(
+ construct<OmpGrainsizeClause::Modifier>(Parser<OmpPrescriptiveness>{})))
+
TYPE_PARSER(sourced(construct<OmpMapClause::Modifier>(
sourced(construct<OmpMapClause::Modifier>(Parser<OmpMapTypeModifier>{}) ||
construct<OmpMapClause::Modifier>(Parser<OmpMapper>{}) ||
@@ -230,6 +241,9 @@ TYPE_PARSER(sourced(construct<OmpMapClause::Modifier>(
TYPE_PARSER(
sourced(construct<OmpOrderClause::Modifier>(Parser<OmpOrderModifier>{})))
+TYPE_PARSER(sourced(
+ construct<OmpNumTasksClause::Modifier>(Parser<OmpPrescriptiveness>{})))
+
TYPE_PARSER(sourced(construct<OmpReductionClause::Modifier>(sourced(
construct<OmpReductionClause::Modifier>(Parser<OmpReductionModifier>{}) ||
construct<OmpReductionClause::Modifier>(
@@ -382,10 +396,16 @@ TYPE_PARSER(construct<OmpDoacross>(
TYPE_CONTEXT_PARSER("Omp Depend clause"_en_US,
construct<OmpDependClause>(
+ // Try to parse OmpDoacross first, because TaskDep will succeed on
+ // "sink: xxx", interpreting it to not have any modifiers, and "sink"
+ // being an OmpObject. Parsing of the TaskDep variant will stop right
+ // after the "sink", leaving the ": xxx" unvisited.
+ construct<OmpDependClause>(Parser<OmpDoacross>{}) ||
+ // Parse TaskDep after Doacross.
construct<OmpDependClause>(construct<OmpDependClause::TaskDep>(
- maybe(Parser<OmpIterator>{} / ","_tok),
- Parser<OmpTaskDependenceType>{} / ":", Parser<OmpObjectList>{})) ||
- construct<OmpDependClause>(Parser<OmpDoacross>{})))
+ maybe(nonemptyList(Parser<OmpDependClause::TaskDep::Modifier>{}) /
+ ": "),
+ Parser<OmpObjectList>{}))))
TYPE_CONTEXT_PARSER("Omp Doacross clause"_en_US,
construct<OmpDoacrossClause>(Parser<OmpDoacross>{}))
@@ -427,12 +447,12 @@ TYPE_PARSER(construct<OmpOrderClause>(
// OMP 5.2 12.6.1 grainsize([ prescriptiveness :] scalar-integer-expression)
TYPE_PARSER(construct<OmpGrainsizeClause>(
- maybe("STRICT" >> pure(OmpGrainsizeClause::Prescriptiveness::Strict) / ":"),
+ maybe(nonemptyList(Parser<OmpGrainsizeClause::Modifier>{}) / ":"),
scalarIntExpr))
// OMP 5.2 12.6.2 num_tasks([ prescriptiveness :] scalar-integer-expression)
TYPE_PARSER(construct<OmpNumTasksClause>(
- maybe("STRICT" >> pure(OmpNumTasksClause::Prescriptiveness::Strict) / ":"),
+ maybe(nonemptyList(Parser<OmpNumTasksClause::Modifier>{}) / ":"),
scalarIntExpr))
TYPE_PARSER(
diff --git a/flang/lib/Parser/parse-tree.cpp b/flang/lib/Parser/parse-tree.cpp
index 24b2902f286f4b..a414f226058e3e 100644
--- a/flang/lib/Parser/parse-tree.cpp
+++ b/flang/lib/Parser/parse-tree.cpp
@@ -267,7 +267,18 @@ OmpDependenceType::Value OmpDoacross::GetDepType() const {
}
OmpTaskDependenceType::Value OmpDependClause::TaskDep::GetTaskDepType() const {
- return std::get<parser::OmpTaskDependenceType>(t).v;
+ using Modifier = OmpDependClause::TaskDep::Modifier;
+ auto &modifiers{std::get<std::optional<std::list<Modifier>>>(t)};
+ if (modifiers) {
+ for (auto &m : *modifiers) {
+ if (auto *dep{std::get_if<OmpTaskDependenceType>(&m.u)}) {
+ return dep->v;
+ }
+ }
+ llvm_unreachable("expecting OmpTaskDependenceType in TaskDep");
+ } else {
+ llvm_unreachable("expecting modifiers on OmpDependClause::TaskDep");
+ }
}
} // namespace Fortran::parser
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index eee1420500ce2c..bde0e18d1d4c06 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2171,13 +2171,13 @@ class UnparseVisitor {
Walk(std::get<OmpOrderClause::Ordering>(x.t));
}
void Unparse(const OmpGrainsizeClause &x) {
- Walk(std::get<std::optional<OmpGrainsizeClause::Prescriptiveness>>(x.t),
- ":");
+ using Modifier = OmpGrainsizeClause::Modifier;
+ Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
Walk(std::get<ScalarIntExpr>(x.t));
}
void Unparse(const OmpNumTasksClause &x) {
- Walk(
- std::get<std::optional<OmpNumTasksClause::Prescriptiveness>>(x.t), ":");
+ using Modifier = OmpNumTasksClause::Modifier;
+ Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
Walk(std::get<ScalarIntExpr>(x.t));
}
void Unparse(const OmpDoacross::Sink &x) {
@@ -2186,8 +2186,8 @@ class UnparseVisitor {
}
void Unparse(const OmpDoacross::Source &) { Word("SOURCE"); }
void Unparse(const OmpDependClause::TaskDep &x) {
- Walk(std::get<OmpTaskDependenceType>(x.t));
- Put(":");
+ using Modifier = OmpDependClause::TaskDep::Modifier;
+ Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
Walk(std::get<OmpObjectList>(x.t));
}
void Unparse(const OmpDefaultmapClause &x) {
@@ -2853,9 +2853,7 @@ class UnparseVisitor {
WALK_NESTED_ENUM(OmpCancelType, Type) // OMP cancel-type
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
+ WALK_NESTED_ENUM(OmpPrescriptiveness, Value) // OMP prescriptiveness
WALK_NESTED_ENUM(OmpMapType, Value) // OMP map-type
WALK_NESTED_ENUM(OmpMapTypeModifier, Value) // OMP map-type-modifier
#undef WALK_NESTED_ENUM
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 4f429710318663..e1c37bffc97506 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -3725,18 +3725,13 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Depend &x) {
}
}
}
- if (std::get<std::optional<parser::OmpIterator>>(taskDep->t)) {
- unsigned allowedInVersion{50};
- if (version < allowedInVersion) {
- context_.Say(GetContext().clauseSource,
- "Iterator modifiers are not supported in %s, %s"_warn_en_US,
- ThisVersion(version), TryVersion(allowedInVersion));
- } else {
+ if (OmpVerifyModifiers(*taskDep, llvm::omp::OMPC_depend,
+ GetContext().clauseSource, context_)) {
+ auto &modifiers{OmpGetModifiers(*taskDep)};
+ if (OmpGetUniqueModifier<parser::OmpIterator>(modifiers)) {
if (dir == llvm::omp::OMPD_depobj) {
context_.Say(GetContext().clauseSource,
- "An iterator-modifier may specify multiple locators, "
- "a DEPEND clause on a DEPOBJ construct must only specify "
- "one locator"_warn_en_US);
+ "An iterator-modifier may specify multiple locators, a DEPEND clause on a DEPOBJ construct must only specify one locator"_warn_en_US);
}
}
}
diff --git a/flang/lib/Semantics/openmp-modifiers.cpp b/flang/lib/Semantics/openmp-modifiers.cpp
index 97227bfef0ea54..e384b0270e6eae 100644
--- a/flang/lib/Semantics/openmp-modifiers.cpp
+++ b/flang/lib/Semantics/openmp-modifiers.cpp
@@ -321,6 +321,22 @@ const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpOrderingModifier>() {
return desc;
}
+template <>
+const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpPrescriptiveness>() {
+ static const OmpModifierDescriptor desc{
+ /*name=*/"prescriptiveness",
+ /*props=*/
+ {
+ {51, {OmpProperty::Unique}},
+ },
+ /*clauses=*/
+ {
+ {51, {Clause::OMPC_grainsize, Clause::OMPC_num_tasks}},
+ },
+ };
+ return desc;
+}
+
template <>
const OmpModifierDescriptor &
OmpGetDescriptor<parser::OmpReductionIdentifier>() {
@@ -363,11 +379,12 @@ const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpTaskDependenceType>() {
/*name=*/"task-dependence-type",
/*props=*/
{
- {52, {OmpProperty::Required, OmpProperty::Ultimate}},
+ {45, {OmpProperty::Required, OmpProperty::Ultimate}},
},
/*clauses=*/
{
- {52, {Clause::OMPC_depend, Clause::OMPC_update}},
+ {45, {Clause::OMPC_depend}},
+ {51, {Clause::OMPC_depend, Clause::OMPC_update}},
},
};
return desc;
diff --git a/flang/test/Parser/OpenMP/depobj-construct.f90 b/flang/test/Parser/OpenMP/depobj-construct.f90
index 51726a5adf99ec..f186c82a2ccc30 100644
--- a/flang/test/Parser/OpenMP/depobj-construct.f90
+++ b/flang/test/Parser/OpenMP/depobj-construct.f90
@@ -8,14 +8,14 @@ subroutine f00
!UNPARSE: SUBROUTINE f00
!UNPARSE: INTEGER x, y
-!UNPARSE: !$OMP DEPOBJ(x) DEPEND(IN:y)
+!UNPARSE: !$OMP DEPOBJ(x) DEPEND(IN: y)
!UNPARSE: END SUBROUTINE
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPDepobjConstruct
!PARSE-TREE: | Verbatim
!PARSE-TREE: | OmpObject -> Designator -> DataRef -> Name = 'x'
!PARSE-TREE: | OmpClause -> Depend -> OmpDependClause -> TaskDep
-!PARSE-TREE: | | OmpTaskDependenceType -> Value = In
+!PARSE-TREE: | | Modifier -> OmpTaskDependenceType -> Value = In
!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'y'
subroutine f01
diff --git a/flang/test/Parser/OpenMP/taskloop.f90 b/flang/test/Parser/OpenMP/taskloop.f90
index a9c361046bd5f5..f053aa7f0cff37 100644
--- a/flang/test/Parser/OpenMP/taskloop.f90
+++ b/flang/test/Parser/OpenMP/taskloop.f90
@@ -4,11 +4,11 @@
subroutine parallel_work
integer :: i
-!CHECK: !$OMP TASKLOOP GRAINSIZE(STRICT:500_4)
+!CHECK: !$OMP TASKLOOP GRAINSIZE(STRICT: 500_4)
!PARSE-TREE: OmpBeginLoopDirective
!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = taskloop
!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Grainsize -> OmpGrainsizeClause
-!PARSE-TREE-NEXT: Prescriptiveness = Strict
+!PARSE-TREE-NEXT: Modifier -> OmpPrescriptiveness -> Value = Strict
!PARSE-TREE-NEXT: Scalar -> Integer -> Expr = '500_4'
!$omp taskloop grainsize(strict: 500)
do i=1,10000
@@ -27,11 +27,11 @@ subroutine parallel_work
end do
!$omp end taskloop
-!CHECK: !$OMP TASKLOOP NUM_TASKS(STRICT:500_4)
+!CHECK: !$OMP TASKLOOP NUM_TASKS(STRICT: 500_4)
!PARSE-TREE: OmpBeginLoopDirective
!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = taskloop
!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> NumTasks -> OmpNumTasksClause
-!PARSE-TREE-NEXT: Prescriptiveness = Strict
+!PARSE-TREE-NEXT: Modifier -> OmpPrescriptiveness -> Value = Strict
!PARSE-TREE-NEXT: Scalar -> Integer -> Expr = '500_4'
!$omp taskloop num_tasks(strict: 500)
do i=1,10000
diff --git a/flang/test/Semantics/OpenMP/depend05.f90 b/flang/test/Semantics/OpenMP/depend05.f90
index 53fd82bd08a9eb..3ca091ef3187d1 100644
--- a/flang/test/Semantics/OpenMP/depend05.f90
+++ b/flang/test/Semantics/OpenMP/depend05.f90
@@ -2,7 +2,7 @@
subroutine f00(x)
integer :: x(10)
-!WARNING: Iterator modifiers are not supported in OpenMP v4.5, try -fopenmp-version=50
+!WARNING: 'iterator' modifier is not supported in OpenMP v4.5, try -fopenmp-version=50
!$omp task depend(iterator(i = 1:10), in: x(i))
x = 0
!$omp end task
diff --git a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
index 07efd6fd4e9da4..67632fb79f8aac 100644
--- a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
+++ b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
@@ -242,6 +242,7 @@ ENUM(MotionExpectation, Present);
// V5.2: [15.9.1] `task-dependence-type` modifier
ENUM(DependenceType, Depobj, In, Inout, Inoutset, Mutexinoutset, Out, Sink,
Source);
+ENUM(Prescriptiveness, Strict);
template <typename I, typename E> //
struct LoopIterationT {
@@ -643,7 +644,7 @@ struct FullT {
// V5.2: [12.6.1] `grainsize` clause
template <typename T, typename I, typename E> //
struct GrainsizeT {
- ENUM(Prescriptiveness, Strict);
+ using Prescriptiveness = type::Prescriptiveness;
using GrainSize = E;
using TupleTrait = std::true_type;
std::tuple<OPT(Prescriptiveness), GrainSize> t;
@@ -876,8 +877,8 @@ struct NowaitT {
// V5.2: [12.6.2] `num_tasks` clause
template <typename T, typename I, typename E> //
struct NumTasksT {
+ using Prescriptiveness = type::Prescriptiveness;
using NumTasks = E;
- ENUM(Prescriptiveness, Strict);
using TupleTrait = std::true_type;
std::tuple<OPT(Prescriptiveness), NumTasks> t;
};
More information about the flang-commits
mailing list