Skip to content

Commit 3590a91

Browse files
authored
[flang][OpenMP] Frontend support for DEVICE_SAFESYNC (llvm#163560)
Add parsing and semantic checks for DEVICE_SAFESYNC clause. No lowering.
1 parent 32de3b9 commit 3590a91

File tree

10 files changed

+64
-10
lines changed

10 files changed

+64
-10
lines changed

flang/include/flang/Lower/OpenMP/Clauses.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ using Depend = tomp::clause::DependT<TypeTy, IdTy, ExprTy>;
214214
using Destroy = tomp::clause::DestroyT<TypeTy, IdTy, ExprTy>;
215215
using Detach = tomp::clause::DetachT<TypeTy, IdTy, ExprTy>;
216216
using Device = tomp::clause::DeviceT<TypeTy, IdTy, ExprTy>;
217+
using DeviceSafesync = tomp::clause::DeviceSafesyncT<TypeTy, IdTy, ExprTy>;
217218
using DeviceType = tomp::clause::DeviceTypeT<TypeTy, IdTy, ExprTy>;
218219
using DistSchedule = tomp::clause::DistScheduleT<TypeTy, IdTy, ExprTy>;
219220
using Doacross = tomp::clause::DoacrossT<TypeTy, IdTy, ExprTy>;

flang/include/flang/Parser/dump-parse-tree.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,7 @@ class ParseTreeDumper {
559559
NODE(OmpDeviceClause, Modifier)
560560
NODE(parser, OmpDeviceModifier)
561561
NODE_ENUM(OmpDeviceModifier, Value)
562+
NODE(parser, OmpDeviceSafesyncClause)
562563
NODE(parser, OmpDeviceTypeClause)
563564
NODE_ENUM(OmpDeviceTypeClause, DeviceTypeDescription)
564565
NODE(parser, OmpDirectiveName)

flang/include/flang/Parser/parse-tree.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4418,6 +4418,14 @@ struct OmpDeviceClause {
44184418
std::tuple<MODIFIERS(), ScalarIntExpr> t;
44194419
};
44204420

4421+
// Ref: [6.0:356-362]
4422+
//
4423+
// device-safesync-clause ->
4424+
// DEVICE_SAFESYNC [(scalar-logical-const-expr)] // since 6.0
4425+
struct OmpDeviceSafesyncClause {
4426+
WRAPPER_CLASS_BOILERPLATE(OmpDeviceSafesyncClause, ScalarLogicalConstantExpr);
4427+
};
4428+
44214429
// Ref: [5.0:180-185], [5.1:210-216], [5.2:275]
44224430
//
44234431
// device-type-clause ->

flang/lib/Lower/OpenMP/Clauses.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,18 @@ Device make(const parser::OmpClause::Device &inp,
740740
/*DeviceDescription=*/makeExpr(t1, semaCtx)}};
741741
}
742742

743+
DeviceSafesync make(const parser::OmpClause::DeviceSafesync &inp,
744+
semantics::SemanticsContext &semaCtx) {
745+
// inp.v -> std::optional<parser::OmpDeviceSafesyncClause>
746+
auto &&maybeRequired = maybeApply(
747+
[&](const parser::OmpDeviceSafesyncClause &c) {
748+
return makeExpr(c.v, semaCtx);
749+
},
750+
inp.v);
751+
752+
return DeviceSafesync{/*Required=*/std::move(maybeRequired)};
753+
}
754+
743755
DeviceType make(const parser::OmpClause::DeviceType &inp,
744756
semantics::SemanticsContext &semaCtx) {
745757
// inp.v -> parser::OmpDeviceTypeClause

flang/lib/Parser/openmp-parsers.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1159,6 +1159,9 @@ TYPE_PARSER( //
11591159
construct<OmpDestroyClause>(Parser<OmpObject>{}))))) ||
11601160
"DEVICE" >> construct<OmpClause>(construct<OmpClause::Device>(
11611161
parenthesized(Parser<OmpDeviceClause>{}))) ||
1162+
"DEVICE_SAFESYNC" >>
1163+
construct<OmpClause>(construct<OmpClause::DeviceSafesync>(
1164+
maybe(parenthesized(scalarLogicalConstantExpr)))) ||
11621165
"DEVICE_TYPE" >> construct<OmpClause>(construct<OmpClause::DeviceType>(
11631166
parenthesized(Parser<OmpDeviceTypeClause>{}))) ||
11641167
"DIST_SCHEDULE" >>

