Skip to content

Commit 3af717d

Browse files
authored
[flang] Add parsing of DO CONCURRENT REDUCE clause (#92518)
Derived from #92480. This PR supports parsing of the DO CONCURRENT REDUCE clause in Fortran 2023. Following the style of the OpenMP parser in MLIR, the front end accepts both arbitrary operations and procedures for the REDUCE clause. But later Semantics can notify type errors and resolve procedure names.
1 parent 485f9f5 commit 3af717d

15 files changed

+433
-155
lines changed

flang/examples/FeatureList/FeatureList.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,6 @@ struct NodeVisitor {
8686
READ_FEATURE(AccObjectList)
8787
READ_FEATURE(AccObjectListWithModifier)
8888
READ_FEATURE(AccObjectListWithReduction)
89-
READ_FEATURE(AccReductionOperator)
90-
READ_FEATURE(AccReductionOperator::Operator)
9189
READ_FEATURE(AccSizeExpr)
9290
READ_FEATURE(AccSizeExprList)
9391
READ_FEATURE(AccSelfClause)
@@ -410,10 +408,13 @@ struct NodeVisitor {
410408
READ_FEATURE(LetterSpec)
411409
READ_FEATURE(LiteralConstant)
412410
READ_FEATURE(IntLiteralConstant)
411+
READ_FEATURE(ReductionOperator)
412+
READ_FEATURE(ReductionOperator::Operator)
413413
READ_FEATURE(LocalitySpec)
414414
READ_FEATURE(LocalitySpec::DefaultNone)
415415
READ_FEATURE(LocalitySpec::Local)
416416
READ_FEATURE(LocalitySpec::LocalInit)
417+
READ_FEATURE(LocalitySpec::Reduce)
417418
READ_FEATURE(LocalitySpec::Shared)
418419
READ_FEATURE(LockStmt)
419420
READ_FEATURE(LockStmt::LockStat)

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,6 @@ class ParseTreeDumper {
9595
NODE(parser, AccObjectList)
9696
NODE(parser, AccObjectListWithModifier)
9797
NODE(parser, AccObjectListWithReduction)
98-
NODE(parser, AccReductionOperator)
99-
NODE_ENUM(parser::AccReductionOperator, Operator)
10098
NODE(parser, AccSizeExpr)
10199
NODE(parser, AccSizeExprList)
102100
NODE(parser, AccSelfClause)
@@ -436,10 +434,13 @@ class ParseTreeDumper {
436434
NODE(parser, LetterSpec)
437435
NODE(parser, LiteralConstant)
438436
NODE(parser, IntLiteralConstant)
437+
NODE(parser, ReductionOperator)
438+
NODE_ENUM(parser::ReductionOperator, Operator)
439439
NODE(parser, LocalitySpec)
440440
NODE(LocalitySpec, DefaultNone)
441441
NODE(LocalitySpec, Local)
442442
NODE(LocalitySpec, LocalInit)
443+
NODE(LocalitySpec, Reduce)
443444
NODE(LocalitySpec, Shared)
444445
NODE(parser, LockStmt)
445446
NODE(LockStmt, LockStat)

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

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2236,16 +2236,34 @@ struct ConcurrentHeader {
22362236
t;
22372237
};
22382238

2239+
// F'2023 R1131 reduce-operation -> reduction-operator
2240+
// CUF reduction-op -> reduction-operator
2241+
// OpenACC 3.3 2.5.15 reduction-operator ->
2242+
// + | * | .AND. | .OR. | .EQV. | .NEQV. |
2243+
// MAX | MIN | IAND | IOR | IEOR
2244+
struct ReductionOperator {
2245+
ENUM_CLASS(
2246+
Operator, Plus, Multiply, Max, Min, Iand, Ior, Ieor, And, Or, Eqv, Neqv)
2247+
WRAPPER_CLASS_BOILERPLATE(ReductionOperator, Operator);
2248+
CharBlock source;
2249+
};
2250+
22392251
// R1130 locality-spec ->
22402252
// LOCAL ( variable-name-list ) | LOCAL_INIT ( variable-name-list ) |
2253+
// REDUCE ( reduce-operation : variable-name-list ) |
22412254
// SHARED ( variable-name-list ) | DEFAULT ( NONE )
22422255
struct LocalitySpec {
22432256
UNION_CLASS_BOILERPLATE(LocalitySpec);
22442257
WRAPPER_CLASS(Local, std::list<Name>);
22452258
WRAPPER_CLASS(LocalInit, std::list<Name>);
2259+
struct Reduce {
2260+
TUPLE_CLASS_BOILERPLATE(Reduce);
2261+
using Operator = ReductionOperator;
2262+
std::tuple<Operator, std::list<Name>> t;
2263+
};
22462264
WRAPPER_CLASS(Shared, std::list<Name>);
22472265
EMPTY_CLASS(DefaultNone);
2248-
std::variant<Local, LocalInit, Shared, DefaultNone> u;
2266+
std::variant<Local, LocalInit, Reduce, Shared, DefaultNone> u;
22492267
};
22502268

22512269
// R1123 loop-control ->
@@ -4066,17 +4084,9 @@ struct AccObjectListWithModifier {
40664084
std::tuple<std::optional<AccDataModifier>, AccObjectList> t;
40674085
};
40684086

4069-
// 2.5.15: + | * | max | min | iand | ior | ieor | .and. | .or. | .eqv. | .neqv.
4070-
struct AccReductionOperator {
4071-
ENUM_CLASS(
4072-
Operator, Plus, Multiply, Max, Min, Iand, Ior, Ieor, And, Or, Eqv, Neqv)
4073-
WRAPPER_CLASS_BOILERPLATE(AccReductionOperator, Operator);
4074-
CharBlock source;
4075-
};
4076-
40774087
struct AccObjectListWithReduction {
40784088
TUPLE_CLASS_BOILERPLATE(AccObjectListWithReduction);
4079-
std::tuple<AccReductionOperator, AccObjectList> t;
4089+
std::tuple<ReductionOperator, AccObjectList> t;
40804090
};
40814091

40824092
struct AccWaitArgument {
@@ -4312,11 +4322,11 @@ struct OpenACCConstruct {
43124322
// block -> * | scalar-int-expr | ( star-or-expr-list )
43134323
// stream -> 0, scalar-int-expr | STREAM = scalar-int-expr
43144324
// cuf-reduction -> [ REDUCE | REDUCTION ] (
4315-
// acc-reduction-op : scalar-variable-list )
4325+
// reduction-op : scalar-variable-list )
43164326

43174327
struct CUFReduction {
43184328
TUPLE_CLASS_BOILERPLATE(CUFReduction);
4319-
using Operator = AccReductionOperator;
4329+
using Operator = ReductionOperator;
43204330
std::tuple<Operator, std::list<Scalar<Variable>>> t;
43214331
};
43224332

flang/include/flang/Semantics/symbol.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,7 @@ class Symbol {
714714
CrayPointer, CrayPointee,
715715
LocalityLocal, // named in LOCAL locality-spec
716716
LocalityLocalInit, // named in LOCAL_INIT locality-spec
717+
LocalityReduce, // named in REDUCE locality-spec
717718
LocalityShared, // named in SHARED locality-spec
718719
InDataStmt, // initialized in a DATA statement, =>object, or /init/
719720
InNamelist, // in a Namelist group

flang/lib/Lower/OpenACC.cpp

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -829,29 +829,29 @@ genPrivatizations(const Fortran::parser::AccObjectList &objectList,
829829
/// Return the corresponding enum value for the mlir::acc::ReductionOperator
830830
/// from the parser representation.
831831
static mlir::acc::ReductionOperator
832-
getReductionOperator(const Fortran::parser::AccReductionOperator &op) {
832+
getReductionOperator(const Fortran::parser::ReductionOperator &op) {
833833
switch (op.v) {
834-
case Fortran::parser::AccReductionOperator::Operator::Plus:
834+
case Fortran::parser::ReductionOperator::Operator::Plus:
835835
return mlir::acc::ReductionOperator::AccAdd;
836-
case Fortran::parser::AccReductionOperator::Operator::Multiply:
836+
case Fortran::parser::ReductionOperator::Operator::Multiply:
837837
return mlir::acc::ReductionOperator::AccMul;
838-
case Fortran::parser::AccReductionOperator::Operator::Max:
838+
case Fortran::parser::ReductionOperator::Operator::Max:
839839
return mlir::acc::ReductionOperator::AccMax;
840-
case Fortran::parser::AccReductionOperator::Operator::Min:
840+
case Fortran::parser::ReductionOperator::Operator::Min:
841841
return mlir::acc::ReductionOperator::AccMin;
842-
case Fortran::parser::AccReductionOperator::Operator::Iand:
842+
case Fortran::parser::ReductionOperator::Operator::Iand:
843843
return mlir::acc::ReductionOperator::AccIand;
844-
case Fortran::parser::AccReductionOperator::Operator::Ior:
844+
case Fortran::parser::ReductionOperator::Operator::Ior:
845845
return mlir::acc::ReductionOperator::AccIor;
846-
case Fortran::parser::AccReductionOperator::Operator::Ieor:
846+
case Fortran::parser::ReductionOperator::Operator::Ieor:
847847
return mlir::acc::ReductionOperator::AccXor;
848-
case Fortran::parser::AccReductionOperator::Operator::And:
848+
case Fortran::parser::ReductionOperator::Operator::And:
849849
return mlir::acc::ReductionOperator::AccLand;
850-
case Fortran::parser::AccReductionOperator::Operator::Or:
850+
case Fortran::parser::ReductionOperator::Operator::Or:
851851
return mlir::acc::ReductionOperator::AccLor;
852-
case Fortran::parser::AccReductionOperator::Operator::Eqv:
852+
case Fortran::parser::ReductionOperator::Operator::Eqv:
853853
return mlir::acc::ReductionOperator::AccEqv;
854-
case Fortran::parser::AccReductionOperator::Operator::Neqv:
854+
case Fortran::parser::ReductionOperator::Operator::Neqv:
855855
return mlir::acc::ReductionOperator::AccNeqv;
856856
}
857857
llvm_unreachable("unexpected reduction operator");
@@ -1356,8 +1356,7 @@ genReductions(const Fortran::parser::AccObjectListWithReduction &objectList,
13561356
llvm::SmallVector<mlir::Attribute> &reductionRecipes) {
13571357
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
13581358
const auto &objects = std::get<Fortran::parser::AccObjectList>(objectList.t);
1359-
const auto &op =
1360-
std::get<Fortran::parser::AccReductionOperator>(objectList.t);
1359+
const auto &op = std::get<Fortran::parser::ReductionOperator>(objectList.t);
13611360
mlir::acc::ReductionOperator mlirOp = getReductionOperator(op);
13621361
Fortran::evaluate::ExpressionAnalyzer ea{semanticsContext};
13631362
for (const auto &accObject : objects.v) {

flang/lib/Parser/executable-parsers.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,11 +254,15 @@ TYPE_PARSER(construct<ConcurrentControl>(name / "=", scalarIntExpr / ":",
254254

255255
// R1130 locality-spec ->
256256
// LOCAL ( variable-name-list ) | LOCAL_INIT ( variable-name-list ) |
257+
// REDUCE ( reduce-operation : variable-name-list ) |
257258
// SHARED ( variable-name-list ) | DEFAULT ( NONE )
258259
TYPE_PARSER(construct<LocalitySpec>(construct<LocalitySpec::Local>(
259260
"LOCAL" >> parenthesized(listOfNames))) ||
260261
construct<LocalitySpec>(construct<LocalitySpec::LocalInit>(
261262
"LOCAL_INIT"_sptok >> parenthesized(listOfNames))) ||
263+
construct<LocalitySpec>(construct<LocalitySpec::Reduce>(
264+
"REDUCE (" >> Parser<LocalitySpec::Reduce::Operator>{} / ":",
265+
listOfNames / ")")) ||
262266
construct<LocalitySpec>(construct<LocalitySpec::Shared>(
263267
"SHARED" >> parenthesized(listOfNames))) ||
264268
construct<LocalitySpec>(

flang/lib/Parser/openacc-parsers.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ TYPE_PARSER(construct<AccObjectListWithModifier>(
3939
maybe(Parser<AccDataModifier>{}), Parser<AccObjectList>{}))
4040

4141
TYPE_PARSER(construct<AccObjectListWithReduction>(
42-
Parser<AccReductionOperator>{} / ":", Parser<AccObjectList>{}))
42+
Parser<ReductionOperator>{} / ":", Parser<AccObjectList>{}))
4343

4444
// 2.16 (3249) wait-argument is:
4545
// [devnum : int-expr :] [queues :] int-expr-list
@@ -92,20 +92,20 @@ TYPE_PARSER(
9292
TYPE_PARSER(construct<AccCollapseArg>(
9393
"FORCE:"_tok >> pure(true) || pure(false), scalarIntConstantExpr))
9494

95-
// 2.5.15 Reduction
95+
// 2.5.15 Reduction, F'2023 R1131, and CUF reduction-op
9696
// Operator for reduction
97-
TYPE_PARSER(sourced(construct<AccReductionOperator>(
98-
first("+" >> pure(AccReductionOperator::Operator::Plus),
99-
"*" >> pure(AccReductionOperator::Operator::Multiply),
100-
"MAX" >> pure(AccReductionOperator::Operator::Max),
101-
"MIN" >> pure(AccReductionOperator::Operator::Min),
102-
"IAND" >> pure(AccReductionOperator::Operator::Iand),
103-
"IOR" >> pure(AccReductionOperator::Operator::Ior),
104-
"IEOR" >> pure(AccReductionOperator::Operator::Ieor),
105-
".AND." >> pure(AccReductionOperator::Operator::And),
106-
".OR." >> pure(AccReductionOperator::Operator::Or),
107-
".EQV." >> pure(AccReductionOperator::Operator::Eqv),
108-
".NEQV." >> pure(AccReductionOperator::Operator::Neqv)))))
97+
TYPE_PARSER(sourced(construct<ReductionOperator>(
98+
first("+" >> pure(ReductionOperator::Operator::Plus),
99+
"*" >> pure(ReductionOperator::Operator::Multiply),
100+
"MAX" >> pure(ReductionOperator::Operator::Max),
101+
"MIN" >> pure(ReductionOperator::Operator::Min),
102+
"IAND" >> pure(ReductionOperator::Operator::Iand),
103+
"IOR" >> pure(ReductionOperator::Operator::Ior),
104+
"IEOR" >> pure(ReductionOperator::Operator::Ieor),
105+
".AND." >> pure(ReductionOperator::Operator::And),
106+
".OR." >> pure(ReductionOperator::Operator::Or),
107+
".EQV." >> pure(ReductionOperator::Operator::Eqv),
108+
".NEQV." >> pure(ReductionOperator::Operator::Neqv)))))
109109

110110
// 2.15.1 Bind clause
111111
TYPE_PARSER(sourced(construct<AccBindClause>(name)) ||

flang/lib/Parser/unparse.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,6 +1038,10 @@ class UnparseVisitor {
10381038
void Unparse(const LocalitySpec::LocalInit &x) {
10391039
Word("LOCAL_INIT("), Walk(x.v, ", "), Put(')');
10401040
}
1041+
void Unparse(const LocalitySpec::Reduce &x) {
1042+
Word("REDUCE("), Walk(std::get<parser::ReductionOperator>(x.t));
1043+
Walk(":", std::get<std::list<parser::Name>>(x.t), ",", ")");
1044+
}
10411045
void Unparse(const LocalitySpec::Shared &x) {
10421046
Word("SHARED("), Walk(x.v, ", "), Put(')');
10431047
}
@@ -2018,7 +2022,7 @@ class UnparseVisitor {
20182022
}
20192023
void Unparse(const AccObjectList &x) { Walk(x.v, ","); }
20202024
void Unparse(const AccObjectListWithReduction &x) {
2021-
Walk(std::get<AccReductionOperator>(x.t));
2025+
Walk(std::get<ReductionOperator>(x.t));
20222026
Put(":");
20232027
Walk(std::get<AccObjectList>(x.t));
20242028
}
@@ -2753,28 +2757,28 @@ class UnparseVisitor {
27532757
WALK_NESTED_ENUM(OmpOrderClause, Type) // OMP order-type
27542758
WALK_NESTED_ENUM(OmpOrderModifier, Kind) // OMP order-modifier
27552759
#undef WALK_NESTED_ENUM
2756-
void Unparse(const AccReductionOperator::Operator x) {
2760+
void Unparse(const ReductionOperator::Operator x) {
27572761
switch (x) {
2758-
case AccReductionOperator::Operator::Plus:
2762+
case ReductionOperator::Operator::Plus:
27592763
Word("+");
27602764
break;
2761-
case AccReductionOperator::Operator::Multiply:
2765+
case ReductionOperator::Operator::Multiply:
27622766
Word("*");
27632767
break;
2764-
case AccReductionOperator::Operator::And:
2768+
case ReductionOperator::Operator::And:
27652769
Word(".AND.");
27662770
break;
2767-
case AccReductionOperator::Operator::Or:
2771+
case ReductionOperator::Operator::Or:
27682772
Word(".OR.");
27692773
break;
2770-
case AccReductionOperator::Operator::Eqv:
2774+
case ReductionOperator::Operator::Eqv:
27712775
Word(".EQV.");
27722776
break;
2773-
case AccReductionOperator::Operator::Neqv:
2777+
case ReductionOperator::Operator::Neqv:
27742778
Word(".NEQV.");
27752779
break;
27762780
default:
2777-
Word(AccReductionOperator::EnumToString(x));
2781+
Word(ReductionOperator::EnumToString(x));
27782782
break;
27792783
}
27802784
}

flang/lib/Semantics/check-acc-structure.cpp

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,33 +22,33 @@
2222
}
2323

2424
using ReductionOpsSet =
25-
Fortran::common::EnumSet<Fortran::parser::AccReductionOperator::Operator,
26-
Fortran::parser::AccReductionOperator::Operator_enumSize>;
25+
Fortran::common::EnumSet<Fortran::parser::ReductionOperator::Operator,
26+
Fortran::parser::ReductionOperator::Operator_enumSize>;
2727

2828
static ReductionOpsSet reductionIntegerSet{
29-
Fortran::parser::AccReductionOperator::Operator::Plus,
30-
Fortran::parser::AccReductionOperator::Operator::Multiply,
31-
Fortran::parser::AccReductionOperator::Operator::Max,
32-
Fortran::parser::AccReductionOperator::Operator::Min,
33-
Fortran::parser::AccReductionOperator::Operator::Iand,
34-
Fortran::parser::AccReductionOperator::Operator::Ior,
35-
Fortran::parser::AccReductionOperator::Operator::Ieor};
29+
Fortran::parser::ReductionOperator::Operator::Plus,
30+
Fortran::parser::ReductionOperator::Operator::Multiply,
31+
Fortran::parser::ReductionOperator::Operator::Max,
32+
Fortran::parser::ReductionOperator::Operator::Min,
33+
Fortran::parser::ReductionOperator::Operator::Iand,
34+
Fortran::parser::ReductionOperator::Operator::Ior,
35+
Fortran::parser::ReductionOperator::Operator::Ieor};
3636

3737
static ReductionOpsSet reductionRealSet{
38-
Fortran::parser::AccReductionOperator::Operator::Plus,
39-
Fortran::parser::AccReductionOperator::Operator::Multiply,
40-
Fortran::parser::AccReductionOperator::Operator::Max,
41-
Fortran::parser::AccReductionOperator::Operator::Min};
38+
Fortran::parser::ReductionOperator::Operator::Plus,
39+
Fortran::parser::ReductionOperator::Operator::Multiply,
40+
Fortran::parser::ReductionOperator::Operator::Max,
41+
Fortran::parser::ReductionOperator::Operator::Min};
4242

4343
static ReductionOpsSet reductionComplexSet{
44-
Fortran::parser::AccReductionOperator::Operator::Plus,
45-
Fortran::parser::AccReductionOperator::Operator::Multiply};
44+
Fortran::parser::ReductionOperator::Operator::Plus,
45+
Fortran::parser::ReductionOperator::Operator::Multiply};
4646

4747
static ReductionOpsSet reductionLogicalSet{
48-
Fortran::parser::AccReductionOperator::Operator::And,
49-
Fortran::parser::AccReductionOperator::Operator::Or,
50-
Fortran::parser::AccReductionOperator::Operator::Eqv,
51-
Fortran::parser::AccReductionOperator::Operator::Neqv};
48+
Fortran::parser::ReductionOperator::Operator::And,
49+
Fortran::parser::ReductionOperator::Operator::Or,
50+
Fortran::parser::ReductionOperator::Operator::Eqv,
51+
Fortran::parser::ReductionOperator::Operator::Neqv};
5252

5353
namespace Fortran::semantics {
5454

@@ -670,7 +670,7 @@ void AccStructureChecker::Enter(const parser::AccClause::Reduction &reduction) {
670670
// The following check that the reduction operator is supported with the given
671671
// type.
672672
const parser::AccObjectListWithReduction &list{reduction.v};
673-
const auto &op{std::get<parser::AccReductionOperator>(list.t)};
673+
const auto &op{std::get<parser::ReductionOperator>(list.t)};
674674
const auto &objects{std::get<parser::AccObjectList>(list.t)};
675675

676676
for (const auto &object : objects.v) {

flang/lib/Semantics/check-cuda.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -475,21 +475,21 @@ static void CheckReduce(
475475
auto cat{type->category()};
476476
bool isOk{false};
477477
switch (op) {
478-
case parser::AccReductionOperator::Operator::Plus:
479-
case parser::AccReductionOperator::Operator::Multiply:
480-
case parser::AccReductionOperator::Operator::Max:
481-
case parser::AccReductionOperator::Operator::Min:
478+
case parser::ReductionOperator::Operator::Plus:
479+
case parser::ReductionOperator::Operator::Multiply:
480+
case parser::ReductionOperator::Operator::Max:
481+
case parser::ReductionOperator::Operator::Min:
482482
isOk = cat == TypeCategory::Integer || cat == TypeCategory::Real;
483483
break;
484-
case parser::AccReductionOperator::Operator::Iand:
485-
case parser::AccReductionOperator::Operator::Ior:
486-
case parser::AccReductionOperator::Operator::Ieor:
484+
case parser::ReductionOperator::Operator::Iand:
485+
case parser::ReductionOperator::Operator::Ior:
486+
case parser::ReductionOperator::Operator::Ieor:
487487
isOk = cat == TypeCategory::Integer;
488488
break;
489-
case parser::AccReductionOperator::Operator::And:
490-
case parser::AccReductionOperator::Operator::Or:
491-
case parser::AccReductionOperator::Operator::Eqv:
492-
case parser::AccReductionOperator::Operator::Neqv:
489+
case parser::ReductionOperator::Operator::And:
490+
case parser::ReductionOperator::Operator::Or:
491+
case parser::ReductionOperator::Operator::Eqv:
492+
case parser::ReductionOperator::Operator::Neqv:
493493
isOk = cat == TypeCategory::Logical;
494494
break;
495495
}

0 commit comments

Comments
 (0)