[flang] [llvm] [flang][OpenMP] Frontend support for REPLAYABLE and TRANSPARENT clauses (PR #158149)
Krzysztof Parzyszek via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 11 13:21:43 PDT 2025
https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/158149
Parsing and semantic checks.
>From 25403cb2cd5218ebf3f1ed18e5d9e762462781e4 Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Thu, 11 Sep 2025 13:47:35 -0500
Subject: [PATCH] [flang][OpenMP] Frontend support for REPLAYABLE and
TRANSPARENT clauses
Parsing and semantic checks.
---
flang/include/flang/Lower/OpenMP/Clauses.h | 2 +
flang/include/flang/Parser/dump-parse-tree.h | 2 +
flang/include/flang/Parser/parse-tree.h | 16 ++++
flang/lib/Lower/OpenMP/Clauses.cpp | 8 +-
flang/lib/Parser/openmp-parsers.cpp | 12 +++
flang/lib/Semantics/check-omp-structure.cpp | 2 +
.../test/Parser/OpenMP/replayable-clause.f90 | 60 +++++++++++++++
.../test/Parser/OpenMP/transparent-clause.f90 | 76 +++++++++++++++++++
.../Semantics/OpenMP/replayable-clause.f90 | 22 ++++++
.../Semantics/OpenMP/transparent-clause.f90 | 19 +++++
llvm/include/llvm/Frontend/OpenMP/ClauseT.h | 30 +++++---
llvm/include/llvm/Frontend/OpenMP/OMP.td | 20 +++++
12 files changed, 257 insertions(+), 12 deletions(-)
create mode 100644 flang/test/Parser/OpenMP/replayable-clause.f90
create mode 100644 flang/test/Parser/OpenMP/transparent-clause.f90
create mode 100644 flang/test/Semantics/OpenMP/replayable-clause.f90
create mode 100644 flang/test/Semantics/OpenMP/transparent-clause.f90
diff --git a/flang/include/flang/Lower/OpenMP/Clauses.h b/flang/include/flang/Lower/OpenMP/Clauses.h
index 638846835094c..18e2f209c2d7a 100644
--- a/flang/include/flang/Lower/OpenMP/Clauses.h
+++ b/flang/include/flang/Lower/OpenMP/Clauses.h
@@ -277,6 +277,7 @@ using Read = tomp::clause::ReadT<TypeTy, IdTy, ExprTy>;
using Reduction = tomp::clause::ReductionT<TypeTy, IdTy, ExprTy>;
using Relaxed = tomp::clause::RelaxedT<TypeTy, IdTy, ExprTy>;
using Release = tomp::clause::ReleaseT<TypeTy, IdTy, ExprTy>;
+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>;
@@ -290,6 +291,7 @@ using Permutation = tomp::clause::PermutationT<TypeTy, IdTy, ExprTy>;
using TaskReduction = tomp::clause::TaskReductionT<TypeTy, IdTy, ExprTy>;
using ThreadLimit = tomp::clause::ThreadLimitT<TypeTy, IdTy, ExprTy>;
using Threads = tomp::clause::ThreadsT<TypeTy, IdTy, ExprTy>;
+using Transparent = tomp::clause::TransparentT<TypeTy, IdTy, ExprTy>;
using To = tomp::clause::ToT<TypeTy, IdTy, ExprTy>;
using UnifiedAddress = tomp::clause::UnifiedAddressT<TypeTy, IdTy, ExprTy>;
using UnifiedSharedMemory =
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index d2ab7cbd8fe35..1c9fd7673e06d 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -658,6 +658,7 @@ class ParseTreeDumper {
NODE(parser, OmpReductionSpecifier)
NODE(parser, OmpRefModifier)
NODE_ENUM(OmpRefModifier, Value)
+ NODE(parser, OmpReplayableClause)
NODE(parser, OmpScheduleClause)
NODE(OmpScheduleClause, Modifier)
NODE_ENUM(OmpScheduleClause, Kind)
@@ -686,6 +687,7 @@ class ParseTreeDumper {
NODE(parser, OmpTraitSetSelector)
NODE(parser, OmpTraitSetSelectorName)
NODE_ENUM(OmpTraitSetSelectorName, Value)
+ NODE(parser, OmpTransparentClause)
NODE(parser, OmpTypeNameList)
NODE(parser, OmpTypeSpecifier)
NODE(parser, OmpUpdateClause)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 622b5f90a9fba..951c96b974141 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -4643,6 +4643,14 @@ struct OmpReductionClause {
std::tuple<MODIFIERS(), OmpObjectList> t;
};
+// Ref: [6.0:440:441]
+//
+// replayable-clause ->
+// REPLAYABLE[(replayable-expression)] // since 6.0
+struct OmpReplayableClause {
+ WRAPPER_CLASS_BOILERPLATE(OmpReplayableClause, Scalar<Logical<ConstantExpr>>);
+};
+
// Ref: [4.5:56-63], [5.0:101-109], [5.1:126-133], [5.2:252-254]
//
// schedule-clause ->
@@ -4692,6 +4700,14 @@ struct OmpToClause {
std::tuple<MODIFIERS(), OmpObjectList, /*CommaSeparated=*/bool> t;
};
+// Ref: [6.0:510-511]
+//
+// transparent-clause ->
+// TRANSPARENT[(impex-type)] // since 6.0
+struct OmpTransparentClause {
+ WRAPPER_CLASS_BOILERPLATE(OmpTransparentClause, ScalarIntExpr);
+};
+
// Ref: [5.0:254-255], [5.1:287-288], [5.2:321-322]
//
// In ATOMIC construct
diff --git a/flang/lib/Lower/OpenMP/Clauses.cpp b/flang/lib/Lower/OpenMP/Clauses.cpp
index cecc1a9395892..1faa920a4d629 100644
--- a/flang/lib/Lower/OpenMP/Clauses.cpp
+++ b/flang/lib/Lower/OpenMP/Clauses.cpp
@@ -221,8 +221,6 @@ MAKE_EMPTY_CLASS(Capture, Capture);
MAKE_EMPTY_CLASS(Compare, Compare);
MAKE_EMPTY_CLASS(DynamicAllocators, DynamicAllocators);
MAKE_EMPTY_CLASS(Full, Full);
-MAKE_EMPTY_CLASS(GraphId, GraphId);
-MAKE_EMPTY_CLASS(GraphReset, GraphReset);
MAKE_EMPTY_CLASS(Inbranch, Inbranch);
MAKE_EMPTY_CLASS(Mergeable, Mergeable);
MAKE_EMPTY_CLASS(Nogroup, Nogroup);
@@ -239,11 +237,11 @@ 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(SelfMaps, SelfMaps);
MAKE_EMPTY_CLASS(Unknown, Unknown);
MAKE_EMPTY_CLASS(Untied, Untied);
MAKE_EMPTY_CLASS(Weak, Weak);
@@ -257,6 +255,10 @@ MAKE_EMPTY_CLASS(Threadprivate, Threadprivate);
MAKE_INCOMPLETE_CLASS(AdjustArgs, AdjustArgs);
MAKE_INCOMPLETE_CLASS(AppendArgs, AppendArgs);
+MAKE_INCOMPLETE_CLASS(GraphId, GraphId);
+MAKE_INCOMPLETE_CLASS(GraphReset, GraphReset);
+MAKE_INCOMPLETE_CLASS(Replayable, Replayable);
+MAKE_INCOMPLETE_CLASS(Transparent, Transparent);
List<IteratorSpecifier>
makeIteratorSpecifiers(const parser::OmpIteratorSpecifier &inp,
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 68e0acdf91fe2..352397502a6e7 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -34,6 +34,9 @@ namespace Fortran::parser {
constexpr auto startOmpLine = skipStuffBeforeStatement >> "!$OMP "_sptok;
constexpr auto endOmpLine = space >> endOfLine;
+constexpr auto logicalConstantExpr{logical(constantExpr)};
+constexpr auto scalarLogicalConstantExpr{scalar(logicalConstantExpr)};
+
// Given a parser for a single element, and a parser for a list of elements
// of the same type, create a parser that constructs the entire list by having
// the single element be the head of the list, and the rest be the tail.
@@ -868,6 +871,8 @@ TYPE_PARSER(construct<OmpReductionClause>(
maybe(nonemptyList(Parser<OmpReductionClause::Modifier>{}) / ":"),
Parser<OmpObjectList>{}))
+TYPE_PARSER(construct<OmpReplayableClause>(scalarLogicalConstantExpr))
+
// OMP 5.0 2.19.5.6 IN_REDUCTION (reduction-identifier: variable-name-list)
TYPE_PARSER(construct<OmpInReductionClause>(
maybe(nonemptyList(Parser<OmpInReductionClause::Modifier>{}) / ":"),
@@ -877,6 +882,8 @@ TYPE_PARSER(construct<OmpTaskReductionClause>(
maybe(nonemptyList(Parser<OmpTaskReductionClause::Modifier>{}) / ":"),
Parser<OmpObjectList>{}))
+TYPE_PARSER(construct<OmpTransparentClause>(scalarIntExpr))
+
// OMP 5.0 2.11.4 allocate-clause -> ALLOCATE ([allocator:] variable-name-list)
// OMP 5.2 2.13.4 allocate-clause -> ALLOCATE ([allocate-modifier
// [, allocate-modifier] :]
@@ -1192,6 +1199,8 @@ TYPE_PARSER( //
"READ" >> construct<OmpClause>(construct<OmpClause::Read>()) ||
"RELAXED" >> construct<OmpClause>(construct<OmpClause::Relaxed>()) ||
"RELEASE" >> construct<OmpClause>(construct<OmpClause::Release>()) ||
+ "REPLAYABLE" >> construct<OmpClause>(construct<OmpClause::Replayable>(
+ maybe(parenthesized(Parser<OmpReplayableClause>{})))) ||
"REVERSE_OFFLOAD" >>
construct<OmpClause>(construct<OmpClause::ReverseOffload>()) ||
"SAFELEN" >> construct<OmpClause>(construct<OmpClause::Safelen>(
@@ -1215,6 +1224,9 @@ TYPE_PARSER( //
parenthesized(scalarIntExpr))) ||
"TO" >> construct<OmpClause>(construct<OmpClause::To>(
parenthesized(Parser<OmpToClause>{}))) ||
+ "TRANSPARENT" >>
+ construct<OmpClause>(construct<OmpClause::Transparent>(
+ maybe(parenthesized(Parser<OmpTransparentClause>{})))) ||
"USE" >> construct<OmpClause>(construct<OmpClause::Use>(
parenthesized(Parser<OmpObject>{}))) ||
"USE_DEVICE_PTR" >> construct<OmpClause>(construct<OmpClause::UseDevicePtr>(
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index d1654a3adcc9c..afa9d049cd33d 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -2845,6 +2845,8 @@ CHECK_SIMPLE_CLAUSE(AcqRel, OMPC_acq_rel)
CHECK_SIMPLE_CLAUSE(Acquire, OMPC_acquire)
CHECK_SIMPLE_CLAUSE(Relaxed, OMPC_relaxed)
CHECK_SIMPLE_CLAUSE(Release, OMPC_release)
+CHECK_SIMPLE_CLAUSE(Replayable, OMPC_replayable)
+CHECK_SIMPLE_CLAUSE(Transparent, OMPC_transparent)
CHECK_SIMPLE_CLAUSE(SeqCst, OMPC_seq_cst)
CHECK_SIMPLE_CLAUSE(Fail, OMPC_fail)
diff --git a/flang/test/Parser/OpenMP/replayable-clause.f90 b/flang/test/Parser/OpenMP/replayable-clause.f90
new file mode 100644
index 0000000000000..c1733449fcb70
--- /dev/null
+++ b/flang/test/Parser/OpenMP/replayable-clause.f90
@@ -0,0 +1,60 @@
+!RUN: %flang_fc1 -fdebug-unparse -fopenmp -fopenmp-version=60 %s | FileCheck --ignore-case --check-prefix="UNPARSE" %s
+!RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=60 %s | FileCheck --check-prefix="PARSE-TREE" %s
+
+subroutine f00
+ !$omp task replayable
+ block
+ end block
+end
+
+!UNPARSE: SUBROUTINE f00
+!UNPARSE: !$OMP TASK REPLAYABLE
+!UNPARSE: BLOCK
+!UNPARSE: END BLOCK
+!UNPARSE: END SUBROUTINE
+
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OmpBlockConstruct
+!PARSE-TREE: | OmpBeginDirective
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = task
+!PARSE-TREE: | | OmpClauseList -> OmpClause -> Replayable ->
+!PARSE-TREE: | | Flags = None
+!PARSE-TREE: | Block
+
+
+subroutine f01(x)
+ implicit none
+ integer :: x
+ !$omp target_update to(x) replayable(.true.)
+end
+
+!UNPARSE: SUBROUTINE f01 (x)
+!UNPARSE: IMPLICIT NONE
+!UNPARSE: INTEGER x
+!UNPARSE: !$OMP TARGET_UPDATE TO(x) REPLAYABLE(.true._4)
+!UNPARSE: END SUBROUTINE
+
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPSimpleStandaloneConstruct -> OmpDirectiveSpecification
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = target update
+!PARSE-TREE: | OmpClauseList -> OmpClause -> To -> OmpToClause
+!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x'
+!PARSE-TREE: | | bool = 'true'
+!PARSE-TREE: | OmpClause -> Replayable -> OmpReplayableClause -> Scalar -> Logical -> Constant -> Expr = '.true._4'
+!PARSE-TREE: | | LiteralConstant -> LogicalLiteralConstant
+!PARSE-TREE: | | | bool = 'true'
+!PARSE-TREE: | Flags = None
+
+
+subroutine f02
+ !$omp taskwait replayable(.false.)
+end
+
+!UNPARSE: SUBROUTINE f02
+!UNPARSE: !$OMP TASKWAIT REPLAYABLE(.false._4)
+!UNPARSE: END SUBROUTINE
+
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPSimpleStandaloneConstruct -> OmpDirectiveSpecification
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = taskwait
+!PARSE-TREE: | OmpClauseList -> OmpClause -> Replayable -> OmpReplayableClause -> Scalar -> Logical -> Constant -> Expr = '.false._4'
+!PARSE-TREE: | | LiteralConstant -> LogicalLiteralConstant
+!PARSE-TREE: | | | bool = 'false'
+!PARSE-TREE: | Flags = None
diff --git a/flang/test/Parser/OpenMP/transparent-clause.f90 b/flang/test/Parser/OpenMP/transparent-clause.f90
new file mode 100644
index 0000000000000..01f49f5e8a15d
--- /dev/null
+++ b/flang/test/Parser/OpenMP/transparent-clause.f90
@@ -0,0 +1,76 @@
+!RUN: %flang_fc1 -fdebug-unparse -fopenmp -fopenmp-version=60 %s | FileCheck --ignore-case --check-prefix="UNPARSE" %s
+!RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=60 %s | FileCheck --check-prefix="PARSE-TREE" %s
+
+subroutine f00(x)
+ implicit none
+ integer :: x
+ !$omp target_data map(to: x) transparent
+ block
+ end block
+end
+
+!UNPARSE: SUBROUTINE f00 (x)
+!UNPARSE: IMPLICIT NONE
+!UNPARSE: INTEGER x
+!UNPARSE: !$OMP TARGET_DATA MAP(TO: x) TRANSPARENT
+!UNPARSE: BLOCK
+!UNPARSE: END BLOCK
+!UNPARSE: END SUBROUTINE
+
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OmpBlockConstruct
+!PARSE-TREE: | OmpBeginDirective
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = target data
+!PARSE-TREE: | | OmpClauseList -> OmpClause -> Map -> OmpMapClause
+!PARSE-TREE: | | | Modifier -> OmpMapType -> Value = To
+!PARSE-TREE: | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x'
+!PARSE-TREE: | | | bool = 'true'
+!PARSE-TREE: | | OmpClause -> Transparent ->
+!PARSE-TREE: | | Flags = None
+!PARSE-TREE: | Block
+
+
+subroutine f01
+ !$omp task transparent(0)
+ !$omp end task
+end
+
+!UNPARSE: SUBROUTINE f01
+!UNPARSE: !$OMP TASK TRANSPARENT(0_4)
+!UNPARSE: !$OMP END TASK
+!UNPARSE: END SUBROUTINE
+
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OmpBlockConstruct
+!PARSE-TREE: | OmpBeginDirective
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = task
+!PARSE-TREE: | | OmpClauseList -> OmpClause -> Transparent -> OmpTransparentClause -> Scalar -> Integer -> Expr = '0_4'
+!PARSE-TREE: | | | LiteralConstant -> IntLiteralConstant = '0'
+!PARSE-TREE: | | Flags = None
+!PARSE-TREE: | Block
+!PARSE-TREE: | OmpEndDirective
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = task
+!PARSE-TREE: | | OmpClauseList ->
+!PARSE-TREE: | | Flags = None
+
+
+subroutine f02
+ implicit none
+ integer :: i
+ !$omp taskloop transparent(2)
+ do i = 1, 10
+ end do
+end
+
+!UNPARSE: SUBROUTINE f02
+!UNPARSE: IMPLICIT NONE
+!UNPARSE: INTEGER i
+!UNPARSE: !$OMP TASKLOOP TRANSPARENT(2_4)
+!UNPARSE: DO i=1_4,10_4
+!UNPARSE: END DO
+!UNPARSE: END SUBROUTINE
+
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct
+!PARSE-TREE: | OmpBeginLoopDirective
+!PARSE-TREE: | | OmpLoopDirective -> llvm::omp::Directive = taskloop
+!PARSE-TREE: | | OmpClauseList -> OmpClause -> Transparent -> OmpTransparentClause -> Scalar -> Integer -> Expr = '2_4'
+!PARSE-TREE: | | | LiteralConstant -> IntLiteralConstant = '2'
+!PARSE-TREE: | DoConstruct
diff --git a/flang/test/Semantics/OpenMP/replayable-clause.f90 b/flang/test/Semantics/OpenMP/replayable-clause.f90
new file mode 100644
index 0000000000000..b8fe6cea23a6f
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/replayable-clause.f90
@@ -0,0 +1,22 @@
+!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=60
+
+subroutine f00(x)
+ implicit none
+ logical :: x
+ !ERROR: Must be a constant value
+ !$omp task replayable(x)
+ !$omp end task
+end
+
+subroutine f01
+ !ERROR: Must have LOGICAL type, but is INTEGER(4)
+ !$omp task replayable(7)
+ !$omp end task
+end
+
+subroutine f02
+ !No diagnostic expected
+ !$omp task replayable
+ !$omp end task
+end
+
diff --git a/flang/test/Semantics/OpenMP/transparent-clause.f90 b/flang/test/Semantics/OpenMP/transparent-clause.f90
new file mode 100644
index 0000000000000..4831ba0f7cef6
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/transparent-clause.f90
@@ -0,0 +1,19 @@
+!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=60
+
+subroutine f00(x)
+ integer :: x(10)
+ !ERROR: Must be a scalar value, but is a rank-1 array
+ !$omp task transparent(x)
+ !$omp end task
+end
+
+subroutine f01
+ implicit none
+ integer :: i
+ !ERROR: Must have INTEGER type, but is CHARACTER(KIND=1,LEN=5_8)
+ !$omp taskloop transparent("hello")
+ do i = 1, 10
+ end do
+ !$omp end taskloop
+end
+
diff --git a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
index 56905854f9baa..1ade9ce0c3a7d 100644
--- a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
+++ b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
@@ -663,13 +663,13 @@ struct GrainsizeT {
// [6.0:438] `graph_id` clause
template <typename T, typename I, typename E> //
struct GraphIdT {
- using EmptyTrait = std::true_type;
+ using IncompleteTrait = std::true_type;
};
// [6.0:438] `graph_reset` clause
template <typename T, typename I, typename E> //
struct GraphResetT {
- using EmptyTrait = std::true_type;
+ using IncompleteTrait = std::true_type;
};
// V5.2: [5.4.9] `has_device_addr` clause
@@ -1046,6 +1046,12 @@ struct ReleaseT {
using EmptyTrait = std::true_type;
};
+// [6.0:440-441] `replayable` clause
+template <typename T, typename I, typename E> //
+struct ReplayableT {
+ using IncompleteTrait = std::true_type;
+};
+
// V5.2: [8.2.1] `requirement` clauses
template <typename T, typename I, typename E> //
struct ReverseOffloadT {
@@ -1153,6 +1159,12 @@ struct ToT {
std::tuple<OPT(Expectation), OPT(Mappers), OPT(Iterator), LocatorList> t;
};
+// [6.0:440-441] `transparent` clause
+template <typename T, typename I, typename E> //
+struct TransparentT {
+ using IncompleteTrait = std::true_type;
+};
+
// V5.2: [8.2.1] `requirement` clauses
template <typename T, typename I, typename E> //
struct UnifiedAddressT {
@@ -1266,11 +1278,10 @@ using ExtensionClausesT =
template <typename T, typename I, typename E>
using EmptyClausesT = std::variant<
AcqRelT<T, I, E>, AcquireT<T, I, E>, CaptureT<T, I, E>, CompareT<T, I, E>,
- DynamicAllocatorsT<T, I, E>, FullT<T, I, E>, GraphIdT<T, I, E>,
- GraphResetT<T, I, E>, InbranchT<T, I, E>, MergeableT<T, I, E>,
- NogroupT<T, I, E>, NoOpenmpRoutinesT<T, I, E>, NoOpenmpT<T, I, E>,
- NoParallelismT<T, I, E>, NotinbranchT<T, I, E>, NowaitT<T, I, E>,
- ReadT<T, I, E>, RelaxedT<T, I, E>, ReleaseT<T, I, E>,
+ DynamicAllocatorsT<T, I, E>, FullT<T, I, E>, InbranchT<T, I, E>,
+ MergeableT<T, I, E>, NogroupT<T, I, E>, NoOpenmpRoutinesT<T, I, E>,
+ NoOpenmpT<T, I, E>, NoParallelismT<T, I, E>, NotinbranchT<T, I, E>,
+ NowaitT<T, I, E>, ReadT<T, I, E>, RelaxedT<T, I, E>, ReleaseT<T, I, E>,
ReverseOffloadT<T, I, E>, SeqCstT<T, I, E>, SimdT<T, I, E>,
ThreadsT<T, I, E>, UnifiedAddressT<T, I, E>, UnifiedSharedMemoryT<T, I, E>,
UnknownT<T, I, E>, UntiedT<T, I, E>, UseT<T, I, E>, WeakT<T, I, E>,
@@ -1278,8 +1289,9 @@ using EmptyClausesT = std::variant<
template <typename T, typename I, typename E>
using IncompleteClausesT =
- std::variant<AdjustArgsT<T, I, E>, AppendArgsT<T, I, E>, MatchT<T, I, E>,
- OtherwiseT<T, I, E>, WhenT<T, I, E>>;
+ std::variant<AdjustArgsT<T, I, E>, AppendArgsT<T, I, E>, GraphIdT<T, I, E>,
+ GraphResetT<T, I, E>, MatchT<T, I, E>, OtherwiseT<T, I, E>,
+ ReplayableT<T, I, E>, TransparentT<T, I, E>, WhenT<T, I, E>>;
template <typename T, typename I, typename E>
using TupleClausesT =
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index 20e4be76ceb0f..d2a6feb9178bf 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -456,6 +456,10 @@ def OMPC_Relaxed : Clause<[Spelling<"relaxed">]> {
def OMPC_Release : Clause<[Spelling<"release">]> {
let clangClass = "OMPReleaseClause";
}
+def OMPC_Replayable : Clause<[Spelling<"replayable">]> {
+ let flangClass = "OmpReplayableClause";
+ let isValueOptional = true;
+}
def OMPC_ReverseOffload : Clause<[Spelling<"reverse_offload">]> {
let clangClass = "OMPReverseOffloadClause";
}
@@ -523,6 +527,10 @@ def OMPC_To : Clause<[Spelling<"to">]> {
let clangClass = "OMPToClause";
let flangClass = "OmpToClause";
}
+def OMPC_Transparent : Clause<[Spelling<"transparent">]> {
+ let flangClass = "OmpTransparentClause";
+ let isValueOptional = true;
+}
def OMPC_UnifiedAddress : Clause<[Spelling<"unified_address">]> {
let clangClass = "OMPUnifiedAddressClause";
}
@@ -1128,6 +1136,7 @@ def OMP_Target : Directive<[Spelling<"target">]> {
VersionedClause<OMPC_NoWait>,
VersionedClause<OMPC_OMPX_Bare>,
VersionedClause<OMPC_OMPX_DynCGroupMem>,
+ VersionedClause<OMPC_Replayable, 60>,
VersionedClause<OMPC_ThreadLimit, 51>,
];
let association = AS_Block;
@@ -1139,6 +1148,7 @@ def OMP_TargetData : Directive<[Spelling<"target data", 1, 52>,
VersionedClause<OMPC_Device>,
VersionedClause<OMPC_If>,
VersionedClause<OMPC_Default, 60>,
+ VersionedClause<OMPC_Transparent, 60>,
];
let requiredClauses = [
VersionedClause<OMPC_Map>,
@@ -1157,6 +1167,7 @@ def OMP_TargetEnterData : Directive<[Spelling<"target enter data", 1, 52>,
VersionedClause<OMPC_Device>,
VersionedClause<OMPC_If>,
VersionedClause<OMPC_NoWait>,
+ VersionedClause<OMPC_Replayable, 60>,
];
let requiredClauses = [
VersionedClause<OMPC_Map>,
@@ -1173,6 +1184,7 @@ def OMP_TargetExitData : Directive<[Spelling<"target exit data", 1, 52>,
VersionedClause<OMPC_Device>,
VersionedClause<OMPC_If>,
VersionedClause<OMPC_NoWait>,
+ VersionedClause<OMPC_Replayable, 60>,
];
let requiredClauses = [
VersionedClause<OMPC_Map>,
@@ -1191,6 +1203,7 @@ def OMP_TargetUpdate : Directive<[Spelling<"target update", 1, 52>,
VersionedClause<OMPC_Device>,
VersionedClause<OMPC_If>,
VersionedClause<OMPC_NoWait>,
+ VersionedClause<OMPC_Replayable, 60>,
];
let association = AS_None;
let category = CA_Executable;
@@ -1213,6 +1226,8 @@ def OMP_Task : Directive<[Spelling<"task">]> {
VersionedClause<OMPC_Final>,
VersionedClause<OMPC_If>,
VersionedClause<OMPC_Priority>,
+ VersionedClause<OMPC_Replayable, 60>,
+ VersionedClause<OMPC_Transparent, 60>,
];
let association = AS_Block;
let category = CA_Executable;
@@ -1254,6 +1269,8 @@ def OMP_TaskLoop : Directive<[Spelling<"taskloop">]> {
VersionedClause<OMPC_Final>,
VersionedClause<OMPC_If>,
VersionedClause<OMPC_Priority>,
+ VersionedClause<OMPC_Replayable, 60>,
+ VersionedClause<OMPC_Transparent, 60>,
];
let allowedExclusiveClauses = [
VersionedClause<OMPC_GrainSize>,
@@ -1267,6 +1284,9 @@ def OMP_TaskWait : Directive<[Spelling<"taskwait">]> {
VersionedClause<OMPC_Depend, 50>,
VersionedClause<OMPC_NoWait, 51>,
];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_Replayable, 60>,
+ ];
let association = AS_None;
let category = CA_Executable;
}
More information about the llvm-commits
mailing list