Skip to content

Commit

Permalink
[flang][openacc] Add parsing support for dim in gang clause
Browse files Browse the repository at this point in the history
Add parsing supprot for dim in gang clause

Depends on D151971

Reviewed By: razvanlupusoru, jeanPerier

Differential Revision: https://reviews.llvm.org/D151972
  • Loading branch information
clementval committed Jun 14, 2023
1 parent e6d8598 commit 5923e46
Show file tree
Hide file tree
Showing 10 changed files with 141 additions and 40 deletions.
2 changes: 1 addition & 1 deletion flang/examples/FeatureList/FeatureList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ struct NodeVisitor {
READ_FEATURE(AccEndAtomic)
READ_FEATURE(AccEndBlockDirective)
READ_FEATURE(AccEndCombinedDirective)
READ_FEATURE(AccGangArgument)
READ_FEATURE(AccGangArg)
READ_FEATURE(AccObject)
READ_FEATURE(AccObjectList)
READ_FEATURE(AccObjectListWithModifier)
Expand Down
6 changes: 5 additions & 1 deletion flang/include/flang/Parser/dump-parse-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,12 @@ class ParseTreeDumper {
NODE(parser, AccEndAtomic)
NODE(parser, AccEndBlockDirective)
NODE(parser, AccEndCombinedDirective)
NODE(parser, AccGangArgument)
NODE(parser, AccCollapseArg)
NODE(parser, AccGangArg)
NODE(AccGangArg, Num)
NODE(AccGangArg, Dim)
NODE(AccGangArg, Static)
NODE(parser, AccGangArgList)
NODE(parser, AccObject)
NODE(parser, AccObjectList)
NODE(parser, AccObjectListWithModifier)
Expand Down
19 changes: 13 additions & 6 deletions flang/include/flang/Parser/parse-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -4077,9 +4077,7 @@ struct AccTileExprList {
};

struct AccSizeExpr {
TUPLE_CLASS_BOILERPLATE(AccSizeExpr);
CharBlock source;
std::tuple<std::optional<ScalarIntExpr>> t; // if null then *
WRAPPER_CLASS_BOILERPLATE(AccSizeExpr, std::optional<ScalarIntExpr>);
};

struct AccSizeExprList {
Expand All @@ -4092,9 +4090,18 @@ struct AccSelfClause {
CharBlock source;
};

struct AccGangArgument {
TUPLE_CLASS_BOILERPLATE(AccGangArgument);
std::tuple<std::optional<ScalarIntExpr>, std::optional<AccSizeExpr>> t;
// num, dim, static
struct AccGangArg {
UNION_CLASS_BOILERPLATE(AccGangArg);
WRAPPER_CLASS(Num, ScalarIntExpr);
WRAPPER_CLASS(Dim, ScalarIntExpr);
WRAPPER_CLASS(Static, AccSizeExpr);
std::variant<Num, Dim, Static> u;
CharBlock source;
};

struct AccGangArgList {
WRAPPER_CLASS_BOILERPLATE(AccGangArgList, std::list<AccGangArg>);
};

struct AccCollapseArg {
Expand Down
39 changes: 20 additions & 19 deletions flang/lib/Lower/OpenACC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -848,25 +848,26 @@ createLoopOp(Fortran::lower::AbstractConverter &converter,
if (const auto *gangClause =
std::get_if<Fortran::parser::AccClause::Gang>(&clause.u)) {
if (gangClause->v) {
const Fortran::parser::AccGangArgument &x = *gangClause->v;
if (const auto &gangNumValue =
std::get<std::optional<Fortran::parser::ScalarIntExpr>>(x.t)) {
gangNum = fir::getBase(converter.genExprValue(
*Fortran::semantics::GetExpr(gangNumValue.value()), stmtCtx));
}
if (const auto &gangStaticValue =
std::get<std::optional<Fortran::parser::AccSizeExpr>>(x.t)) {
const auto &expr =
std::get<std::optional<Fortran::parser::ScalarIntExpr>>(
gangStaticValue.value().t);
if (expr) {
gangStatic = fir::getBase(converter.genExprValue(
*Fortran::semantics::GetExpr(*expr), stmtCtx));
} else {
// * was passed as value and will be represented as a special
// constant.
gangStatic = builder.createIntegerConstant(
clauseLocation, builder.getIndexType(), starCst);
const Fortran::parser::AccGangArgList &x = *gangClause->v;
for (const Fortran::parser::AccGangArg &gangArg : x.v) {
if (const auto *num =
std::get_if<Fortran::parser::AccGangArg::Num>(&gangArg.u)) {
gangNum = fir::getBase(converter.genExprValue(
*Fortran::semantics::GetExpr(num->v), stmtCtx));
} else if (const auto *staticArg =
std::get_if<Fortran::parser::AccGangArg::Static>(
&gangArg.u)) {

const Fortran::parser::AccSizeExpr &sizeExpr = staticArg->v;
if (sizeExpr.v) {
gangStatic = fir::getBase(converter.genExprValue(
*Fortran::semantics::GetExpr(*sizeExpr.v), stmtCtx));
} else {
// * was passed as value and will be represented as a special
// constant.
gangStatic = builder.createIntegerConstant(
clauseLocation, builder.getIndexType(), starCst);
}
}
}
}
Expand Down
19 changes: 14 additions & 5 deletions flang/lib/Parser/openacc-parsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,20 @@ TYPE_PARSER(construct<AccTileExpr>(scalarIntConstantExpr) ||
"*" >> construct<std::optional<ScalarIntConstantExpr>>()))
TYPE_PARSER(construct<AccTileExprList>(nonemptyList(Parser<AccTileExpr>{})))

// 2.9 (1607) gang-arg is:
// [[num:]int-expr][[,]static:size-expr]
TYPE_PARSER(construct<AccGangArgument>(
maybe(("NUM:"_tok >> scalarIntExpr || scalarIntExpr)),
maybe(", STATIC:" >> Parser<AccSizeExpr>{})))
// 2.9 gang-arg is one of :
// [num:]int-expr
// dim:int-expr
// static:size-expr
TYPE_PARSER(construct<AccGangArg>(construct<AccGangArg::Static>(
"STATIC: " >> Parser<AccSizeExpr>{})) ||
construct<AccGangArg>(
construct<AccGangArg::Dim>("DIM: " >> scalarIntExpr)) ||
construct<AccGangArg>(
construct<AccGangArg::Num>(maybe("NUM: "_tok) >> scalarIntExpr)))

// 2.9 gang-arg-list
TYPE_PARSER(
construct<AccGangArgList>(many(maybe(","_tok) >> Parser<AccGangArg>{})))

// 2.9.1 collapse
TYPE_PARSER(construct<AccCollapseArg>(
Expand Down
16 changes: 13 additions & 3 deletions flang/lib/Parser/unparse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1908,9 +1908,19 @@ class UnparseVisitor {
}
}
void Unparse(const AccClauseList &x) { Walk(" ", x.v, " "); }
void Unparse(const AccGangArgument &x) {
Walk("NUM:", std::get<std::optional<ScalarIntExpr>>(x.t));
Walk(", STATIC:", std::get<std::optional<AccSizeExpr>>(x.t));
void Unparse(const AccGangArgList &x) { Walk(x.v, ","); }
void Before(const AccSizeExpr &x) {
if (!x.v)
Put("*");
}
void Before(const AccGangArg &x) {
common::visit(common::visitors{
[&](const AccGangArg::Num &) { Word("NUM:"); },
[&](const AccGangArg::Dim &) { Word("DIM:"); },
[&](const AccGangArg::Static &) { Word("STATIC:"); },
[](const StatOrErrmsg &) {},
},
x.u);
}
void Unparse(const AccCollapseArg &x) {
const auto &force{std::get<bool>(x.t)};
Expand Down
21 changes: 20 additions & 1 deletion flang/lib/Semantics/check-acc-structure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,6 @@ CHECK_SIMPLE_CLAUSE(DeviceResident, ACCC_device_resident)
CHECK_SIMPLE_CLAUSE(DeviceType, ACCC_device_type)
CHECK_SIMPLE_CLAUSE(Finalize, ACCC_finalize)
CHECK_SIMPLE_CLAUSE(Firstprivate, ACCC_firstprivate)
CHECK_SIMPLE_CLAUSE(Gang, ACCC_gang)
CHECK_SIMPLE_CLAUSE(Host, ACCC_host)
CHECK_SIMPLE_CLAUSE(If, ACCC_if)
CHECK_SIMPLE_CLAUSE(IfPresent, ACCC_if_present)
Expand Down Expand Up @@ -405,6 +404,26 @@ void AccStructureChecker::Enter(const parser::AccClause::Copyout &c) {
}
}

void AccStructureChecker::Enter(const parser::AccClause::Gang &g) {
CheckAllowed(llvm::acc::Clause::ACCC_gang);

if (g.v) {
bool hasNum = false;
bool hasDim = false;
const Fortran::parser::AccGangArgList &x = *g.v;
for (const Fortran::parser::AccGangArg &gangArg : x.v) {
if (std::get_if<Fortran::parser::AccGangArg::Num>(&gangArg.u))
hasNum = true;
else if (std::get_if<Fortran::parser::AccGangArg::Dim>(&gangArg.u))
hasDim = true;
}

if (hasDim && hasNum)
context_.Say(GetContext().clauseSource,
"The num argument is not allowed when dim is specified"_err_en_US);
}
}

void AccStructureChecker::Enter(const parser::AccClause::Self &x) {
CheckAllowed(llvm::acc::Clause::ACCC_self);
const std::optional<parser::AccSelfClause> &accSelfClause = x.v;
Expand Down
51 changes: 48 additions & 3 deletions flang/test/Parser/acc-unparse.f90
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,58 @@ program bug47659

subroutine acc_loop()
integer :: i, j
real :: a(10)
integer :: gangNum, gangDim, gangStatic

!CHECK-LABEL: SUBROUTINE acc_loop

!$acc loop collapse(force: 2)
do i = 1, 10
do j = 1, 10
end do
end do
end subroutine

!CHECK-LABEL: SUBROUTINE acc_loop
!CHECK: !$ACC LOOP COLLAPSE(FORCE:2_4)

!$acc loop gang
do i = 1, 10
a(i) = i
end do
! CHECK: !$ACC LOOP GANG

!$acc loop gang(gangNum)
do i = 1, 10
a(i) = i
end do
! CHECK: !$ACC LOOP GANG(NUM:gangnum)

!$acc loop gang(num: gangNum)
do i = 1, 10
a(i) = i
end do
! CHECK: !$ACC LOOP GANG(NUM:gangnum)

!$acc loop gang(dim: gangDim)
do i = 1, 10
a(i) = i
end do
! CHECK: !$ACC LOOP GANG(DIM:gangdim)

!$acc loop gang(static:gangStatic)
do i = 1, 10
a(i) = i
end do
! CHECK: !$ACC LOOP GANG(STATIC:gangstatic)

!$acc loop gang(static:*)
do i = 1, 10
a(i) = i
end do
! CHECK: !$ACC LOOP GANG(STATIC:*)

!$acc loop gang(static:gangStatic, dim: gangDim)
do i = 1, 10
a(i) = i
end do
! CHECK: !$ACC LOOP GANG(STATIC:gangstatic,DIM:gangdim)

end subroutine
6 changes: 6 additions & 0 deletions flang/test/Semantics/OpenACC/acc-loop.f90
Original file line number Diff line number Diff line change
Expand Up @@ -257,4 +257,10 @@ program openacc_loop_validity
a(i) = 3.14
end do
end do

!ERROR: The num argument is not allowed when dim is specified
!$acc loop gang(1, dim: 2)
do i = 1, N
end do

end program openacc_loop_validity
2 changes: 1 addition & 1 deletion llvm/include/llvm/Frontend/OpenACC/ACC.td
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ def ACCC_FirstPrivate : Clause<"firstprivate"> {

// 2.9.2
def ACCC_Gang : Clause<"gang"> {
let flangClass = "AccGangArgument";
let flangClass = "AccGangArgList";
let isValueOptional = true;
}

Expand Down

0 comments on commit 5923e46

Please sign in to comment.