Skip to content

Commit cdd54ff

Browse files
authored
[flang][OpenMP] Frontend support for REPLAYABLE and TRANSPARENT clauses (#158149)
Parsing and semantic checks.
1 parent 13547a9 commit cdd54ff

File tree

12 files changed

+248
-2
lines changed

12 files changed

+248
-2
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ using Read = tomp::clause::ReadT<TypeTy, IdTy, ExprTy>;
277277
using Reduction = tomp::clause::ReductionT<TypeTy, IdTy, ExprTy>;
278278
using Relaxed = tomp::clause::RelaxedT<TypeTy, IdTy, ExprTy>;
279279
using Release = tomp::clause::ReleaseT<TypeTy, IdTy, ExprTy>;
280+
using Replayable = tomp::clause::ReplayableT<TypeTy, IdTy, ExprTy>;
280281
using ReverseOffload = tomp::clause::ReverseOffloadT<TypeTy, IdTy, ExprTy>;
281282
using Safelen = tomp::clause::SafelenT<TypeTy, IdTy, ExprTy>;
282283
using Schedule = tomp::clause::ScheduleT<TypeTy, IdTy, ExprTy>;
@@ -290,6 +291,7 @@ using Permutation = tomp::clause::PermutationT<TypeTy, IdTy, ExprTy>;
290291
using TaskReduction = tomp::clause::TaskReductionT<TypeTy, IdTy, ExprTy>;
291292
using ThreadLimit = tomp::clause::ThreadLimitT<TypeTy, IdTy, ExprTy>;
292293
using Threads = tomp::clause::ThreadsT<TypeTy, IdTy, ExprTy>;
294+
using Transparent = tomp::clause::TransparentT<TypeTy, IdTy, ExprTy>;
293295
using To = tomp::clause::ToT<TypeTy, IdTy, ExprTy>;
294296
using UnifiedAddress = tomp::clause::UnifiedAddressT<TypeTy, IdTy, ExprTy>;
295297
using UnifiedSharedMemory =

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,7 @@ class ParseTreeDumper {
658658
NODE(parser, OmpReductionSpecifier)
659659
NODE(parser, OmpRefModifier)
660660
NODE_ENUM(OmpRefModifier, Value)
661+
NODE(parser, OmpReplayableClause)
661662
NODE(parser, OmpScheduleClause)
662663
NODE(OmpScheduleClause, Modifier)
663664
NODE_ENUM(OmpScheduleClause, Kind)
@@ -686,6 +687,7 @@ class ParseTreeDumper {
686687
NODE(parser, OmpTraitSetSelector)
687688
NODE(parser, OmpTraitSetSelectorName)
688689
NODE_ENUM(OmpTraitSetSelectorName, Value)
690+
NODE(parser, OmpTransparentClause)
689691
NODE(parser, OmpTypeNameList)
690692
NODE(parser, OmpTypeSpecifier)
691693
NODE(parser, OmpUpdateClause)

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4643,6 +4643,14 @@ struct OmpReductionClause {
46434643
std::tuple<MODIFIERS(), OmpObjectList> t;
46444644
};
46454645

4646+
// Ref: [6.0:440:441]
4647+
//
4648+
// replayable-clause ->
4649+
// REPLAYABLE[(replayable-expression)] // since 6.0
4650+
struct OmpReplayableClause {
4651+
WRAPPER_CLASS_BOILERPLATE(OmpReplayableClause, Scalar<Logical<ConstantExpr>>);
4652+
};
4653+
46464654
// Ref: [4.5:56-63], [5.0:101-109], [5.1:126-133], [5.2:252-254]
46474655
//
46484656
// schedule-clause ->
@@ -4692,6 +4700,14 @@ struct OmpToClause {
46924700
std::tuple<MODIFIERS(), OmpObjectList, /*CommaSeparated=*/bool> t;
46934701
};
46944702

4703+
// Ref: [6.0:510-511]
4704+
//
4705+
// transparent-clause ->
4706+
// TRANSPARENT[(impex-type)] // since 6.0
4707+
struct OmpTransparentClause {
4708+
WRAPPER_CLASS_BOILERPLATE(OmpTransparentClause, ScalarIntExpr);
4709+
};
4710+
46954711
// Ref: [5.0:254-255], [5.1:287-288], [5.2:321-322]
46964712
//
46974713
// In ATOMIC construct

flang/lib/Lower/OpenMP/Clauses.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,11 +239,11 @@ MAKE_EMPTY_CLASS(Relaxed, Relaxed);
239239
MAKE_EMPTY_CLASS(Release, Release);
240240
MAKE_EMPTY_CLASS(ReverseOffload, ReverseOffload);
241241
MAKE_EMPTY_CLASS(SeqCst, SeqCst);
242+
MAKE_EMPTY_CLASS(SelfMaps, SelfMaps);
242243
MAKE_EMPTY_CLASS(Simd, Simd);
243244
MAKE_EMPTY_CLASS(Threads, Threads);
244245
MAKE_EMPTY_CLASS(UnifiedAddress, UnifiedAddress);
245246
MAKE_EMPTY_CLASS(UnifiedSharedMemory, UnifiedSharedMemory);
246-
MAKE_EMPTY_CLASS(SelfMaps, SelfMaps);
247247
MAKE_EMPTY_CLASS(Unknown, Unknown);
248248
MAKE_EMPTY_CLASS(Untied, Untied);
249249
MAKE_EMPTY_CLASS(Weak, Weak);
@@ -257,6 +257,8 @@ MAKE_EMPTY_CLASS(Threadprivate, Threadprivate);
257257

258258
MAKE_INCOMPLETE_CLASS(AdjustArgs, AdjustArgs);
259259
MAKE_INCOMPLETE_CLASS(AppendArgs, AppendArgs);
260+
MAKE_INCOMPLETE_CLASS(Replayable, Replayable);
261+
MAKE_INCOMPLETE_CLASS(Transparent, Transparent);
260262

261263
List<IteratorSpecifier>
262264
makeIteratorSpecifiers(const parser::OmpIteratorSpecifier &inp,

flang/lib/Parser/openmp-parsers.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ using namespace Fortran::parser::omp;
3636
constexpr auto startOmpLine = skipStuffBeforeStatement >> "!$OMP "_sptok;
3737
constexpr auto endOmpLine = space >> endOfLine;
3838

39+
constexpr auto logicalConstantExpr{logical(constantExpr)};
40+
constexpr auto scalarLogicalConstantExpr{scalar(logicalConstantExpr)};
41+
3942
// Given a parser for a single element, and a parser for a list of elements
4043
// of the same type, create a parser that constructs the entire list by having
4144
// the single element be the head of the list, and the rest be the tail.
@@ -870,6 +873,8 @@ TYPE_PARSER(construct<OmpReductionClause>(
870873
maybe(nonemptyList(Parser<OmpReductionClause::Modifier>{}) / ":"),
871874
Parser<OmpObjectList>{}))
872875

876+
TYPE_PARSER(construct<OmpReplayableClause>(scalarLogicalConstantExpr))
877+
873878
// OMP 5.0 2.19.5.6 IN_REDUCTION (reduction-identifier: variable-name-list)
874879
TYPE_PARSER(construct<OmpInReductionClause>(
875880
maybe(nonemptyList(Parser<OmpInReductionClause::Modifier>{}) / ":"),
@@ -879,6 +884,8 @@ TYPE_PARSER(construct<OmpTaskReductionClause>(
879884
maybe(nonemptyList(Parser<OmpTaskReductionClause::Modifier>{}) / ":"),
880885
Parser<OmpObjectList>{}))
881886

887+
TYPE_PARSER(construct<OmpTransparentClause>(scalarIntExpr))
888+
882889
// OMP 5.0 2.11.4 allocate-clause -> ALLOCATE ([allocator:] variable-name-list)
883890
// OMP 5.2 2.13.4 allocate-clause -> ALLOCATE ([allocate-modifier
884891
// [, allocate-modifier] :]
@@ -1194,6 +1201,8 @@ TYPE_PARSER( //
11941201
"READ" >> construct<OmpClause>(construct<OmpClause::Read>()) ||
11951202
"RELAXED" >> construct<OmpClause>(construct<OmpClause::Relaxed>()) ||
11961203
"RELEASE" >> construct<OmpClause>(construct<OmpClause::Release>()) ||
1204+
"REPLAYABLE" >> construct<OmpClause>(construct<OmpClause::Replayable>(
1205+
maybe(parenthesized(Parser<OmpReplayableClause>{})))) ||
11971206
"REVERSE_OFFLOAD" >>
11981207
construct<OmpClause>(construct<OmpClause::ReverseOffload>()) ||
11991208
"SAFELEN" >> construct<OmpClause>(construct<OmpClause::Safelen>(
@@ -1217,6 +1226,9 @@ TYPE_PARSER( //
12171226
parenthesized(scalarIntExpr))) ||
12181227
"TO" >> construct<OmpClause>(construct<OmpClause::To>(
12191228
parenthesized(Parser<OmpToClause>{}))) ||
1229+
"TRANSPARENT" >>
1230+
construct<OmpClause>(construct<OmpClause::Transparent>(
1231+
maybe(parenthesized(Parser<OmpTransparentClause>{})))) ||
12201232
"USE" >> construct<OmpClause>(construct<OmpClause::Use>(
12211233
parenthesized(Parser<OmpObject>{}))) ||
12221234
"USE_DEVICE_PTR" >> construct<OmpClause>(construct<OmpClause::UseDevicePtr>(

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2831,6 +2831,8 @@ CHECK_SIMPLE_CLAUSE(AcqRel, OMPC_acq_rel)
28312831
CHECK_SIMPLE_CLAUSE(Acquire, OMPC_acquire)
28322832
CHECK_SIMPLE_CLAUSE(Relaxed, OMPC_relaxed)
28332833
CHECK_SIMPLE_CLAUSE(Release, OMPC_release)
2834+
CHECK_SIMPLE_CLAUSE(Replayable, OMPC_replayable)
2835+
CHECK_SIMPLE_CLAUSE(Transparent, OMPC_transparent)
28342836
CHECK_SIMPLE_CLAUSE(SeqCst, OMPC_seq_cst)
28352837
CHECK_SIMPLE_CLAUSE(Fail, OMPC_fail)
28362838

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
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
3+
4+
subroutine f00
5+
!$omp task replayable
6+
block
7+
end block
8+
end
9+
10+
!UNPARSE: SUBROUTINE f00
11+
!UNPARSE: !$OMP TASK REPLAYABLE
12+
!UNPARSE: BLOCK
13+
!UNPARSE: END BLOCK
14+
!UNPARSE: END SUBROUTINE
15+
16+
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OmpBlockConstruct
17+
!PARSE-TREE: | OmpBeginDirective
18+
!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = task
19+
!PARSE-TREE: | | OmpClauseList -> OmpClause -> Replayable ->
20+
!PARSE-TREE: | | Flags = None
21+
!PARSE-TREE: | Block
22+
23+
24+
subroutine f01(x)
25+
implicit none
26+
integer :: x
27+
!$omp target_update to(x) replayable(.true.)
28+
end
29+
30+
!UNPARSE: SUBROUTINE f01 (x)
31+
!UNPARSE: IMPLICIT NONE
32+
!UNPARSE: INTEGER x
33+
!UNPARSE: !$OMP TARGET_UPDATE TO(x) REPLAYABLE(.true._4)
34+
!UNPARSE: END SUBROUTINE
35+
36+
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPSimpleStandaloneConstruct -> OmpDirectiveSpecification
37+
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = target update
38+
!PARSE-TREE: | OmpClauseList -> OmpClause -> To -> OmpToClause
39+
!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x'
40+
!PARSE-TREE: | | bool = 'true'
41+
!PARSE-TREE: | OmpClause -> Replayable -> OmpReplayableClause -> Scalar -> Logical -> Constant -> Expr = '.true._4'
42+
!PARSE-TREE: | | LiteralConstant -> LogicalLiteralConstant
43+
!PARSE-TREE: | | | bool = 'true'
44+
!PARSE-TREE: | Flags = None
45+
46+
47+
subroutine f02
48+
!$omp taskwait replayable(.false.)
49+
end
50+
51+
!UNPARSE: SUBROUTINE f02
52+
!UNPARSE: !$OMP TASKWAIT REPLAYABLE(.false._4)
53+
!UNPARSE: END SUBROUTINE
54+
55+
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPSimpleStandaloneConstruct -> OmpDirectiveSpecification
56+
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = taskwait
57+
!PARSE-TREE: | OmpClauseList -> OmpClause -> Replayable -> OmpReplayableClause -> Scalar -> Logical -> Constant -> Expr = '.false._4'
58+
!PARSE-TREE: | | LiteralConstant -> LogicalLiteralConstant
59+
!PARSE-TREE: | | | bool = 'false'
60+
!PARSE-TREE: | Flags = None
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
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
3+
4+
subroutine f00(x)
5+
implicit none
6+
integer :: x
7+
!$omp target_data map(to: x) transparent
8+
block
9+
end block
10+
end
11+
12+
!UNPARSE: SUBROUTINE f00 (x)
13+
!UNPARSE: IMPLICIT NONE
14+
!UNPARSE: INTEGER x
15+
!UNPARSE: !$OMP TARGET_DATA MAP(TO: x) TRANSPARENT
16+
!UNPARSE: BLOCK
17+
!UNPARSE: END BLOCK
18+
!UNPARSE: END SUBROUTINE
19+
20+
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OmpBlockConstruct
21+
!PARSE-TREE: | OmpBeginDirective
22+
!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = target data
23+
!PARSE-TREE: | | OmpClauseList -> OmpClause -> Map -> OmpMapClause
24+
!PARSE-TREE: | | | Modifier -> OmpMapType -> Value = To
25+
!PARSE-TREE: | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x'
26+
!PARSE-TREE: | | | bool = 'true'
27+
!PARSE-TREE: | | OmpClause -> Transparent ->
28+
!PARSE-TREE: | | Flags = None
29+
!PARSE-TREE: | Block
30+
31+
32+
subroutine f01
33+
!$omp task transparent(0)
34+
!$omp end task
35+
end
36+
37+
!UNPARSE: SUBROUTINE f01
38+
!UNPARSE: !$OMP TASK TRANSPARENT(0_4)
39+
!UNPARSE: !$OMP END TASK
40+
!UNPARSE: END SUBROUTINE
41+
42+
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OmpBlockConstruct
43+
!PARSE-TREE: | OmpBeginDirective
44+
!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = task
45+
!PARSE-TREE: | | OmpClauseList -> OmpClause -> Transparent -> OmpTransparentClause -> Scalar -> Integer -> Expr = '0_4'
46+
!PARSE-TREE: | | | LiteralConstant -> IntLiteralConstant = '0'
47+
!PARSE-TREE: | | Flags = None
48+
!PARSE-TREE: | Block
49+
!PARSE-TREE: | OmpEndDirective
50+
!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = task
51+
!PARSE-TREE: | | OmpClauseList ->
52+
!PARSE-TREE: | | Flags = None
53+
54+
55+
subroutine f02
56+
implicit none
57+
integer :: i
58+
!$omp taskloop transparent(2)
59+
do i = 1, 10
60+
end do
61+
end
62+
63+
!UNPARSE: SUBROUTINE f02
64+
!UNPARSE: IMPLICIT NONE
65+
!UNPARSE: INTEGER i
66+
!UNPARSE: !$OMP TASKLOOP TRANSPARENT(2_4)
67+
!UNPARSE: DO i=1_4,10_4
68+
!UNPARSE: END DO
69+
!UNPARSE: END SUBROUTINE
70+
71+
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct
72+
!PARSE-TREE: | OmpBeginLoopDirective
73+
!PARSE-TREE: | | OmpLoopDirective -> llvm::omp::Directive = taskloop
74+
!PARSE-TREE: | | OmpClauseList -> OmpClause -> Transparent -> OmpTransparentClause -> Scalar -> Integer -> Expr = '2_4'
75+
!PARSE-TREE: | | | LiteralConstant -> IntLiteralConstant = '2'
76+
!PARSE-TREE: | DoConstruct
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=60
2+
3+
subroutine f00(x)
4+
implicit none
5+
logical :: x
6+
!ERROR: Must be a constant value
7+
!$omp task replayable(x)
8+
!$omp end task
9+
end
10+
11+
subroutine f01
12+
!ERROR: Must have LOGICAL type, but is INTEGER(4)
13+
!$omp task replayable(7)
14+
!$omp end task
15+
end
16+
17+
subroutine f02
18+
!No diagnostic expected
19+
!$omp task replayable
20+
!$omp end task
21+
end
22+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=60
2+
3+
subroutine f00(x)
4+
integer :: x(10)
5+
!ERROR: Must be a scalar value, but is a rank-1 array
6+
!$omp task transparent(x)
7+
!$omp end task
8+
end
9+
10+
subroutine f01
11+
implicit none
12+
integer :: i
13+
!ERROR: Must have INTEGER type, but is CHARACTER(KIND=1,LEN=5_8)
14+
!$omp taskloop transparent("hello")
15+
do i = 1, 10
16+
end do
17+
!$omp end taskloop
18+
end
19+

0 commit comments

Comments
 (0)