Skip to content
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
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