Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 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
2 changes: 2 additions & 0 deletions flang/include/flang/Lower/OpenMP/Clauses.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ using Depend = tomp::clause::DependT<TypeTy, IdTy, ExprTy>;
using Destroy = tomp::clause::DestroyT<TypeTy, IdTy, ExprTy>;
using Detach = tomp::clause::DetachT<TypeTy, IdTy, ExprTy>;
using Device = tomp::clause::DeviceT<TypeTy, IdTy, ExprTy>;
using DeviceSafesync = tomp::clause::DeviceSafesyncT<TypeTy, IdTy, ExprTy>;
using DeviceType = tomp::clause::DeviceTypeT<TypeTy, IdTy, ExprTy>;
using DistSchedule = tomp::clause::DistScheduleT<TypeTy, IdTy, ExprTy>;
using Doacross = tomp::clause::DoacrossT<TypeTy, IdTy, ExprTy>;
Expand Down Expand Up @@ -282,6 +283,7 @@ using Replayable = tomp::clause::ReplayableT<TypeTy, IdTy, ExprTy>;
using ReverseOffload = tomp::clause::ReverseOffloadT<TypeTy, IdTy, ExprTy>;
using Safelen = tomp::clause::SafelenT<TypeTy, IdTy, ExprTy>;
using Schedule = tomp::clause::ScheduleT<TypeTy, IdTy, ExprTy>;
using SelfMaps = tomp::clause::SelfMapsT<TypeTy, IdTy, ExprTy>;
using SeqCst = tomp::clause::SeqCstT<TypeTy, IdTy, ExprTy>;
using Severity = tomp::clause::SeverityT<TypeTy, IdTy, ExprTy>;
using Shared = tomp::clause::SharedT<TypeTy, IdTy, ExprTy>;
Expand Down
6 changes: 6 additions & 0 deletions flang/include/flang/Parser/dump-parse-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,7 @@ class ParseTreeDumper {
NODE(OmpDeviceClause, Modifier)
NODE(parser, OmpDeviceModifier)
NODE_ENUM(OmpDeviceModifier, Value)
NODE(parser, OmpDeviceSafesyncClause)
NODE(parser, OmpDeviceTypeClause)
NODE_ENUM(OmpDeviceTypeClause, DeviceTypeDescription)
NODE(parser, OmpDirectiveName)
Expand All @@ -568,6 +569,7 @@ class ParseTreeDumper {
NODE(OmpDoacross, Sink)
NODE(OmpDoacross, Source)
NODE(parser, OmpDoacrossClause)
NODE(parser, OmpDynamicAllocatorsClause)
NODE(parser, OmpDynGroupprivateClause)
NODE(OmpDynGroupprivateClause, Modifier)
NODE(parser, OmpEndDirective)
Expand Down Expand Up @@ -661,9 +663,11 @@ class ParseTreeDumper {
NODE(parser, OmpRefModifier)
NODE_ENUM(OmpRefModifier, Value)
NODE(parser, OmpReplayableClause)
NODE(parser, OmpReverseOffloadClause)
NODE(parser, OmpScheduleClause)
NODE(OmpScheduleClause, Modifier)
NODE_ENUM(OmpScheduleClause, Kind)
NODE(parser, OmpSelfMapsClause)
NODE(parser, OmpSelfModifier)
NODE_ENUM(OmpSelfModifier, Value)
NODE(parser, OmpSeverityClause)
Expand Down Expand Up @@ -691,6 +695,8 @@ class ParseTreeDumper {
NODE(parser, OmpTransparentClause)
NODE(parser, OmpTypeNameList)
NODE(parser, OmpTypeSpecifier)
NODE(parser, OmpUnifiedAddressClause)
NODE(parser, OmpUnifiedSharedMemoryClause)
NODE(parser, OmpUpdateClause)
NODE(parser, OmpUseClause)
NODE(parser, OmpVariableCategory)
Expand Down
57 changes: 56 additions & 1 deletion flang/include/flang/Parser/parse-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ using IntConstantExpr = Integer<ConstantExpr>; // R1031
using ScalarLogicalExpr = Scalar<LogicalExpr>;
using ScalarIntExpr = Scalar<IntExpr>;
using ScalarIntConstantExpr = Scalar<IntConstantExpr>;
using ScalarLogicalConstantExpr = Scalar<Logical<ConstantExpr>>;
using ScalarDefaultCharExpr = Scalar<DefaultCharExpr>;
// R1030 default-char-constant-expr is used in the Standard only as part of
// scalar-default-char-constant-expr.
Expand Down Expand Up @@ -4417,6 +4418,14 @@ struct OmpDeviceClause {
std::tuple<MODIFIERS(), ScalarIntExpr> t;
};

// Ref: [6.0:356-362]
//
// device-safesync-clause ->
// DEVICE_SAFESYNC [(scalar-logical-const-expr)] // since 6.0
struct OmpDeviceSafesyncClause {
WRAPPER_CLASS_BOILERPLATE(OmpDeviceSafesyncClause, ScalarLogicalConstantExpr);
};

// Ref: [5.0:180-185], [5.1:210-216], [5.2:275]
//
// device-type-clause ->
Expand All @@ -4426,6 +4435,16 @@ struct OmpDeviceTypeClause {
WRAPPER_CLASS_BOILERPLATE(OmpDeviceTypeClause, DeviceTypeDescription);
};

// Ref: [5.0:60-63], [5.1:83-86], [5.2:212-213], [6.0:356-362]
//
// dynamic-allocators-clause ->
// DYNAMIC_ALLOCATORS // since 5.0
// [(scalar-logical-const-expr)] // since 6.0
struct OmpDynamicAllocatorsClause {
WRAPPER_CLASS_BOILERPLATE(
OmpDynamicAllocatorsClause, ScalarLogicalConstantExpr);
};

struct OmpDynGroupprivateClause {
TUPLE_CLASS_BOILERPLATE(OmpDynGroupprivateClause);
MODIFIER_BOILERPLATE(OmpAccessGroup, OmpPrescriptiveness);
Expand Down Expand Up @@ -4703,7 +4722,16 @@ struct OmpReductionClause {
// replayable-clause ->
// REPLAYABLE[(replayable-expression)] // since 6.0
struct OmpReplayableClause {
WRAPPER_CLASS_BOILERPLATE(OmpReplayableClause, Scalar<Logical<ConstantExpr>>);
WRAPPER_CLASS_BOILERPLATE(OmpReplayableClause, ScalarLogicalConstantExpr);
};

// Ref: [5.0:60-63], [5.1:83-86], [5.2:212-213], [6.0:356-362]
//
// reverse-offload-clause ->
// REVERSE_OFFLOAD // since 5.0
// [(scalar-logical-const-expr)] // since 6.0
struct OmpReverseOffloadClause {
WRAPPER_CLASS_BOILERPLATE(OmpReverseOffloadClause, ScalarLogicalConstantExpr);
};

// Ref: [4.5:56-63], [5.0:101-109], [5.1:126-133], [5.2:252-254]
Expand All @@ -4721,6 +4749,14 @@ struct OmpScheduleClause {
std::tuple<MODIFIERS(), Kind, std::optional<ScalarIntExpr>> t;
};

// ref: [6.0:361-362]
//
// self-maps-clause ->
// SELF_MAPS [(scalar-logical-const-expr)] // since 6.0
struct OmpSelfMapsClause {
WRAPPER_CLASS_BOILERPLATE(OmpSelfMapsClause, ScalarLogicalConstantExpr);
};

// REF: [5.2:217]
// severity-clause ->
// SEVERITY(warning|fatal)
Expand Down Expand Up @@ -4763,6 +4799,25 @@ struct OmpTransparentClause {
WRAPPER_CLASS_BOILERPLATE(OmpTransparentClause, ScalarIntExpr);
};

// Ref: [5.0:60-63], [5.1:83-86], [5.2:212-213], [6.0:356-362]
//
// unified-address-clause ->
// UNIFIED_ADDRESS // since 5.0
// [(scalar-logical-const-expr)] // since 6.0
struct OmpUnifiedAddressClause {
WRAPPER_CLASS_BOILERPLATE(OmpUnifiedAddressClause, ScalarLogicalConstantExpr);
};

// Ref: [5.0:60-63], [5.1:83-86], [5.2:212-213], [6.0:356-362]
//
// unified-shared-memory-clause ->
// UNIFIED_SHARED_MEMORY // since 5.0
// [(scalar-logical-const-expr)] // since 6.0
struct OmpUnifiedSharedMemoryClause {
WRAPPER_CLASS_BOILERPLATE(
OmpUnifiedSharedMemoryClause, ScalarLogicalConstantExpr);
};

// Ref: [5.0:254-255], [5.1:287-288], [5.2:321-322]
//
// In ATOMIC construct
Expand Down
80 changes: 71 additions & 9 deletions flang/lib/Lower/OpenMP/Clauses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,6 @@ MAKE_EMPTY_CLASS(AcqRel, AcqRel);
MAKE_EMPTY_CLASS(Acquire, Acquire);
MAKE_EMPTY_CLASS(Capture, Capture);
MAKE_EMPTY_CLASS(Compare, Compare);
MAKE_EMPTY_CLASS(DynamicAllocators, DynamicAllocators);
MAKE_EMPTY_CLASS(Full, Full);
MAKE_EMPTY_CLASS(Inbranch, Inbranch);
MAKE_EMPTY_CLASS(Mergeable, Mergeable);
Expand All @@ -235,13 +234,9 @@ MAKE_EMPTY_CLASS(OmpxBare, OmpxBare);
MAKE_EMPTY_CLASS(Read, Read);
MAKE_EMPTY_CLASS(Relaxed, Relaxed);
MAKE_EMPTY_CLASS(Release, Release);
MAKE_EMPTY_CLASS(ReverseOffload, ReverseOffload);
MAKE_EMPTY_CLASS(SeqCst, SeqCst);
MAKE_EMPTY_CLASS(SelfMaps, SelfMaps);
MAKE_EMPTY_CLASS(Simd, Simd);
MAKE_EMPTY_CLASS(Threads, Threads);
MAKE_EMPTY_CLASS(UnifiedAddress, UnifiedAddress);
MAKE_EMPTY_CLASS(UnifiedSharedMemory, UnifiedSharedMemory);
MAKE_EMPTY_CLASS(Unknown, Unknown);
MAKE_EMPTY_CLASS(Untied, Untied);
MAKE_EMPTY_CLASS(Weak, Weak);
Expand Down Expand Up @@ -745,6 +740,18 @@ Device make(const parser::OmpClause::Device &inp,
/*DeviceDescription=*/makeExpr(t1, semaCtx)}};
}

DeviceSafesync make(const parser::OmpClause::DeviceSafesync &inp,
semantics::SemanticsContext &semaCtx) {
// inp.v -> std::optional<parser::OmpDeviceSafesyncClause>
auto &&maybeRequired = maybeApply(
[&](const parser::OmpDeviceSafesyncClause &c) {
return makeExpr(c.v, semaCtx);
},
inp.v);

return DeviceSafesync{/*Required=*/std::move(maybeRequired)};
}

DeviceType make(const parser::OmpClause::DeviceType &inp,
semantics::SemanticsContext &semaCtx) {
// inp.v -> parser::OmpDeviceTypeClause
Expand Down Expand Up @@ -775,7 +782,18 @@ Doacross make(const parser::OmpClause::Doacross &inp,
return makeDoacross(inp.v.v, semaCtx);
}

// DynamicAllocators: empty
DynamicAllocators make(const parser::OmpClause::DynamicAllocators &inp,
semantics::SemanticsContext &semaCtx) {
// inp.v -> td::optional<arser::OmpDynamicAllocatorsClause>
auto &&maybeRequired = maybeApply(
[&](const parser::OmpDynamicAllocatorsClause &c) {
return makeExpr(c.v, semaCtx);
},
inp.v);

return DynamicAllocators{/*Required=*/std::move(maybeRequired)};
}


DynGroupprivate make(const parser::OmpClause::DynGroupprivate &inp,
semantics::SemanticsContext &semaCtx) {
Expand Down Expand Up @@ -1338,7 +1356,18 @@ Reduction make(const parser::OmpClause::Reduction &inp,

// Relaxed: empty
// Release: empty
// ReverseOffload: empty

ReverseOffload make(const parser::OmpClause::ReverseOffload &inp,
semantics::SemanticsContext &semaCtx) {
// inp.v -> std::optional<parser::OmpReverseOffloadClause>
auto &&maybeRequired = maybeApply(
[&](const parser::OmpReverseOffloadClause &c) {
return makeExpr(c.v, semaCtx);
},
inp.v);

return ReverseOffload{/*Required=*/std::move(maybeRequired)};
}

Safelen make(const parser::OmpClause::Safelen &inp,
semantics::SemanticsContext &semaCtx) {
Expand Down Expand Up @@ -1391,6 +1420,18 @@ Schedule make(const parser::OmpClause::Schedule &inp,

// SeqCst: empty

SelfMaps make(const parser::OmpClause::SelfMaps &inp,
semantics::SemanticsContext &semaCtx) {
// inp.v -> std::optional<parser::OmpSelfMapsClause>
auto &&maybeRequired = maybeApply(
[&](const parser::OmpSelfMapsClause &c) {
return makeExpr(c.v, semaCtx);
},
inp.v);

return SelfMaps{/*Required=*/std::move(maybeRequired)};
}

Severity make(const parser::OmpClause::Severity &inp,
semantics::SemanticsContext &semaCtx) {
// inp -> empty
Expand Down Expand Up @@ -1480,8 +1521,29 @@ To make(const parser::OmpClause::To &inp,
/*LocatorList=*/makeObjects(t3, semaCtx)}};
}

// UnifiedAddress: empty
// UnifiedSharedMemory: empty
UnifiedAddress make(const parser::OmpClause::UnifiedAddress &inp,
semantics::SemanticsContext &semaCtx) {
// inp.v -> std::optional<parser::OmpUnifiedAddressClause>
auto &&maybeRequired = maybeApply(
[&](const parser::OmpUnifiedAddressClause &c) {
return makeExpr(c.v, semaCtx);
},
inp.v);

return UnifiedAddress{/*Required=*/std::move(maybeRequired)};
}

UnifiedSharedMemory make(const parser::OmpClause::UnifiedSharedMemory &inp,
semantics::SemanticsContext &semaCtx) {
// inp.v -> std::optional<parser::OmpUnifiedSharedMemoryClause>
auto &&maybeRequired = maybeApply(
[&](const parser::OmpUnifiedSharedMemoryClause &c) {
return makeExpr(c.v, semaCtx);
},
inp.v);

return UnifiedSharedMemory{/*Required=*/std::move(maybeRequired)};
}

Uniform make(const parser::OmpClause::Uniform &inp,
semantics::SemanticsContext &semaCtx) {
Expand Down
17 changes: 13 additions & 4 deletions flang/lib/Parser/openmp-parsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1159,6 +1159,9 @@ TYPE_PARSER( //
construct<OmpDestroyClause>(Parser<OmpObject>{}))))) ||
"DEVICE" >> construct<OmpClause>(construct<OmpClause::Device>(
parenthesized(Parser<OmpDeviceClause>{}))) ||
"DEVICE_SAFESYNC" >>
construct<OmpClause>(construct<OmpClause::DeviceSafesync>(
maybe(parenthesized(scalarLogicalConstantExpr)))) ||
"DEVICE_TYPE" >> construct<OmpClause>(construct<OmpClause::DeviceType>(
parenthesized(Parser<OmpDeviceTypeClause>{}))) ||
"DIST_SCHEDULE" >>
Expand All @@ -1167,7 +1170,8 @@ TYPE_PARSER( //
"DOACROSS" >>
construct<OmpClause>(parenthesized(Parser<OmpDoacrossClause>{})) ||
"DYNAMIC_ALLOCATORS" >>
construct<OmpClause>(construct<OmpClause::DynamicAllocators>()) ||
construct<OmpClause>(construct<OmpClause::DynamicAllocators>(
maybe(parenthesized(scalarLogicalConstantExpr)))) ||
"DYN_GROUPPRIVATE" >>
construct<OmpClause>(construct<OmpClause::DynGroupprivate>(
parenthesized(Parser<OmpDynGroupprivateClause>{}))) ||
Expand Down Expand Up @@ -1279,12 +1283,15 @@ TYPE_PARSER( //
"REPLAYABLE" >> construct<OmpClause>(construct<OmpClause::Replayable>(
maybe(parenthesized(Parser<OmpReplayableClause>{})))) ||
"REVERSE_OFFLOAD" >>
construct<OmpClause>(construct<OmpClause::ReverseOffload>()) ||
construct<OmpClause>(construct<OmpClause::ReverseOffload>(
maybe(parenthesized(scalarLogicalConstantExpr)))) ||
"SAFELEN" >> construct<OmpClause>(construct<OmpClause::Safelen>(
parenthesized(scalarIntConstantExpr))) ||
"SCHEDULE" >> construct<OmpClause>(construct<OmpClause::Schedule>(
parenthesized(Parser<OmpScheduleClause>{}))) ||
"SEQ_CST" >> construct<OmpClause>(construct<OmpClause::SeqCst>()) ||
"SELF_MAPS" >> construct<OmpClause>(construct<OmpClause::SelfMaps>(
maybe(parenthesized(scalarLogicalConstantExpr)))) ||
"SEVERITY" >> construct<OmpClause>(construct<OmpClause::Severity>(
parenthesized(Parser<OmpSeverityClause>{}))) ||
"SHARED" >> construct<OmpClause>(construct<OmpClause::Shared>(
Expand Down Expand Up @@ -1312,9 +1319,11 @@ TYPE_PARSER( //
construct<OmpClause>(construct<OmpClause::UseDeviceAddr>(
parenthesized(Parser<OmpObjectList>{}))) ||
"UNIFIED_ADDRESS" >>
construct<OmpClause>(construct<OmpClause::UnifiedAddress>()) ||
construct<OmpClause>(construct<OmpClause::UnifiedAddress>(
maybe(parenthesized(scalarLogicalConstantExpr)))) ||
"UNIFIED_SHARED_MEMORY" >>
construct<OmpClause>(construct<OmpClause::UnifiedSharedMemory>()) ||
construct<OmpClause>(construct<OmpClause::UnifiedSharedMemory>(
maybe(parenthesized(scalarLogicalConstantExpr)))) ||
"UNIFORM" >> construct<OmpClause>(construct<OmpClause::Uniform>(
parenthesized(nonemptyList(name)))) ||
"UNTIED" >> construct<OmpClause>(construct<OmpClause::Untied>()) ||
Expand Down
46 changes: 37 additions & 9 deletions flang/lib/Semantics/check-omp-structure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1517,19 +1517,43 @@ void OmpStructureChecker::Leave(const parser::OpenMPDepobjConstruct &x) {
void OmpStructureChecker::Enter(const parser::OpenMPRequiresConstruct &x) {
const auto &dirName{x.v.DirName()};
PushContextAndClauseSets(dirName.source, dirName.v);
unsigned version{context_.langOptions().OpenMPVersion};

if (visitedAtomicSource_.empty()) {
return;
}
for (const parser::OmpClause &clause : x.v.Clauses().v) {
llvm::omp::Clause id{clause.Id()};
if (id == llvm::omp::Clause::OMPC_atomic_default_mem_order) {
parser::MessageFormattedText txt(
"REQUIRES directive with '%s' clause found lexically after atomic operation without a memory order clause"_err_en_US,
parser::ToUpperCaseLetters(llvm::omp::getOpenMPClauseName(id)));
parser::Message message(clause.source, txt);
message.Attach(visitedAtomicSource_, "Previous atomic construct"_en_US);
context_.Say(std::move(message));
if (!visitedAtomicSource_.empty()) {
parser::MessageFormattedText txt(
"REQUIRES directive with '%s' clause found lexically after atomic operation without a memory order clause"_err_en_US,
parser::ToUpperCaseLetters(llvm::omp::getOpenMPClauseName(id)));
parser::Message message(clause.source, txt);
message.Attach(visitedAtomicSource_, "Previous atomic construct"_en_US);
context_.Say(std::move(message));
}
} else {
bool hasArgument{common::visit(
[&](auto &&s) {
using TypeS = llvm::remove_cvref_t<decltype(s)>;
if constexpr ( //
std::is_same_v<TypeS, parser::OmpClause::DeviceSafesync> ||
std::is_same_v<TypeS, parser::OmpClause::DynamicAllocators> ||
std::is_same_v<TypeS, parser::OmpClause::ReverseOffload> ||
std::is_same_v<TypeS, parser::OmpClause::SelfMaps> ||
std::is_same_v<TypeS, parser::OmpClause::UnifiedAddress> ||
std::is_same_v<TypeS, parser::OmpClause::UnifiedSharedMemory>) {
return s.v.has_value();
} else {
return false;
}
},
clause.u)};
if (version < 60 && hasArgument) {
context_.Say(clause.source,
"An argument to %s is an %s feature, %s"_warn_en_US,
parser::ToUpperCaseLetters(
llvm::omp::getOpenMPClauseName(clause.Id())),
ThisVersion(60), TryVersion(60));
}
}
}
}
Expand Down Expand Up @@ -5172,6 +5196,10 @@ void OmpStructureChecker::Enter(
CheckAllowedRequiresClause(llvm::omp::Clause::OMPC_atomic_default_mem_order);
}

void OmpStructureChecker::Enter(const parser::OmpClause::DeviceSafesync &x) {
CheckAllowedRequiresClause(llvm::omp::Clause::OMPC_device_safesync);
}

void OmpStructureChecker::Enter(const parser::OmpClause::DynamicAllocators &x) {
CheckAllowedRequiresClause(llvm::omp::Clause::OMPC_dynamic_allocators);
}
Expand Down
Loading