Skip to content

[flang][OpenMP] Use new modifiers in IF/LASTPRIVATE #118128

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 13 commits into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion flang/examples/FeatureList/FeatureList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,8 @@ struct NodeVisitor {
READ_FEATURE(OmpPrescriptiveness)
READ_FEATURE(OmpPrescriptiveness::Value)
READ_FEATURE(OmpIfClause)
READ_FEATURE(OmpIfClause::DirectiveNameModifier)
READ_FEATURE(OmpIfClause::Modifier)
READ_FEATURE(OmpDirectiveNameModifier)
READ_FEATURE(OmpLinearClause)
READ_FEATURE(OmpLinearClause::WithModifier)
READ_FEATURE(OmpLinearClause::WithoutModifier)
Expand Down
5 changes: 3 additions & 2 deletions flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "FlangOmpReportVisitor.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Frontend/OpenMP/OMP.h"

namespace Fortran {
namespace parser {
Expand Down Expand Up @@ -238,9 +239,9 @@ void OpenMPCounterVisitor::Post(const OmpScheduleClause::Kind &c) {
clauseDetails +=
"type=" + std::string{OmpScheduleClause::EnumToString(c)} + ";";
}
void OpenMPCounterVisitor::Post(const OmpIfClause::DirectiveNameModifier &c) {
void OpenMPCounterVisitor::Post(const OmpDirectiveNameModifier &c) {
clauseDetails +=
"name_modifier=" + std::string{OmpIfClause::EnumToString(c)} + ";";
"name_modifier=" + llvm::omp::getOpenMPDirectiveName(c.v).str() + ";";
}
void OpenMPCounterVisitor::Post(const OmpCancelType::Type &c) {
clauseDetails += "type=" + std::string{OmpCancelType::EnumToString(c)} + ";";
Expand Down
2 changes: 1 addition & 1 deletion flang/examples/FlangOmpReport/FlangOmpReportVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ struct OpenMPCounterVisitor {
void Post(const OmpTaskDependenceType::Value &c);
void Post(const OmpMapType::Value &c);
void Post(const OmpScheduleClause::Kind &c);
void Post(const OmpIfClause::DirectiveNameModifier &c);
void Post(const OmpDirectiveNameModifier &c);
void Post(const OmpCancelType::Type &c);
void Post(const OmpClause &c);
void PostClauseCommon(const ClauseInfo &ci);
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 @@ -550,10 +550,13 @@ class ParseTreeDumper {
NODE(OmpFromClause, Modifier)
NODE(parser, OmpExpectation)
NODE_ENUM(OmpExpectation, Value)
NODE(parser, OmpDirectiveNameModifier)
NODE(parser, OmpIfClause)
NODE_ENUM(OmpIfClause, DirectiveNameModifier)
NODE_ENUM(OmpLastprivateClause, LastprivateModifier)
NODE(OmpIfClause, Modifier)
NODE(parser, OmpLastprivateClause)
NODE(OmpLastprivateClause, Modifier)
NODE(parser, OmpLastprivateModifier)
NODE_ENUM(OmpLastprivateModifier, Value)
NODE(parser, OmpLinearClause)
NODE(OmpLinearClause, WithModifier)
NODE(OmpLinearClause, WithoutModifier)
Expand Down
50 changes: 41 additions & 9 deletions flang/include/flang/Parser/parse-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -3558,6 +3558,23 @@ struct OmpDeviceModifier {
WRAPPER_CLASS_BOILERPLATE(OmpDeviceModifier, Value);
};

// Ref: [5.2:72-73,230-323], in 4.5-5.1 it's scattered over individual
// directives that allow the IF clause.
//
// directive-name-modifier ->
// PARALLEL | TARGET | TARGET DATA |
// TARGET ENTER DATA | TARGET EXIT DATA |
// TARGET UPDATE | TASK | TASKLOOP | // since 4.5
// CANCEL[*] | SIMD | // since 5.0
// TEAMS // since 5.2
//
// [*] The IF clause is allowed on CANCEL in OpenMP 4.5, but only without
// the directive-name-modifier. For the sake of uniformity CANCEL can be
// considered a valid value in 4.5 as well.
struct OmpDirectiveNameModifier {
WRAPPER_CLASS_BOILERPLATE(OmpDirectiveNameModifier, llvm::omp::Directive);
};

// Ref: [5.1:205-209], [5.2:166-168]
//
// motion-modifier ->
Expand All @@ -3581,6 +3598,15 @@ struct OmpIterator {
WRAPPER_CLASS_BOILERPLATE(OmpIterator, std::list<OmpIteratorSpecifier>);
};

// Ref: [5.0:288-290], [5.1:321-322], [5.2:115-117]
//
// lastprivate-modifier ->
// CONDITIONAL // since 5.0
struct OmpLastprivateModifier {
ENUM_CLASS(Value, Conditional)
WRAPPER_CLASS_BOILERPLATE(OmpLastprivateModifier, Value);
};

// Ref: [4.5:207-210], [5.0:290-293], [5.1:323-325], [5.2:117-120]
//
// linear-modifier ->
Expand Down Expand Up @@ -3913,12 +3939,16 @@ struct OmpGrainsizeClause {
std::tuple<MODIFIERS(), ScalarIntExpr> t;
};

// 2.12 if-clause -> IF ([ directive-name-modifier :] scalar-logical-expr)
// Ref: [5.2:72-73], in 4.5-5.1 it's scattered over individual directives
// that allow the IF clause.
//
// if-clause ->
// IF([directive-name-modifier:]
// scalar-logical-expression) // since 4.5
struct OmpIfClause {
TUPLE_CLASS_BOILERPLATE(OmpIfClause);
ENUM_CLASS(DirectiveNameModifier, Parallel, Simd, Target, TargetData,
TargetEnterData, TargetExitData, TargetUpdate, Task, Taskloop, Teams)
std::tuple<std::optional<DirectiveNameModifier>, ScalarLogicalExpr> t;
MODIFIER_BOILERPLATE(OmpDirectiveNameModifier);
std::tuple<MODIFIERS(), ScalarLogicalExpr> t;
};

// OMP 5.0 2.19.5.6 in_reduction-clause -> IN_REDUCTION (reduction-identifier:
Expand All @@ -3928,13 +3958,15 @@ struct OmpInReductionClause {
std::tuple<OmpReductionIdentifier, OmpObjectList> t;
};

// OMP 5.0 2.19.4.5 lastprivate-clause ->
// LASTPRIVATE ([lastprivate-modifier :] list)
// lastprivate-modifier -> CONDITIONAL
// Ref: [4.5:199-201], [5.0:288-290], [5.1:321-322], [5.2:115-117]
//
// lastprivate-clause ->
// LASTPRIVATE(list) | // since 4.5
// LASTPRIVATE([lastprivate-modifier:] list) // since 5.0
struct OmpLastprivateClause {
TUPLE_CLASS_BOILERPLATE(OmpLastprivateClause);
ENUM_CLASS(LastprivateModifier, Conditional);
std::tuple<std::optional<LastprivateModifier>, OmpObjectList> t;
MODIFIER_BOILERPLATE(OmpLastprivateModifier);
std::tuple<MODIFIERS(), OmpObjectList> t;
};

// 2.15.3.7 linear-clause -> LINEAR (linear-list[ : linear-step])
Expand Down
2 changes: 2 additions & 0 deletions flang/include/flang/Semantics/openmp-modifiers.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,10 @@ DECLARE_DESCRIPTOR(parser::OmpAllocatorSimpleModifier);
DECLARE_DESCRIPTOR(parser::OmpChunkModifier);
DECLARE_DESCRIPTOR(parser::OmpDependenceType);
DECLARE_DESCRIPTOR(parser::OmpDeviceModifier);
DECLARE_DESCRIPTOR(parser::OmpDirectiveNameModifier);
DECLARE_DESCRIPTOR(parser::OmpExpectation);
DECLARE_DESCRIPTOR(parser::OmpIterator);
DECLARE_DESCRIPTOR(parser::OmpLastprivateModifier);
DECLARE_DESCRIPTOR(parser::OmpLinearModifier);
DECLARE_DESCRIPTOR(parser::OmpMapper);
DECLARE_DESCRIPTOR(parser::OmpMapType);
Expand Down
36 changes: 11 additions & 25 deletions flang/lib/Lower/OpenMP/Clauses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -825,27 +825,13 @@ Holds make(const parser::OmpClause::Holds &inp,
If make(const parser::OmpClause::If &inp,
semantics::SemanticsContext &semaCtx) {
// inp.v -> parser::OmpIfClause
using wrapped = parser::OmpIfClause;

CLAUSET_ENUM_CONVERT( //
convert, wrapped::DirectiveNameModifier, llvm::omp::Directive,
// clang-format off
MS(Parallel, OMPD_parallel)
MS(Simd, OMPD_simd)
MS(Target, OMPD_target)
MS(TargetData, OMPD_target_data)
MS(TargetEnterData, OMPD_target_enter_data)
MS(TargetExitData, OMPD_target_exit_data)
MS(TargetUpdate, OMPD_target_update)
MS(Task, OMPD_task)
MS(Taskloop, OMPD_taskloop)
MS(Teams, OMPD_teams)
// clang-format on
);
auto &t0 = std::get<std::optional<wrapped::DirectiveNameModifier>>(inp.v.t);
auto &mods = semantics::OmpGetModifiers(inp.v);
auto *m0 =
semantics::OmpGetUniqueModifier<parser::OmpDirectiveNameModifier>(mods);
auto &t1 = std::get<parser::ScalarLogicalExpr>(inp.v.t);
return If{{/*DirectiveNameModifier=*/maybeApply(convert, t0),
/*IfExpression=*/makeExpr(t1, semaCtx)}};
return If{
{/*DirectiveNameModifier=*/maybeApplyToV([](auto &&s) { return s; }, m0),
/*IfExpression=*/makeExpr(t1, semaCtx)}};
}

// Inbranch: empty
Expand Down Expand Up @@ -889,20 +875,20 @@ IsDevicePtr make(const parser::OmpClause::IsDevicePtr &inp,
Lastprivate make(const parser::OmpClause::Lastprivate &inp,
semantics::SemanticsContext &semaCtx) {
// inp.v -> parser::OmpLastprivateClause
using wrapped = parser::OmpLastprivateClause;

CLAUSET_ENUM_CONVERT( //
convert, parser::OmpLastprivateClause::LastprivateModifier,
convert, parser::OmpLastprivateModifier::Value,
Lastprivate::LastprivateModifier,
// clang-format off
MS(Conditional, Conditional)
// clang-format on
);

auto &t0 = std::get<std::optional<wrapped::LastprivateModifier>>(inp.v.t);
auto &mods = semantics::OmpGetModifiers(inp.v);
auto *m0 =
semantics::OmpGetUniqueModifier<parser::OmpLastprivateModifier>(mods);
auto &t1 = std::get<parser::OmpObjectList>(inp.v.t);

return Lastprivate{{/*LastprivateModifier=*/maybeApply(convert, t0),
return Lastprivate{{/*LastprivateModifier=*/maybeApplyToV(convert, m0),
/*List=*/makeObjects(t1, semaCtx)}};
}

Expand Down
1 change: 1 addition & 0 deletions flang/lib/Parser/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ add_flang_library(FortranParser
LINK_COMPONENTS
Support
FrontendOpenACC
FrontendOpenMP

DEPENDS
omp_gen
Expand Down
73 changes: 55 additions & 18 deletions flang/lib/Parser/openmp-parsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,58 @@
#include "token-parsers.h"
#include "type-parser-implementation.h"
#include "flang/Parser/parse-tree.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Frontend/OpenMP/OMP.h"

// OpenMP Directives and Clauses
namespace Fortran::parser {

constexpr auto startOmpLine = skipStuffBeforeStatement >> "!$OMP "_sptok;
constexpr auto endOmpLine = space >> endOfLine;

/// Parse OpenMP directive name (this includes compound directives).
struct OmpDirectiveNameParser {
using resultType = llvm::omp::Directive;
using Token = TokenStringMatch<false, false>;

std::optional<resultType> Parse(ParseState &state) const {
for (const NameWithId &nid : directives()) {
if (attempt(Token(nid.first.data())).Parse(state)) {
return nid.second;
}
}
return std::nullopt;
}

private:
using NameWithId = std::pair<std::string, llvm::omp::Directive>;

llvm::iterator_range<const NameWithId *> directives() const;
void initTokens(NameWithId *) const;
};

llvm::iterator_range<const OmpDirectiveNameParser::NameWithId *>
OmpDirectiveNameParser::directives() const {
static NameWithId table[llvm::omp::Directive_enumSize];
[[maybe_unused]] static bool init = (initTokens(table), true);
return llvm::make_range(std::cbegin(table), std::cend(table));
}

void OmpDirectiveNameParser::initTokens(NameWithId *table) const {
for (size_t i{0}, e{llvm::omp::Directive_enumSize}; i != e; ++i) {
auto id{static_cast<llvm::omp::Directive>(i)};
llvm::StringRef name{llvm::omp::getOpenMPDirectiveName(id)};
table[i] = std::make_pair(name.str(), id);
}
// Sort the table with respect to the directive name length in a descending
// order. This is to make sure that longer names are tried first, before
// any potential prefix (e.g. "target update" before "target").
std::sort(table, table + llvm::omp::Directive_enumSize,
[](auto &a, auto &b) { return a.first.size() > b.first.size(); });
}

template <typename Clause, typename Separator> struct ModifierList {
constexpr ModifierList(Separator sep) : sep_(sep) {}
constexpr ModifierList(const ModifierList &) = default;
Expand Down Expand Up @@ -136,6 +181,9 @@ TYPE_PARSER(construct<OmpIterator>( //
"ITERATOR" >>
parenthesized(nonemptyList(sourced(Parser<OmpIteratorSpecifier>{})))))

TYPE_PARSER(construct<OmpLastprivateModifier>(
"CONDITIONAL" >> pure(OmpLastprivateModifier::Value::Conditional)))

// 2.15.3.7 LINEAR (linear-list: linear-step)
// linear-list -> list | modifier(list)
// linear-modifier -> REF | VAL | UVAL
Expand Down Expand Up @@ -232,6 +280,11 @@ TYPE_PARSER(sourced(construct<OmpFromClause::Modifier>(
TYPE_PARSER(sourced(
construct<OmpGrainsizeClause::Modifier>(Parser<OmpPrescriptiveness>{})))

TYPE_PARSER(sourced(construct<OmpIfClause::Modifier>(OmpDirectiveNameParser{})))

TYPE_PARSER(sourced(construct<OmpLastprivateClause::Modifier>(
Parser<OmpLastprivateModifier>{})))

TYPE_PARSER(sourced(construct<OmpMapClause::Modifier>(
sourced(construct<OmpMapClause::Modifier>(Parser<OmpMapTypeModifier>{}) ||
construct<OmpMapClause::Modifier>(Parser<OmpMapper>{}) ||
Expand Down Expand Up @@ -345,22 +398,7 @@ TYPE_PARSER(construct<OmpDeviceTypeClause>(

// 2.12 IF (directive-name-modifier: scalar-logical-expr)
TYPE_PARSER(construct<OmpIfClause>(
maybe(
("PARALLEL" >> pure(OmpIfClause::DirectiveNameModifier::Parallel) ||
"SIMD" >> pure(OmpIfClause::DirectiveNameModifier::Simd) ||
"TARGET ENTER DATA" >>
pure(OmpIfClause::DirectiveNameModifier::TargetEnterData) ||
"TARGET EXIT DATA" >>
pure(OmpIfClause::DirectiveNameModifier::TargetExitData) ||
"TARGET DATA" >>
pure(OmpIfClause::DirectiveNameModifier::TargetData) ||
"TARGET UPDATE" >>
pure(OmpIfClause::DirectiveNameModifier::TargetUpdate) ||
"TARGET" >> pure(OmpIfClause::DirectiveNameModifier::Target) ||
"TASK"_id >> pure(OmpIfClause::DirectiveNameModifier::Task) ||
"TASKLOOP" >> pure(OmpIfClause::DirectiveNameModifier::Taskloop) ||
"TEAMS" >> pure(OmpIfClause::DirectiveNameModifier::Teams)) /
":"),
maybe(nonemptyList(Parser<OmpIfClause::Modifier>{}) / ":"),
scalarLogicalExpr))

TYPE_PARSER(construct<OmpReductionClause>(
Expand Down Expand Up @@ -460,8 +498,7 @@ TYPE_PARSER(

// OMP 5.0 2.19.4.5 LASTPRIVATE ([lastprivate-modifier :] list)
TYPE_PARSER(construct<OmpLastprivateClause>(
maybe("CONDITIONAL" >>
pure(OmpLastprivateClause::LastprivateModifier::Conditional) / ":"),
maybe(nonemptyList(Parser<OmpLastprivateClause::Modifier>{}) / ":"),
Parser<OmpObjectList>{}))

// OMP 5.2 11.7.1 BIND ( PARALLEL | TEAMS | THREAD )
Expand Down
15 changes: 8 additions & 7 deletions flang/lib/Parser/unparse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2074,6 +2074,9 @@ class UnparseVisitor {
},
x.u);
}
void Unparse(const OmpDirectiveNameModifier &x) {
Word(llvm::omp::getOpenMPDirectiveName(x.v));
}
void Unparse(const OmpIteratorSpecifier &x) {
Walk(std::get<TypeDeclarationStmt>(x.t));
Put(" = ");
Expand All @@ -2090,9 +2093,8 @@ class UnparseVisitor {
Put(")");
}
void Unparse(const OmpLastprivateClause &x) {
Walk(
std::get<std::optional<OmpLastprivateClause::LastprivateModifier>>(x.t),
":");
using Modifier = OmpLastprivateClause::Modifier;
Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
Walk(std::get<OmpObjectList>(x.t));
}
void Unparse(const OmpMapClause &x) {
Expand Down Expand Up @@ -2127,7 +2129,8 @@ class UnparseVisitor {
Walk(std::get<OmpObjectList>(x.t));
}
void Unparse(const OmpIfClause &x) {
Walk(std::get<std::optional<OmpIfClause::DirectiveNameModifier>>(x.t), ":");
using Modifier = OmpIfClause::Modifier;
Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
Walk(std::get<ScalarLogicalExpr>(x.t));
}
void Unparse(const OmpLinearClause::WithoutModifier &x) {
Expand Down Expand Up @@ -2837,8 +2840,7 @@ class UnparseVisitor {
WALK_NESTED_ENUM(OmpDefaultClause, DataSharingAttribute) // OMP default
WALK_NESTED_ENUM(OmpDefaultmapClause, ImplicitBehavior) // OMP defaultmap
WALK_NESTED_ENUM(OmpVariableCategory, Value) // OMP variable-category
WALK_NESTED_ENUM(
OmpLastprivateClause, LastprivateModifier) // OMP lastprivate-modifier
WALK_NESTED_ENUM(OmpLastprivateModifier, Value) // OMP lastprivate-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
Expand All @@ -2849,7 +2851,6 @@ class UnparseVisitor {
OmpDeviceTypeClause, DeviceTypeDescription) // OMP device_type
WALK_NESTED_ENUM(OmpReductionModifier, Value) // OMP reduction-modifier
WALK_NESTED_ENUM(OmpExpectation, Value) // OMP motion-expectation
WALK_NESTED_ENUM(OmpIfClause, DirectiveNameModifier) // OMP directive-modifier
WALK_NESTED_ENUM(OmpCancelType, Type) // OMP cancel-type
WALK_NESTED_ENUM(OmpOrderClause, Ordering) // OMP ordering
WALK_NESTED_ENUM(OmpOrderModifier, Value) // OMP order-modifier
Expand Down
Loading
Loading