Skip to content

Commit cb355de

Browse files
authored
[Flang][OpenMP] Add Parsing support for Indirect Clause (#143505)
As part of OpenMP Version 5.1, support for the `indirect` clause was added for the `declare target` directive. This clause should follow an `enter` clause, and allows procedure calls to be done indirectly through OpenMP. This adds Parsing support for the clause, along with semantics checks. Currently, lowering for the clause is not supported so a TODO message will be outputted to the user. It also performs version checking as `indirect` is only support in OpenMP 5.1 or greater. See also: #110008
1 parent c564ebb commit cb355de

File tree

11 files changed

+181
-5
lines changed

11 files changed

+181
-5
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,7 @@ class ParseTreeDumper {
565565
NODE_ENUM(OmpDependenceType, Value)
566566
NODE(parser, OmpTaskDependenceType)
567567
NODE_ENUM(OmpTaskDependenceType, Value)
568+
NODE(parser, OmpIndirectClause)
568569
NODE(parser, OmpIterationOffset)
569570
NODE(parser, OmpIteration)
570571
NODE(parser, OmpIterationVector)

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4300,6 +4300,12 @@ struct OmpHoldsClause {
43004300
WRAPPER_CLASS_BOILERPLATE(OmpHoldsClause, common::Indirection<Expr>);
43014301
};
43024302

4303+
// Ref: [5.2: 209]
4304+
struct OmpIndirectClause {
4305+
WRAPPER_CLASS_BOILERPLATE(
4306+
OmpIndirectClause, std::optional<ScalarLogicalExpr>);
4307+
};
4308+
43034309
// Ref: [5.2:72-73], in 4.5-5.1 it's scattered over individual directives
43044310
// that allow the IF clause.
43054311
//

flang/lib/Lower/OpenMP/Clauses.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -905,8 +905,8 @@ Inclusive make(const parser::OmpClause::Inclusive &inp,
905905

906906
Indirect make(const parser::OmpClause::Indirect &inp,
907907
semantics::SemanticsContext &semaCtx) {
908-
// inp -> empty
909-
llvm_unreachable("Empty: indirect");
908+
// inp.v.v -> std::optional<parser::ScalarLogicalExpr>
909+
return Indirect{maybeApply(makeExprFn(semaCtx), inp.v.v)};
910910
}
911911

912912
Init make(const parser::OmpClause::Init &inp,

flang/lib/Parser/openmp-parsers.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,6 +1004,8 @@ TYPE_PARSER( //
10041004
"IF" >> construct<OmpClause>(construct<OmpClause::If>(
10051005
parenthesized(Parser<OmpIfClause>{}))) ||
10061006
"INBRANCH" >> construct<OmpClause>(construct<OmpClause::Inbranch>()) ||
1007+
"INDIRECT" >> construct<OmpClause>(construct<OmpClause::Indirect>(
1008+
maybe(parenthesized(scalarLogicalExpr)))) ||
10071009
"INIT" >> construct<OmpClause>(construct<OmpClause::Init>(
10081010
parenthesized(Parser<OmpInitClause>{}))) ||
10091011
"INCLUSIVE" >> construct<OmpClause>(construct<OmpClause::Inclusive>(

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1820,15 +1820,24 @@ void OmpStructureChecker::Leave(const parser::OmpDeclareTargetWithClause &x) {
18201820
const parser::OmpClause *toClause = FindClause(llvm::omp::Clause::OMPC_to);
18211821
const parser::OmpClause *linkClause =
18221822
FindClause(llvm::omp::Clause::OMPC_link);
1823+
const parser::OmpClause *indirectClause =
1824+
FindClause(llvm::omp::Clause::OMPC_indirect);
18231825
if (!enterClause && !toClause && !linkClause) {
18241826
context_.Say(x.source,
18251827
"If the DECLARE TARGET directive has a clause, it must contain at least one ENTER clause or LINK clause"_err_en_US);
18261828
}
1829+
if (indirectClause && !enterClause) {
1830+
context_.Say(x.source,
1831+
"The INDIRECT clause cannot be used without the ENTER clause with the DECLARE TARGET directive."_err_en_US);
1832+
}
18271833
unsigned version{context_.langOptions().OpenMPVersion};
18281834
if (toClause && version >= 52) {
18291835
context_.Warn(common::UsageWarning::OpenMPUsage, toClause->source,
18301836
"The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead."_warn_en_US);
18311837
}
1838+
if (indirectClause) {
1839+
CheckAllowedClause(llvm::omp::Clause::OMPC_indirect);
1840+
}
18321841
}
18331842
}
18341843

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
! This test checks the lowering of OpenMP Indirect Clause when used with the Declare Target directive
2+
3+
! RUN: not flang -fc1 -emit-fir -fopenmp -fopenmp-version=52 %s 2>&1 | FileCheck %s
4+
5+
module functions
6+
implicit none
7+
8+
interface
9+
function func() result(i)
10+
character(1) :: i
11+
end function
12+
end interface
13+
14+
contains
15+
function func1() result(i)
16+
!CHECK: not yet implemented: Unhandled clause INDIRECT in DECLARE TARGET construct
17+
!$omp declare target enter(func1) indirect(.true.)
18+
character(1) :: i
19+
i = 'a'
20+
return
21+
end function
22+
end module
23+
24+
program main
25+
use functions
26+
implicit none
27+
procedure (func), pointer :: ptr1=>func1
28+
character(1) :: val1
29+
30+
!$omp target map(from: val1)
31+
val1 = ptr1()
32+
!$omp end target
33+
34+
end program
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
! REQUIRES: openmp_runtime
2+
3+
! RUN: %flang_fc1 %openmp_flags -fopenmp-version=52 -fdebug-dump-parse-tree %s | FileCheck %s
4+
! RUN: %flang_fc1 %openmp_flags -fdebug-unparse -fopenmp-version=52 %s | FileCheck %s --check-prefix="UNPARSE"
5+
6+
module functions
7+
implicit none
8+
9+
interface
10+
function func() result(i)
11+
character(1) :: i
12+
end function
13+
end interface
14+
15+
contains
16+
function func1() result(i)
17+
!$omp declare target enter(func1) indirect(.true.)
18+
!CHECK: | | | | | OmpDeclareTargetSpecifier -> OmpDeclareTargetWithClause -> OmpClauseList -> OmpClause -> Enter -> OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'func1'
19+
!CHECK-NEXT: | | | | | OmpClause -> Indirect -> OmpIndirectClause -> Scalar -> Logical -> Expr = '.true._4'
20+
!CHECK-NEXT: | | | | | | LiteralConstant -> LogicalLiteralConstant
21+
!CHECK-NEXT: | | | | | | | bool = 'true'
22+
character(1) :: i
23+
i = 'a'
24+
return
25+
end function
26+
27+
function func2() result(i)
28+
!$omp declare target enter(func2) indirect
29+
!CHECK: | | | | | OmpDeclareTargetSpecifier -> OmpDeclareTargetWithClause -> OmpClauseList -> OmpClause -> Enter -> OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'func2'
30+
!CHECK-NEXT: | | | | | OmpClause -> Indirect -> OmpIndirectClause ->
31+
character(1) :: i
32+
i = 'b'
33+
return
34+
end function
35+
end module
36+
37+
program main
38+
use functions
39+
implicit none
40+
procedure (func), pointer :: ptr1=>func1, ptr2=>func2
41+
character(1) :: val1, val2
42+
43+
!$omp target map(from: val1)
44+
val1 = ptr1()
45+
!$omp end target
46+
!$omp target map(from: val2)
47+
val2 = ptr2()
48+
!$omp end target
49+
50+
end program
51+
52+
!UNPARSE: !$OMP DECLARE TARGET ENTER(func1) INDIRECT(.true._4)
53+
!UNPARSE: !$OMP DECLARE TARGET ENTER(func2) INDIRECT()

flang/test/Semantics/indirect01.f90

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
! This test checks the lowering of OpenMP Indirect Clause when used with the Declare Target directive
2+
3+
! RUN: not flang -fopenmp -fopenmp-version=52 %s 2>&1 | FileCheck %s
4+
5+
module functions
6+
implicit none
7+
8+
interface
9+
function func() result(i)
10+
character(1) :: i
11+
end function
12+
end interface
13+
14+
contains
15+
function func1() result(i)
16+
!CHECK: The INDIRECT clause cannot be used without the ENTER clause with the DECLARE TARGET directive.
17+
!$omp declare target indirect(.true.)
18+
character(1) :: i
19+
i = 'a'
20+
return
21+
end function
22+
end module
23+
24+
program main
25+
use functions
26+
implicit none
27+
procedure (func), pointer :: ptr1=>func1
28+
character(1) :: val1
29+
30+
!$omp target map(from: val1)
31+
val1 = ptr1()
32+
!$omp end target
33+
34+
end program

flang/test/Semantics/indirect02.f90

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
! This test checks the lowering of OpenMP Indirect Clause when used with the Declare Target directive
2+
3+
! RUN: not flang -fopenmp -fopenmp-version=50 %s 2>&1 | FileCheck %s --check-prefix="CHECK-50"
4+
! RUN: not flang -fopenmp -fopenmp-version=52 %s 2>&1 | FileCheck %s --check-prefix="CHECK-52"
5+
6+
module functions
7+
implicit none
8+
9+
interface
10+
function func() result(i)
11+
character(1) :: i
12+
end function
13+
end interface
14+
15+
contains
16+
function func1() result(i)
17+
!CHECK-50: INDIRECT clause is not allowed on directive DECLARE TARGET in OpenMP v5.0, try -fopenmp-version=51
18+
!CHECK-52: not yet implemented: Unhandled clause INDIRECT in DECLARE TARGET construct
19+
!$omp declare target enter(func1) indirect(.true.)
20+
character(1) :: i
21+
i = 'a'
22+
return
23+
end function
24+
end module
25+
26+
program main
27+
use functions
28+
implicit none
29+
procedure (func), pointer :: ptr1=>func1
30+
character(1) :: val1
31+
32+
!$omp target map(from: val1)
33+
val1 = ptr1()
34+
!$omp end target
35+
36+
end program

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -701,7 +701,7 @@ template <typename T, typename I, typename E> //
701701
struct IndirectT {
702702
using InvokedByFptr = E;
703703
using WrapperTrait = std::true_type;
704-
InvokedByFptr v;
704+
OPT(InvokedByFptr) v;
705705
};
706706

707707
// V5.2: [14.1.2] `init` clause

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ def OMPC_Inclusive : Clause<[Spelling<"inclusive">]> {
246246
let flangClass = "OmpObjectList";
247247
}
248248
def OMPC_Indirect : Clause<[Spelling<"indirect">]> {
249+
let flangClass = "OmpIndirectClause";
249250
}
250251
def OMPC_Init : Clause<[Spelling<"init">]> {
251252
let clangClass = "OMPInitClause";
@@ -646,7 +647,7 @@ def OMP_EndAssumes : Directive<[Spelling<"end assumes">]> {
646647
def OMP_BeginDeclareTarget : Directive<[Spelling<"begin declare target">]> {
647648
let allowedClauses = [
648649
VersionedClause<OMPC_DeviceType>,
649-
VersionedClause<OMPC_Indirect>,
650+
VersionedClause<OMPC_Indirect, 51>,
650651
VersionedClause<OMPC_Link>,
651652
VersionedClause<OMPC_To>,
652653
];
@@ -724,7 +725,7 @@ def OMP_DeclareSimd : Directive<[Spelling<"declare simd">]> {
724725
def OMP_DeclareTarget : Directive<[Spelling<"declare target">]> {
725726
let allowedClauses = [
726727
VersionedClause<OMPC_Enter, 52>,
727-
VersionedClause<OMPC_Indirect>,
728+
VersionedClause<OMPC_Indirect, 51>,
728729
VersionedClause<OMPC_Link>,
729730
VersionedClause<OMPC_To>,
730731
];

0 commit comments

Comments
 (0)