[flang][openacc] Add parsing support for dim in gang clause

Add parsing supprot for dim in gang clause

Depends on D151971

Reviewed By: razvanlupusoru, jeanPerier

Differential Revision: https://reviews.llvm.org/D151972
This commit is contained in:
Valentin Clement 2023-06-13 20:33:20 -07:00
parent e6d8598e13
commit 5923e46fce
No known key found for this signature in database
GPG Key ID: 086D54783C928776
10 changed files with 141 additions and 40 deletions

View File

@ -80,7 +80,7 @@ public:
READ_FEATURE(AccEndAtomic)
READ_FEATURE(AccEndBlockDirective)
READ_FEATURE(AccEndCombinedDirective)
READ_FEATURE(AccGangArgument)
READ_FEATURE(AccGangArg)
READ_FEATURE(AccObject)
READ_FEATURE(AccObjectList)
READ_FEATURE(AccObjectListWithModifier)

View File

@ -84,8 +84,12 @@ public:
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)

View File

@ -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 {
@ -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 {

View File

@ -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);
}
}
}
}

View File

@ -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>(

View File

@ -1908,9 +1908,19 @@ public:
}
}
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)};

View File

@ -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)
@ -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;

View File

@ -21,13 +21,58 @@ end program
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

View File

@ -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

View File

@ -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;
}