flang/lib/Semantics/check-omp-structure.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1535,6 +1535,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPRequiresConstruct &x) {
15351535
[&](auto &&s) {
15361536
using TypeS = llvm::remove_cvref_t<decltype(s)>;
15371537
if constexpr ( //
1538+
std::is_same_v<TypeS, parser::OmpClause::DeviceSafesync> ||
15381539
std::is_same_v<TypeS, parser::OmpClause::DynamicAllocators> ||
15391540
std::is_same_v<TypeS, parser::OmpClause::ReverseOffload> ||
15401541
std::is_same_v<TypeS, parser::OmpClause::SelfMaps> ||
@@ -5194,6 +5195,10 @@ void OmpStructureChecker::Enter(
51945195
CheckAllowedRequiresClause(llvm::omp::Clause::OMPC_atomic_default_mem_order);
51955196
}
51965197

5198+
void OmpStructureChecker::Enter(const parser::OmpClause::DeviceSafesync &x) {
5199+
CheckAllowedRequiresClause(llvm::omp::Clause::OMPC_device_safesync);
5200+
}
5201+
51975202
void OmpStructureChecker::Enter(const parser::OmpClause::DynamicAllocators &x) {
51985203
CheckAllowedRequiresClause(llvm::omp::Clause::OMPC_dynamic_allocators);
51995204
}

flang/lib/Semantics/resolve-directives.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,7 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
586586
[&](auto &&s) {
587587
using TypeS = llvm::remove_cvref_t<decltype(s)>;
588588
if constexpr ( //
589+
std::is_same_v<TypeS, OmpClause::DeviceSafesync> ||
589590
std::is_same_v<TypeS, OmpClause::DynamicAllocators> ||
590591
std::is_same_v<TypeS, OmpClause::ReverseOffload> ||
591592
std::is_same_v<TypeS, OmpClause::SelfMaps> ||

flang/test/Parser/OpenMP/requires.f90

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
!RUN: %flang_fc1 -fdebug-unparse -fopenmp -fopenmp-version=50 %s | FileCheck --ignore-case --check-prefix="UNPARSE" %s
2-
!RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=50 %s | FileCheck --check-prefix="PARSE-TREE" %s
1+
!RUN: %flang_fc1 -fdebug-unparse -fopenmp -fopenmp-version=60 %s | FileCheck --ignore-case --check-prefix="UNPARSE" %s
2+
!RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=60 %s | FileCheck --check-prefix="PARSE-TREE" %s
33

44
!$omp requires atomic_default_mem_order(seq_cst)
55

@@ -44,4 +44,13 @@
4444
!PARSE-TREE: | | | bool = 'false'
4545
!PARSE-TREE: | Flags = None
4646

47+
!$omp requires device_safesync
48+
49+
!UNPARSE: !$OMP REQUIRES DEVICE_SAFESYNC
50+
51+
!PARSE-TREE: OpenMPDeclarativeConstruct -> OpenMPRequiresConstruct -> OmpDirectiveSpecification
52+
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = requires
53+
!PARSE-TREE: | OmpClauseList -> OmpClause -> DeviceSafesync
54+
!PARSE-TREE: | Flags = None
55+
4756
end

llvm/include/llvm/Frontend/OpenMP/ClauseT.h

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,14 @@ struct DeviceT {
541541
std::tuple<OPT(DeviceModifier), DeviceDescription> t;
542542
};
543543

544+
// [6.0:362]
545+
template <typename T, typename I, typename E> //
546+
struct DeviceSafesyncT {
547+
using Requires = E;
548+
using WrapperTrait = std::true_type;
549+
OPT(Requires) v;
550+
};
551+
544552
// V5.2: [13.1] `device_type` clause
545553
template <typename T, typename I, typename E> //
546554
struct DeviceTypeT {
@@ -1332,14 +1340,15 @@ using WrapperClausesT = std::variant<
13321340
AtomicDefaultMemOrderT<T, I, E>, AtT<T, I, E>, BindT<T, I, E>,
13331341
CollapseT<T, I, E>, ContainsT<T, I, E>, CopyinT<T, I, E>,
13341342
CopyprivateT<T, I, E>, DefaultT<T, I, E>, DestroyT<T, I, E>,
1335-
DetachT<T, I, E>, DeviceTypeT<T, I, E>, DynamicAllocatorsT<T, I, E>,
1336-
EnterT<T, I, E>, ExclusiveT<T, I, E>, FailT<T, I, E>, FilterT<T, I, E>,
1337-
FinalT<T, I, E>, FirstprivateT<T, I, E>, HasDeviceAddrT<T, I, E>,
1338-
HintT<T, I, E>, HoldsT<T, I, E>, InclusiveT<T, I, E>, IndirectT<T, I, E>,
1339-
InitializerT<T, I, E>, IsDevicePtrT<T, I, E>, LinkT<T, I, E>,
1340-
MessageT<T, I, E>, NocontextT<T, I, E>, NontemporalT<T, I, E>,
1341-
NovariantsT<T, I, E>, NumTeamsT<T, I, E>, NumThreadsT<T, I, E>,
1342-
OrderedT<T, I, E>, PartialT<T, I, E>, PriorityT<T, I, E>, PrivateT<T, I, E>,
1343+
DetachT<T, I, E>, DeviceSafesyncT<T, I, E>, DeviceTypeT<T, I, E>,
1344+
DynamicAllocatorsT<T, I, E>, EnterT<T, I, E>, ExclusiveT<T, I, E>,
1345+
FailT<T, I, E>, FilterT<T, I, E>, FinalT<T, I, E>, FirstprivateT<T, I, E>,
1346+
HasDeviceAddrT<T, I, E>, HintT<T, I, E>, HoldsT<T, I, E>,
1347+
InclusiveT<T, I, E>, IndirectT<T, I, E>, InitializerT<T, I, E>,
1348+
IsDevicePtrT<T, I, E>, LinkT<T, I, E>, MessageT<T, I, E>,
1349+
NocontextT<T, I, E>, NontemporalT<T, I, E>, NovariantsT<T, I, E>,
1350+
NumTeamsT<T, I, E>, NumThreadsT<T, I, E>, OrderedT<T, I, E>,
1351+
PartialT<T, I, E>, PriorityT<T, I, E>, PrivateT<T, I, E>,
13431352
ProcBindT<T, I, E>, ReverseOffloadT<T, I, E>, SafelenT<T, I, E>,
13441353
SelfMapsT<T, I, E>, SeverityT<T, I, E>, SharedT<T, I, E>, SimdlenT<T, I, E>,
13451354
SizesT<T, I, E>, PermutationT<T, I, E>, ThreadLimitT<T, I, E>,

llvm/include/llvm/Frontend/OpenMP/OMP.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,10 @@ def OMPC_Device : Clause<[Spelling<"device">]> {
163163
let clangClass = "OMPDeviceClause";
164164
let flangClass = "OmpDeviceClause";
165165
}
166+
def OMPC_DeviceSafesync : Clause<[Spelling<"device_safesync">]> {
167+
let flangClass = "OmpDeviceSafesyncClause";
168+
let isValueOptional = true;
169+
}
166170
def OMPC_DeviceType : Clause<[Spelling<"device_type">]> {
167171
let flangClass = "OmpDeviceTypeClause";
168172
}
@@ -1018,6 +1022,7 @@ def OMP_Requires : Directive<[Spelling<"requires">]> {
10181022
let allowedOnceClauses = [
10191023
VersionedClause<OMPC_UnifiedAddress>,
10201024
VersionedClause<OMPC_UnifiedSharedMemory>,
1025+
VersionedClause<OMPC_DeviceSafesync, 60>,
10211026
// OpenMP 5.2 Spec: If an implementation is not supporting a requirement
10221027
// (reverse offload in this case) then it should give compile-time error
10231028
// termination.

0 commit comments

Comments
 (0)