Skip to content

[flang][OpenMP] Use new modifiers in DEPEND/GRAINSIZE/NUM_TASKS #117917

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Dec 2, 2024
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