Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 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
1 change: 1 addition & 0 deletions flang/include/flang/Lower/OpenMP/Clauses.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,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
5 changes: 5 additions & 0 deletions flang/include/flang/Parser/dump-parse-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,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 +662,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 +694,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
49 changes: 48 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 @@ -4426,6 +4427,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 +4714,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 +4741,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 +4791,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
68 changes: 59 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 @@ -775,7 +770,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 +1344,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 +1408,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 +1509,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
14 changes: 10 additions & 4 deletions flang/lib/Parser/openmp-parsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1167,7 +1167,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 +1280,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 +1316,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
41 changes: 32 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,42 @@ 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::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
24 changes: 21 additions & 3 deletions flang/lib/Semantics/resolve-directives.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,21 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
using RequiresClauses = WithOmpDeclarative::RequiresClauses;
PushContext(x.source, llvm::omp::Directive::OMPD_requires);

auto getArgument{[&](auto &&maybeClause) {
if (maybeClause) {
// Scalar<Logical<Constant<common::Indirection<Expr>>>>
auto &parserExpr{maybeClause->v.thing.thing.thing.value()};
evaluate::ExpressionAnalyzer ea{context_};
if (auto &&maybeExpr{ea.Analyze(parserExpr)}) {
if (auto v{omp::GetLogicalValue(*maybeExpr)}) {
return *v;
}
}
}
// If the argument is missing, it is assumed to be true.
return true;
}};

// Gather information from the clauses.
RequiresClauses reqs;
const common::OmpMemoryOrderType *memOrder{nullptr};
Expand All @@ -573,16 +588,19 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
if constexpr ( //
std::is_same_v<TypeS, OmpClause::DynamicAllocators> ||
std::is_same_v<TypeS, OmpClause::ReverseOffload> ||
std::is_same_v<TypeS, OmpClause::SelfMaps> ||
std::is_same_v<TypeS, OmpClause::UnifiedAddress> ||
std::is_same_v<TypeS, OmpClause::UnifiedSharedMemory>) {
return RequiresClauses{clause.Id()};
} else {
return RequiresClauses{};
if (getArgument(s.v)) {
return RequiresClauses{clause.Id()};
}
}
return RequiresClauses{};
},
},
clause.u);
}

// Merge clauses into parents' symbols details.
AddOmpRequiresToScope(currScope(), &reqs, memOrder);
return true;
Expand Down
14 changes: 14 additions & 0 deletions flang/test/Parser/OpenMP/requires.f90
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,18 @@
!PARSE-TREE: | OmpClause -> ReverseOffload
!PARSE-TREE: | Flags = None

!$omp requires self_maps(.true.) unified_address(.false.)

!UNPARSE: !$OMP REQUIRES SELF_MAPS(.true._4) UNIFIED_ADDRESS(.false._4)

!PARSE-TREE: OpenMPDeclarativeConstruct -> OpenMPRequiresConstruct -> OmpDirectiveSpecification
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = requires
!PARSE-TREE: | OmpClauseList -> OmpClause -> SelfMaps -> OmpSelfMapsClause -> Scalar -> Logical -> Constant -> Expr = '.true._4'
!PARSE-TREE: | | LiteralConstant -> LogicalLiteralConstant
!PARSE-TREE: | | | bool = 'true'
!PARSE-TREE: | OmpClause -> UnifiedAddress -> OmpUnifiedAddressClause -> Scalar -> Logical -> Constant -> Expr = '.false._4'
!PARSE-TREE: | | LiteralConstant -> LogicalLiteralConstant
!PARSE-TREE: | | | bool = 'false'
!PARSE-TREE: | Flags = None

end
Loading