Skip to content

Commit 5197006

Browse files
committed
[Flang][OpenMP] Add Parsing support for Indirect Clause
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 fb054e6 commit 5197006

File tree

12 files changed

+179
-3
lines changed

12 files changed

+179
-3
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,7 @@ class ParseTreeDumper {
574574
NODE_ENUM(OmpDependenceType, Value)
575575
NODE(parser, OmpTaskDependenceType)
576576
NODE_ENUM(OmpTaskDependenceType, Value)
577+
NODE(parser, OmpIndirectClause)
577578
NODE(parser, OmpIterationOffset)
578579
NODE(parser, OmpIteration)
579580
NODE(parser, OmpIterationVector)

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

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

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

flang/lib/Lower/OpenMP/Clauses.cpp

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

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

913913
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
@@ -996,6 +996,8 @@ TYPE_PARSER( //
996996
"IF" >> construct<OmpClause>(construct<OmpClause::If>(
997997
parenthesized(Parser<OmpIfClause>{}))) ||
998998
"INBRANCH" >> construct<OmpClause>(construct<OmpClause::Inbranch>()) ||
999+
"INDIRECT" >> construct<OmpClause>(construct<OmpClause::Indirect>(
1000+
maybe(parenthesized(scalarLogicalExpr)))) ||
9991001
"INIT" >> construct<OmpClause>(construct<OmpClause::Init>(
10001002
parenthesized(Parser<OmpInitClause>{}))) ||
10011003
"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
@@ -1812,15 +1812,24 @@ void OmpStructureChecker::Leave(const parser::OmpDeclareTargetWithClause &x) {
18121812
const parser::OmpClause *toClause = FindClause(llvm::omp::Clause::OMPC_to);
18131813
const parser::OmpClause *linkClause =
18141814
FindClause(llvm::omp::Clause::OMPC_link);
1815+
const parser::OmpClause *indirectClause = FindClause(llvm::omp::Clause::OMPC_indirect);
18151816
if (!enterClause && !toClause && !linkClause) {
18161817
context_.Say(x.source,
18171818
"If the DECLARE TARGET directive has a clause, it must contain at least one ENTER clause or LINK clause"_err_en_US);
18181819
}
1820+
if (indirectClause && !enterClause) {
1821+
context_.Say(x.source,
1822+
"The INDIRECT clause cannot be used without the ENTER clause with the DECLARE TARGET directive."_err_en_US);
1823+
}
18191824
unsigned version{context_.langOptions().OpenMPVersion};
18201825
if (toClause && version >= 52) {
18211826
context_.Warn(common::UsageWarning::OpenMPUsage, toClause->source,
18221827
"The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead."_warn_en_US);
18231828
}
1829+
if(indirectClause && version < 51) {
1830+
context_.Say(x.source,
1831+
"The usage of INDIRECT clause on DECLARE TARGET directive is only supported on OpenMP Version 5.1 or greater"_err_en_US);
1832+
}
18241833
}
18251834
}
18261835

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ class OmpStructureChecker
243243
void CheckSymbolNames(
244244
const parser::CharBlock &source, const parser::OmpObjectList &objList);
245245
void CheckIntentInPointer(SymbolSourceMap &, const llvm::omp::Clause);
246+
void MakeScalarLogicalTrue(const parser::OmpClause *clause);
246247
void CheckProcedurePointer(SymbolSourceMap &, const llvm::omp::Clause);
247248
void CheckCrayPointee(const parser::OmpObjectList &objectList,
248249
llvm::StringRef clause, bool suggestToUseCrayPointer = true);
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: The usage of INDIRECT clause on DECLARE TARGET directive is only supported on OpenMP Version 5.1 or greater
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: 1 addition & 0 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";

0 commit comments

Comments
 (0)