Skip to content

Commit 5030105

Browse files
[flang][OpenMP]Support for subroutine call for DECLARE REDUCTION init (#127889)
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 3dc7991 commit 5030105

File tree

9 files changed

+157
-11
lines changed

9 files changed

+157
-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
@@ -638,6 +638,8 @@ class ParseTreeDumper {
638638
NODE(parser, OmpReductionCombiner)
639639
NODE(parser, OmpTaskReductionClause)
640640
NODE(OmpTaskReductionClause, Modifier)
641+
NODE(parser, OmpReductionInitializerProc)
642+
NODE(parser, OmpReductionInitializerExpr)
641643
NODE(parser, OmpReductionInitializerClause)
642644
NODE(parser, OmpReductionIdentifier)
643645
NODE(parser, OmpAllocateClause)

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

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

46304630
// 2.16 declare-reduction -> DECLARE REDUCTION (reduction-identifier : type-list
46314631
// : combiner) [initializer-clause]
4632-
WRAPPER_CLASS(OmpReductionInitializerClause, Expr);
4632+
struct OmpReductionInitializerProc {
4633+
TUPLE_CLASS_BOILERPLATE(OmpReductionInitializerProc);
4634+
std::tuple<ProcedureDesignator, std::list<ActualArgSpec>> t;
4635+
};
4636+
WRAPPER_CLASS(OmpReductionInitializerExpr, Expr);
4637+
4638+
struct OmpReductionInitializerClause {
4639+
UNION_CLASS_BOILERPLATE(OmpReductionInitializerClause);
4640+
std::variant<OmpReductionInitializerProc, OmpReductionInitializerExpr> u;
4641+
};
46334642

46344643
struct OpenMPDeclareReductionConstruct {
46354644
TUPLE_CLASS_BOILERPLATE(OpenMPDeclareReductionConstruct);

flang/lib/Parser/openmp-parsers.cpp

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

1161+
TYPE_PARSER(construct<OmpReductionInitializerExpr>("OMP_PRIV =" >> expr))
1162+
TYPE_PARSER(
1163+
construct<OmpReductionInitializerProc>(Parser<ProcedureDesignator>{},
1164+
parenthesized(many(maybe(","_tok) >> Parser<ActualArgSpec>{}))))
1165+
11611166
TYPE_PARSER(construct<OmpReductionInitializerClause>(
1162-
"INITIALIZER" >> parenthesized("OMP_PRIV =" >> expr)))
1167+
"INITIALIZER" >> parenthesized(construct<OmpReductionInitializerClause>(
1168+
Parser<OmpReductionInitializerExpr>{}) ||
1169+
construct<OmpReductionInitializerClause>(
1170+
Parser<OmpReductionInitializerProc>{}))))
11631171

11641172
// 2.16 Declare Reduction Construct
11651173
TYPE_PARSER(sourced(construct<OpenMPDeclareReductionConstruct>(

flang/lib/Parser/unparse.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2699,9 +2699,19 @@ class UnparseVisitor {
26992699
void Unparse(const OmpDeclareTargetWithList &x) {
27002700
Put("("), Walk(x.v), Put(")");
27012701
}
2702-
void Unparse(const OmpReductionInitializerClause &x) {
2703-
Word(" INITIALIZER(OMP_PRIV = ");
2702+
void Unparse(const OmpReductionInitializerProc &x) {
2703+
Walk(std::get<ProcedureDesignator>(x.t));
2704+
Put("(");
2705+
Walk(std::get<std::list<ActualArgSpec>>(x.t));
2706+
Put(")");
2707+
}
2708+
void Unparse(const OmpReductionInitializerExpr &x) {
2709+
Word("OMP_PRIV = ");
27042710
Walk(x.v);
2711+
}
2712+
void Unparse(const OmpReductionInitializerClause &x) {
2713+
Word(" INITIALIZER(");
2714+
Walk(x.u);
27052715
Put(")");
27062716
}
27072717
void Unparse(const OpenMPDeclareReductionConstruct &x) {

flang/lib/Semantics/resolve-names.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1482,13 +1482,27 @@ 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+
context().Say(name.source,
1491+
"Implicit subroutine declaration '%s' in !$OMP DECLARE REDUCTION"_err_en_US,
1492+
name.source);
1493+
}
1494+
return true;
1495+
}
1496+
14851497
bool Pre(const parser::OpenMPDeclareReductionConstruct &x) {
14861498
AddOmpSourceRange(x.source);
14871499
parser::OmpClauseList emptyList{std::list<parser::OmpClause>{}};
14881500
ProcessReductionSpecifier(
14891501
std::get<Indirection<parser::OmpReductionSpecifier>>(x.t).value(),
14901502
emptyList);
1491-
Walk(std::get<std::optional<parser::OmpReductionInitializerClause>>(x.t));
1503+
auto &init =
1504+
std::get<std::optional<parser::OmpReductionInitializerClause>>(x.t);
1505+
Walk(init);
14921506
return false;
14931507
}
14941508
bool Pre(const parser::OmpMapClause &);
@@ -1741,15 +1755,13 @@ void OmpVisitor::ProcessMapperSpecifier(const parser::OmpMapperSpecifier &spec,
17411755
void OmpVisitor::ProcessReductionSpecifier(
17421756
const parser::OmpReductionSpecifier &spec,
17431757
const parser::OmpClauseList &clauses) {
1744-
BeginDeclTypeSpec();
17451758
const auto &id{std::get<parser::OmpReductionIdentifier>(spec.t)};
17461759
if (auto procDes{std::get_if<parser::ProcedureDesignator>(&id.u)}) {
17471760
if (auto *name{std::get_if<parser::Name>(&procDes->u)}) {
17481761
name->symbol =
17491762
&MakeSymbol(*name, MiscDetails{MiscDetails::Kind::ConstructName});
17501763
}
17511764
}
1752-
EndDeclTypeSpec();
17531765
// Creating a new scope in case the combiner expression (or clauses) use
17541766
// reerved identifiers, like "omp_in". This is a temporary solution until
17551767
// 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'
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
! RUN: not %flang_fc1 -emit-obj -fopenmp -fopenmp-version=50 %s 2>&1 | FileCheck %s
2+
3+
subroutine initme(x,n)
4+
integer x,n
5+
x=n
6+
end subroutine initme
7+
8+
subroutine subr
9+
!$omp declare reduction(red_add:integer(4):omp_out=omp_out+omp_in) initializer(initme(omp_priv,0))
10+
!CHECK: error: Implicit subroutine declaration 'initme' in !$OMP DECLARE REDUCTION
11+
end subroutine subr

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)