Skip to content

Commit d0188eb

Browse files
[flang][OpenMP]Add symbls omp_in, omp_out and omp_priv in DECLARE RED… (#129908)
…UCTION This patch allows better parsing of the reduction and initializer components, including supporting derived types in both those places. There is more work needed here, but this is a definite improvement in what can be handled through parser and semantics. Note that declare reduction is still not supported in lowering, so any attempt to compile DECLARE REDUCTION code will end with a TODO aka "Not yet implemented" abort in the compiler. Note that this version of the code does not cover declaring multiple reductions using the same name with different types. This is will be fixed in a future patch. [This was also the case before this change]. One existing test modified to actually compile (as it didn't in the original form).
1 parent 459b4e3 commit d0188eb

File tree

8 files changed

+78
-34
lines changed

8 files changed

+78
-34
lines changed

Diff for: flang/include/flang/Parser/dump-parse-tree.h

-1
Original file line numberDiff line numberDiff line change
@@ -639,7 +639,6 @@ class ParseTreeDumper {
639639
NODE(parser, OmpTaskReductionClause)
640640
NODE(OmpTaskReductionClause, Modifier)
641641
NODE(parser, OmpInitializerProc)
642-
NODE(parser, OmpInitializerExpr)
643642
NODE(parser, OmpInitializerClause)
644643
NODE(parser, OmpReductionIdentifier)
645644
NODE(parser, OmpAllocateClause)

Diff for: flang/include/flang/Parser/parse-tree.h

+1-3
Original file line numberDiff line numberDiff line change
@@ -4269,12 +4269,10 @@ struct OmpInitializerProc {
42694269
TUPLE_CLASS_BOILERPLATE(OmpInitializerProc);
42704270
std::tuple<ProcedureDesignator, std::list<ActualArgSpec>> t;
42714271
};
4272-
WRAPPER_CLASS(OmpInitializerExpr, Expr);
4273-
42744272
// Initialization for declare reduction construct
42754273
struct OmpInitializerClause {
42764274
UNION_CLASS_BOILERPLATE(OmpInitializerClause);
4277-
std::variant<OmpInitializerProc, OmpInitializerExpr> u;
4275+
std::variant<OmpInitializerProc, AssignmentStmt> u;
42784276
};
42794277

42804278
// Ref: [4.5:199-201], [5.0:288-290], [5.1:321-322], [5.2:115-117]

Diff for: flang/lib/Parser/openmp-parsers.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -1249,12 +1249,11 @@ TYPE_PARSER(construct<OmpBlockDirective>(first(
12491249
TYPE_PARSER(sourced(construct<OmpBeginBlockDirective>(
12501250
sourced(Parser<OmpBlockDirective>{}), Parser<OmpClauseList>{})))
12511251

1252-
TYPE_PARSER(construct<OmpInitializerExpr>("OMP_PRIV =" >> expr))
12531252
TYPE_PARSER(construct<OmpInitializerProc>(Parser<ProcedureDesignator>{},
12541253
parenthesized(many(maybe(","_tok) >> Parser<ActualArgSpec>{}))))
12551254

12561255
TYPE_PARSER(construct<OmpInitializerClause>(
1257-
construct<OmpInitializerClause>(Parser<OmpInitializerExpr>{}) ||
1256+
construct<OmpInitializerClause>(assignmentStmt) ||
12581257
construct<OmpInitializerClause>(Parser<OmpInitializerProc>{})))
12591258

12601259
// 2.16 Declare Reduction Construct

Diff for: flang/lib/Parser/unparse.cpp

+8-4
Original file line numberDiff line numberDiff line change
@@ -2721,11 +2721,15 @@ class UnparseVisitor {
27212721
Walk(std::get<std::list<ActualArgSpec>>(x.t));
27222722
Put(")");
27232723
}
2724-
void Unparse(const OmpInitializerExpr &x) {
2725-
Word("OMP_PRIV = ");
2726-
Walk(x.v);
2724+
void Unparse(const OmpInitializerClause &x) {
2725+
// Don't let the visitor go to the normal AssignmentStmt Unparse function,
2726+
// it adds an extra newline that we don't want.
2727+
if (const auto *assignment{std::get_if<AssignmentStmt>(&x.u)}) {
2728+
Walk(assignment->t, "=");
2729+
} else {
2730+
Walk(x.u);
2731+
}
27272732
}
2728-
void Unparse(const OmpInitializerClause &x) { Walk(x.u); }
27292733
void Unparse(const OpenMPDeclareReductionConstruct &x) {
27302734
BeginOpenMP();
27312735
Word("!$OMP DECLARE REDUCTION ");

Diff for: flang/lib/Semantics/resolve-names.cpp

+40-8
Original file line numberDiff line numberDiff line change
@@ -1758,14 +1758,46 @@ void OmpVisitor::ProcessReductionSpecifier(
17581758
&MakeSymbol(*name, MiscDetails{MiscDetails::Kind::ConstructName});
17591759
}
17601760
}
1761-
// Creating a new scope in case the combiner expression (or clauses) use
1762-
// reerved identifiers, like "omp_in". This is a temporary solution until
1763-
// we deal with these in a more thorough way.
1764-
PushScope(Scope::Kind::OtherConstruct, nullptr);
1765-
Walk(std::get<parser::OmpTypeNameList>(spec.t));
1766-
Walk(std::get<std::optional<parser::OmpReductionCombiner>>(spec.t));
1767-
Walk(clauses);
1768-
PopScope();
1761+
1762+
auto &typeList{std::get<parser::OmpTypeNameList>(spec.t)};
1763+
1764+
// Create a temporary variable declaration for the four variables
1765+
// used in the reduction specifier and initializer (omp_out, omp_in,
1766+
// omp_priv and omp_orig), with the type in the typeList.
1767+
//
1768+
// In theory it would be possible to create only variables that are
1769+
// actually used, but that requires walking the entire parse-tree of the
1770+
// expressions, and finding the relevant variables [there may well be other
1771+
// variables involved too].
1772+
//
1773+
// This allows doing semantic analysis where the type is a derived type
1774+
// e.g omp_out%x = omp_out%x + omp_in%x.
1775+
//
1776+
// These need to be temporary (in their own scope). If they are created
1777+
// as variables in the outer scope, if there's more than one type in the
1778+
// typelist, duplicate symbols will be reported.
1779+
const parser::CharBlock ompVarNames[]{
1780+
{"omp_in", 6}, {"omp_out", 7}, {"omp_priv", 8}, {"omp_orig", 8}};
1781+
1782+
for (auto &t : typeList.v) {
1783+
PushScope(Scope::Kind::OtherConstruct, nullptr);
1784+
BeginDeclTypeSpec();
1785+
// We need to walk t.u because Walk(t) does it's own BeginDeclTypeSpec.
1786+
Walk(t.u);
1787+
1788+
const DeclTypeSpec *typeSpec{GetDeclTypeSpec()};
1789+
assert(typeSpec && "We should have a type here");
1790+
1791+
for (auto &nm : ompVarNames) {
1792+
ObjectEntityDetails details{};
1793+
details.set_type(*typeSpec);
1794+
MakeSymbol(nm, Attrs{}, std::move(details));
1795+
}
1796+
EndDeclTypeSpec();
1797+
Walk(std::get<std::optional<parser::OmpReductionCombiner>>(spec.t));
1798+
Walk(clauses);
1799+
PopScope();
1800+
}
17691801
}
17701802

17711803
bool OmpVisitor::Pre(const parser::OmpDirectiveSpecification &x) {

Diff for: flang/test/Parser/OpenMP/declare-reduction-unparse.f90

+2-2
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ end function func
4444
program main
4545
integer :: my_var
4646
!CHECK: !$OMP DECLARE REDUCTION (my_add_red:INTEGER: omp_out=omp_out+omp_in
47-
!CHECK-NEXT: ) INITIALIZER(OMP_PRIV = 0_4)
47+
!CHECK-NEXT: ) INITIALIZER(omp_priv=0_4)
4848

4949
!$omp declare reduction (my_add_red : integer : omp_out = omp_out + omp_in) initializer (omp_priv=0)
5050
my_var = 0
@@ -58,4 +58,4 @@ end program main
5858
!PARSE-TREE: OmpReductionIdentifier -> ProcedureDesignator -> Name = 'my_add_red'
5959
!PARSE-TREE: DeclarationTypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec
6060
!PARSE-TREE: OmpReductionCombiner -> AssignmentStmt = 'omp_out=omp_out+omp_in'
61-
!PARSE-TREE: OmpInitializerClause -> OmpInitializerExpr -> Expr = '0_4'
61+
!PARSE-TREE: OmpInitializerClause -> AssignmentStmt = 'omp_priv=0_4'

Diff for: flang/test/Parser/OpenMP/metadirective-dirspec.f90

+17-12
Original file line numberDiff line numberDiff line change
@@ -92,20 +92,20 @@ subroutine f03
9292
integer :: x
9393
endtype
9494
type :: tt2
95-
real :: a
95+
real :: x
9696
endtype
9797
!$omp metadirective when(user={condition(.true.)}: &
98-
!$omp & declare reduction(+ : tt1, tt2 : omp_out = omp_in + omp_out))
98+
!$omp & declare reduction(+ : tt1, tt2 : omp_out%x = omp_in%x + omp_out%x))
9999
end
100100

101101
!UNPARSE: SUBROUTINE f03
102102
!UNPARSE: TYPE :: tt1
103103
!UNPARSE: INTEGER :: x
104104
!UNPARSE: END TYPE
105105
!UNPARSE: TYPE :: tt2
106-
!UNPARSE: REAL :: a
106+
!UNPARSE: REAL :: x
107107
!UNPARSE: END TYPE
108-
!UNPARSE: !$OMP METADIRECTIVE WHEN(USER={CONDITION(.true._4)}: DECLARE REDUCTION(+:tt1,tt2: omp_out=omp_in+omp_out
108+
!UNPARSE: !$OMP METADIRECTIVE WHEN(USER={CONDITION(.true._4)}: DECLARE REDUCTION(+:tt1,tt2: omp_out%x=omp_in%x+omp_out%x
109109
!UNPARSE: ))
110110
!UNPARSE: END SUBROUTINE
111111

@@ -127,15 +127,20 @@ subroutine f03
127127
!PARSE-TREE: | | | | | Name = 'tt1'
128128
!PARSE-TREE: | | | | OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec
129129
!PARSE-TREE: | | | | | Name = 'tt2'
130-
!PARSE-TREE: | | | | OmpReductionCombiner -> AssignmentStmt = 'omp_out=omp_in+omp_out'
131-
!PARSE-TREE: | | | | | Variable = 'omp_out'
132-
!PARSE-TREE: | | | | | | Designator -> DataRef -> Name = 'omp_out'
133-
!PARSE-TREE: | | | | | Expr = 'omp_in+omp_out'
130+
!PARSE-TREE: | | | | OmpReductionCombiner -> AssignmentStmt = 'omp_out%x=omp_in%x+omp_out%x'
131+
!PARSE-TREE: | | | | | | Designator -> DataRef -> StructureComponent
132+
!PARSE-TREE: | | | | | | | DataRef -> Name = 'omp_out'
133+
!PARSE-TREE: | | | | | | | Name = 'x'
134+
!PARSE-TREE: | | | | | Expr = 'omp_in%x+omp_out%x'
134135
!PARSE-TREE: | | | | | | Add
135-
!PARSE-TREE: | | | | | | | Expr = 'omp_in'
136-
!PARSE-TREE: | | | | | | | | Designator -> DataRef -> Name = 'omp_in'
137-
!PARSE-TREE: | | | | | | | Expr = 'omp_out'
138-
!PARSE-TREE: | | | | | | | | Designator -> DataRef -> Name = 'omp_out'
136+
!PARSE-TREE: | | | | | | | Expr = 'omp_in%x'
137+
!PARSE-TREE: | | | | | | | | Designator -> DataRef -> StructureComponent
138+
!PARSE-TREE: | | | | | | | | | DataRef -> Name = 'omp_in'
139+
!PARSE-TREE: | | | | | | | | | Name = 'x'
140+
!PARSE-TREE: | | | | | | | Expr = 'omp_out%x'
141+
!PARSE-TREE: | | | | | | | | Designator -> DataRef -> StructureComponent
142+
!PARSE-TREE: | | | | | | | | | DataRef -> Name = 'omp_out'
143+
!PARSE-TREE: | | | | | | | | | Name = 'x'
139144
!PARSE-TREE: | | | OmpClauseList ->
140145

141146
subroutine f04

Diff for: flang/test/Semantics/OpenMP/declare-reduction.f90

+9-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ end subroutine initme
1818
end interface
1919
!$omp declare reduction(red_add:integer(4):omp_out=omp_out+omp_in) initializer(initme(omp_priv,0))
2020
!CHECK: red_add: Misc ConstructName
21-
!CHECK: Subprogram scope: initme
21+
!CHECK: Subprogram scope: initme
22+
!CHECK: omp_in size=4 offset=0: ObjectEntity type: INTEGER(4)
23+
!CHECK: omp_orig size=4 offset=4: ObjectEntity type: INTEGER(4)
24+
!CHECK: omp_out size=4 offset=8: ObjectEntity type: INTEGER(4)
25+
!CHECK: omp_priv size=4 offset=12: ObjectEntity type: INTEGER(4)
2226
!$omp simd reduction(red_add:res)
2327
do i=1,n
2428
res=res+x(i)
@@ -32,6 +36,9 @@ program main
3236
!$omp declare reduction (my_add_red : integer : omp_out = omp_out + omp_in) initializer (omp_priv=0)
3337

3438
!CHECK: my_add_red: Misc ConstructName
39+
!CHECK: omp_in size=4 offset=0: ObjectEntity type: INTEGER(4)
40+
!CHECK: omp_orig size=4 offset=4: ObjectEntity type: INTEGER(4)
41+
!CHECK: omp_out size=4 offset=8: ObjectEntity type: INTEGER(4)
42+
!CHECK: omp_priv size=4 offset=12: ObjectEntity type: INTEGER(4)
3543

3644
end program main
37-

0 commit comments

Comments
 (0)