Skip to content
6 changes: 4 additions & 2 deletions flang/examples/FeatureList/FeatureList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down
7 changes: 5 additions & 2 deletions flang/include/flang/Parser/dump-parse-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
42 changes: 30 additions & 12 deletions flang/include/flang/Parser/parse-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -3627,6 +3627,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 ->
Expand Down Expand Up @@ -3816,8 +3825,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;
};
Expand Down Expand Up @@ -3878,11 +3887,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)
Expand Down Expand Up @@ -3948,6 +3961,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 ->
Expand Down Expand Up @@ -4015,13 +4039,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 ->
Expand All @@ -4030,6 +4047,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;
};

Expand Down
1 change: 1 addition & 0 deletions flang/include/flang/Semantics/openmp-modifiers.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
55 changes: 26 additions & 29 deletions flang/lib/Lower/OpenMP/Clauses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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".

Expand Down Expand Up @@ -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( //
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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)}};
}

Expand Down
1 change: 1 addition & 0 deletions flang/lib/Lower/OpenMP/Clauses.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
30 changes: 25 additions & 5 deletions flang/lib/Parser/openmp-parsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) ||
Expand Down Expand Up @@ -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>{})))

Expand All @@ -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>{}) ||
Expand All @@ -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>(
Expand Down Expand Up @@ -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>{}))
Expand Down Expand Up @@ -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(
Expand Down
13 changes: 12 additions & 1 deletion flang/lib/Parser/parse-tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 7 additions & 9 deletions flang/lib/Parser/unparse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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) {
Expand Down Expand Up @@ -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
Expand Down
15 changes: 5 additions & 10 deletions flang/lib/Semantics/check-omp-structure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
Expand Down
Loading
Loading