Skip to content

Commit eaff8c5

Browse files
[flang][OpenMP]Add symbls omp_in, omp_out and omp_priv in DECLARE REDUCTION
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 9925359 commit eaff8c5

File tree

7 files changed

+57
-29
lines changed

7 files changed

+57
-29
lines changed

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

Lines changed: 0 additions & 1 deletion
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)

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4252,12 +4252,10 @@ struct OmpInitializerProc {
42524252
TUPLE_CLASS_BOILERPLATE(OmpInitializerProc);
42534253
std::tuple<ProcedureDesignator, std::list<ActualArgSpec>> t;
42544254
};
4255-
WRAPPER_CLASS(OmpInitializerExpr, Expr);
4256-
42574255
// Initialization for declare reduction construct
42584256
struct OmpInitializerClause {
42594257
UNION_CLASS_BOILERPLATE(OmpInitializerClause);
4260-
std::variant<OmpInitializerProc, OmpInitializerExpr> u;
4258+
std::variant<OmpInitializerProc, AssignmentStmt> u;
42614259
};
42624260

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

flang/lib/Parser/openmp-parsers.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,12 +1176,11 @@ TYPE_PARSER(construct<OmpBlockDirective>(first(
11761176
TYPE_PARSER(sourced(construct<OmpBeginBlockDirective>(
11771177
sourced(Parser<OmpBlockDirective>{}), Parser<OmpClauseList>{})))
11781178

1179-
TYPE_PARSER(construct<OmpInitializerExpr>("OMP_PRIV =" >> expr))
11801179
TYPE_PARSER(construct<OmpInitializerProc>(Parser<ProcedureDesignator>{},
11811180
parenthesized(many(maybe(","_tok) >> Parser<ActualArgSpec>{}))))
11821181

11831182
TYPE_PARSER(construct<OmpInitializerClause>(
1184-
construct<OmpInitializerClause>(Parser<OmpInitializerExpr>{}) ||
1183+
construct<OmpInitializerClause>(assignmentStmt) ||
11851184
construct<OmpInitializerClause>(Parser<OmpInitializerProc>{})))
11861185

11871186
// 2.16 Declare Reduction Construct

flang/lib/Parser/unparse.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2705,11 +2705,14 @@ class UnparseVisitor {
27052705
Walk(std::get<std::list<ActualArgSpec>>(x.t));
27062706
Put(")");
27072707
}
2708-
void Unparse(const OmpInitializerExpr &x) {
2709-
Word("OMP_PRIV = ");
2710-
Walk(x.v);
2708+
void Unparse(const OmpInitializerClause &x) {
2709+
// Don't let the visitor go to the normal AssignmentStmt Unparse function,
2710+
// it adds an extra newline that we don't want.
2711+
if (const auto *assignment = std::get_if<AssignmentStmt>(&x.u))
2712+
Walk(assignment->t, "=");
2713+
else
2714+
Walk(x.u);
27112715
}
2712-
void Unparse(const OmpInitializerClause &x) { Walk(x.u); }
27132716
void Unparse(const OpenMPDeclareReductionConstruct &x) {
27142717
BeginOpenMP();
27152718
Word("!$OMP DECLARE REDUCTION ");

flang/lib/Semantics/resolve-names.cpp

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1656,6 +1656,7 @@ class OmpVisitor : public virtual DeclarationVisitor {
16561656
const parser::OmpClauseList &clauses);
16571657
void ProcessReductionSpecifier(const parser::OmpReductionSpecifier &spec,
16581658
const std::optional<parser::OmpClauseList> &clauses);
1659+
void CreateTempSymbol(const parser::CharBlock &name, const DeclTypeSpec &dts);
16591660
};
16601661

16611662
bool OmpVisitor::NeedsScope(const parser::OpenMPBlockConstruct &x) {
@@ -1748,6 +1749,14 @@ void OmpVisitor::ProcessMapperSpecifier(const parser::OmpMapperSpecifier &spec,
17481749
PopScope();
17491750
}
17501751

1752+
void OmpVisitor::CreateTempSymbol(
1753+
const parser::CharBlock &name, const DeclTypeSpec &dts) {
1754+
ObjectEntityDetails details;
1755+
details.set_type(dts);
1756+
1757+
MakeSymbol(name, Attrs{}, std::move(details));
1758+
}
1759+
17511760
void OmpVisitor::ProcessReductionSpecifier(
17521761
const parser::OmpReductionSpecifier &spec,
17531762
const std::optional<parser::OmpClauseList> &clauses) {
@@ -1761,11 +1770,26 @@ void OmpVisitor::ProcessReductionSpecifier(
17611770
// Creating a new scope in case the combiner expression (or clauses) use
17621771
// reerved identifiers, like "omp_in". This is a temporary solution until
17631772
// 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();
1773+
auto &typeList = std::get<parser::OmpTypeNameList>(spec.t);
1774+
for (auto &t : typeList.v) {
1775+
PushScope(Scope::Kind::OtherConstruct, nullptr);
1776+
BeginDeclTypeSpec();
1777+
// We need to walk t.u because Walk(t) does it's own BeginDeclTypeSpec.
1778+
Walk(t.u);
1779+
1780+
auto *typeSpec = GetDeclTypeSpec();
1781+
assert(typeSpec && "We should have a type here");
1782+
const parser::CharBlock ompVarNames[] = {
1783+
{"omp_in", 6}, {"omp_out", 7}, {"omp_priv", 8}};
1784+
1785+
for (auto &nm : ompVarNames) {
1786+
CreateTempSymbol(nm, *typeSpec);
1787+
}
1788+
EndDeclTypeSpec();
1789+
Walk(std::get<std::optional<parser::OmpReductionCombiner>>(spec.t));
1790+
Walk(clauses);
1791+
PopScope();
1792+
}
17691793
}
17701794

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

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

Lines changed: 2 additions & 2 deletions
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'

flang/test/Parser/OpenMP/metadirective-dirspec.f90

Lines changed: 17 additions & 12 deletions
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

0 commit comments

Comments
 (0)