Skip to content

Commit f1d1dec

Browse files
[flang][OpenMP]Support for subroutine call for DECLARE REDUCTION init
The DECLARE REDUCTION allows the initialization part to be either an expression or a call to a subroutine. This modifies the parsing and semantic analysis to allow the use of the subroutine, in addition to the simple expression that was already supported. New tests in parser and semantics sections check that the generated structure is as expected. DECLARE REDUCTION lowering is not yet implemented, so will end in a TODO. A new test with an init subroutine is added, that checks that this variant also ends with a "Not yet implemented" message.
1 parent 0de2cca commit f1d1dec

File tree

8 files changed

+145
-11
lines changed

8 files changed

+145
-11
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,8 @@ class ParseTreeDumper {
631631
NODE(parser, OmpReductionCombiner)
632632
NODE(parser, OmpTaskReductionClause)
633633
NODE(OmpTaskReductionClause, Modifier)
634+
NODE(parser, OmpReductionInitializerProc)
635+
NODE(parser, OmpReductionInitializerExpr)
634636
NODE(parser, OmpReductionInitializerClause)
635637
NODE(parser, OmpReductionIdentifier)
636638
NODE(parser, OmpAllocateClause)

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4548,7 +4548,16 @@ struct OpenMPDeclareMapperConstruct {
45484548

45494549
// 2.16 declare-reduction -> DECLARE REDUCTION (reduction-identifier : type-list
45504550
// : combiner) [initializer-clause]
4551-
WRAPPER_CLASS(OmpReductionInitializerClause, Expr);
4551+
struct OmpReductionInitializerProc {
4552+
TUPLE_CLASS_BOILERPLATE(OmpReductionInitializerProc);
4553+
std::tuple<ProcedureDesignator, std::list<ActualArgSpec>> t;
4554+
};
4555+
WRAPPER_CLASS(OmpReductionInitializerExpr, Expr);
4556+
4557+
struct OmpReductionInitializerClause {
4558+
UNION_CLASS_BOILERPLATE(OmpReductionInitializerClause);
4559+
std::variant<OmpReductionInitializerProc, OmpReductionInitializerExpr> u;
4560+
};
45524561

45534562
struct OpenMPDeclareReductionConstruct {
45544563
TUPLE_CLASS_BOILERPLATE(OpenMPDeclareReductionConstruct);

flang/lib/Parser/openmp-parsers.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1142,8 +1142,16 @@ TYPE_PARSER(construct<OmpBlockDirective>(first(
11421142
TYPE_PARSER(sourced(construct<OmpBeginBlockDirective>(
11431143
sourced(Parser<OmpBlockDirective>{}), Parser<OmpClauseList>{})))
11441144

1145+
TYPE_PARSER(construct<OmpReductionInitializerExpr>("OMP_PRIV =" >> expr))
1146+
TYPE_PARSER(
1147+
construct<OmpReductionInitializerProc>(Parser<ProcedureDesignator>{},
1148+
parenthesized(many(maybe(","_tok) >> Parser<ActualArgSpec>{}))))
1149+
11451150
TYPE_PARSER(construct<OmpReductionInitializerClause>(
1146-
"INITIALIZER" >> parenthesized("OMP_PRIV =" >> expr)))
1151+
"INITIALIZER" >> parenthesized(construct<OmpReductionInitializerClause>(
1152+
Parser<OmpReductionInitializerExpr>{}) ||
1153+
construct<OmpReductionInitializerClause>(
1154+
Parser<OmpReductionInitializerProc>{}))))
11471155

11481156
// 2.16 Declare Reduction Construct
11491157
TYPE_PARSER(sourced(construct<OpenMPDeclareReductionConstruct>(

flang/lib/Parser/unparse.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2681,9 +2681,19 @@ class UnparseVisitor {
26812681
void Unparse(const OmpDeclareTargetWithList &x) {
26822682
Put("("), Walk(x.v), Put(")");
26832683
}
2684-
void Unparse(const OmpReductionInitializerClause &x) {
2685-
Word(" INITIALIZER(OMP_PRIV = ");
2684+
void Unparse(const OmpReductionInitializerProc &x) {
2685+
Walk(std::get<ProcedureDesignator>(x.t));
2686+
Put("(");
2687+
Walk(std::get<std::list<ActualArgSpec>>(x.t));
2688+
Put(")");
2689+
}
2690+
void Unparse(const OmpReductionInitializerExpr &x) {
2691+
Word("OMP_PRIV = ");
26862692
Walk(x.v);
2693+
}
2694+
void Unparse(const OmpReductionInitializerClause &x) {
2695+
Word(" INITIALIZER(");
2696+
Walk(x.u);
26872697
Put(")");
26882698
}
26892699
void Unparse(const OpenMPDeclareReductionConstruct &x) {

flang/lib/Semantics/resolve-names.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1482,13 +1482,26 @@ class OmpVisitor : public virtual DeclarationVisitor {
14821482
return false;
14831483
}
14841484

1485+
bool Pre(const parser::OmpReductionInitializerProc &x) {
1486+
auto &procDes = std::get<parser::ProcedureDesignator>(x.t);
1487+
auto &name = std::get<parser::Name>(procDes.u);
1488+
auto *symbol{FindSymbol(NonDerivedTypeScope(), name)};
1489+
if (!symbol) {
1490+
symbol = &MakeSymbol(context().globalScope(), name.source, Attrs{});
1491+
Resolve(name, *symbol);
1492+
}
1493+
return true;
1494+
}
1495+
14851496
bool Pre(const parser::OpenMPDeclareReductionConstruct &x) {
14861497
AddOmpSourceRange(x.source);
14871498
parser::OmpClauseList emptyList{std::list<parser::OmpClause>{}};
14881499
ProcessReductionSpecifier(
14891500
std::get<Indirection<parser::OmpReductionSpecifier>>(x.t).value(),
14901501
emptyList);
1491-
Walk(std::get<std::optional<parser::OmpReductionInitializerClause>>(x.t));
1502+
auto &init =
1503+
std::get<std::optional<parser::OmpReductionInitializerClause>>(x.t);
1504+
Walk(init);
14921505
return false;
14931506
}
14941507
bool Pre(const parser::OmpMapClause &);
@@ -1741,15 +1754,13 @@ void OmpVisitor::ProcessMapperSpecifier(const parser::OmpMapperSpecifier &spec,
17411754
void OmpVisitor::ProcessReductionSpecifier(
17421755
const parser::OmpReductionSpecifier &spec,
17431756
const parser::OmpClauseList &clauses) {
1744-
BeginDeclTypeSpec();
17451757
const auto &id{std::get<parser::OmpReductionIdentifier>(spec.t)};
17461758
if (auto procDes{std::get_if<parser::ProcedureDesignator>(&id.u)}) {
17471759
if (auto *name{std::get_if<parser::Name>(&procDes->u)}) {
17481760
name->symbol =
17491761
&MakeSymbol(*name, MiscDetails{MiscDetails::Kind::ConstructName});
17501762
}
17511763
}
1752-
EndDeclTypeSpec();
17531764
// Creating a new scope in case the combiner expression (or clauses) use
17541765
// reerved identifiers, like "omp_in". This is a temporary solution until
17551766
// we deal with these in a more thorough way.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
! This test checks lowering of OpenMP declare reduction Directive, with initialization
2+
! via a subroutine. This functionality is currently not implemented.
3+
4+
! RUN: not flang -fc1 -emit-fir -fopenmp %s 2>&1 | FileCheck %s
5+
6+
!CHECK: not yet implemented: OpenMPDeclareReductionConstruct
7+
subroutine initme(x,n)
8+
integer x,n
9+
x=n
10+
end subroutine initme
11+
12+
function func(x, n, init)
13+
integer func
14+
integer x(n)
15+
integer res
16+
interface
17+
subroutine initme(x,n)
18+
integer x,n
19+
end subroutine initme
20+
end interface
21+
!$omp declare reduction(red_add:integer(4):omp_out=omp_out+omp_in) initializer(initme(omp_priv,0))
22+
res=init
23+
!$omp simd reduction(red_add:res)
24+
do i=1,n
25+
res=res+x(i)
26+
enddo
27+
func=res
28+
end function func

flang/test/Parser/OpenMP/declare-reduction-unparse.f90

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,51 @@
11
! RUN: %flang_fc1 -fdebug-unparse -fopenmp %s | FileCheck --ignore-case %s
22
! RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp %s | FileCheck --check-prefix="PARSE-TREE" %s
3+
4+
!CHECK-LABEL: SUBROUTINE initme (x, n)
5+
subroutine initme(x,n)
6+
integer x,n
7+
x=n
8+
end subroutine initme
9+
!CHECK: END SUBROUTINE initme
10+
11+
!CHECK: FUNCTION func(x, n, init)
12+
function func(x, n, init)
13+
integer func
14+
integer x(n)
15+
integer res
16+
interface
17+
subroutine initme(x,n)
18+
integer x,n
19+
end subroutine initme
20+
end interface
21+
!CHECK: !$OMP DECLARE REDUCTION (red_add:INTEGER(KIND=4_4): omp_out=omp_out+omp_in
22+
!CHECK: ) INITIALIZER(initme(omp_priv, 0_4))
23+
!$omp declare reduction(red_add:integer(4):omp_out=omp_out+omp_in) initializer(initme(omp_priv,0))
24+
!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct
25+
!PARSE-TREE: OmpReductionCombiner -> AssignmentStmt = 'omp_out=omp_out+omp_in'
26+
!PARSE-TREE: OmpReductionInitializerClause -> OmpReductionInitializerProc
27+
!PARSE-TREE-NEXT: ProcedureDesignator -> Name = 'initme'
28+
res=init
29+
!$omp simd reduction(red_add:res)
30+
!CHECK: !$OMP SIMD REDUCTION(red_add: res)
31+
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct
32+
!PARSE-TREE: OmpBeginLoopDirective
33+
!PARSE-TREE: OmpLoopDirective -> llvm::omp::Directive = simd
34+
!PARSE-TREE: OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause
35+
!PARSE-TREE: Modifier -> OmpReductionIdentifier -> ProcedureDesignator -> Name = 'red_add
36+
do i=1,n
37+
res=res+x(i)
38+
enddo
39+
func=res
40+
end function func
41+
!CHECK: END FUNCTION func
42+
343
!CHECK-LABEL: program main
444
program main
545
integer :: my_var
6-
!CHECK: !$OMP DECLARE REDUCTION (my_add_red:INTEGER: omp_out=omp_out+omp_in
7-
!CHECK-NEXT: ) INITIALIZER(OMP_PRIV = 0_4)
8-
46+
!CHECK: !$OMP DECLARE REDUCTION (my_add_red:INTEGER: omp_out=omp_out+omp_in
47+
!CHECK-NEXT: ) INITIALIZER(OMP_PRIV = 0_4)
48+
949
!$omp declare reduction (my_add_red : integer : omp_out = omp_out + omp_in) initializer (omp_priv=0)
1050
my_var = 0
1151
!$omp parallel reduction (my_add_red : my_var) num_threads(4)
@@ -18,4 +58,4 @@ end program main
1858
!PARSE-TREE: OmpReductionIdentifier -> ProcedureDesignator -> Name = 'my_add_red'
1959
!PARSE-TREE: DeclarationTypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec
2060
!PARSE-TREE: OmpReductionCombiner -> AssignmentStmt = 'omp_out=omp_out+omp_in'
21-
!PARSE-TREE: OmpReductionInitializerClause -> Expr = '0_4'
61+
!PARSE-TREE: OmpReductionInitializerClause -> OmpReductionInitializerExpr -> Expr = '0_4'

flang/test/Semantics/OpenMP/declare-reduction.f90

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,31 @@
11
! RUN: %flang_fc1 -fdebug-dump-symbols -fopenmp -fopenmp-version=50 %s | FileCheck %s
22

3+
!CHECK-LABEL: Subprogram scope: initme
4+
subroutine initme(x,n)
5+
integer x,n
6+
x=n
7+
end subroutine initme
8+
9+
!CHECK-LABEL: Subprogram scope: func
10+
function func(x, n, init)
11+
integer func
12+
integer x(n)
13+
integer res
14+
interface
15+
subroutine initme(x,n)
16+
integer x,n
17+
end subroutine initme
18+
end interface
19+
!$omp declare reduction(red_add:integer(4):omp_out=omp_out+omp_in) initializer(initme(omp_priv,0))
20+
!CHECK: red_add: Misc ConstructName
21+
!CHECK: Subprogram scope: initme
22+
!$omp simd reduction(red_add:res)
23+
do i=1,n
24+
res=res+x(i)
25+
enddo
26+
func=res
27+
end function func
28+
329
program main
430
!CHECK-LABEL: MainProgram scope: main
531

0 commit comments

Comments
 (0)