Skip to content

Commit

Permalink
[flang][openacc][NFC] Make self clause value optional in ACC.td and e…
Browse files Browse the repository at this point in the history
…xtract the parser

Set the isOptional flag for the self clause. Move the optional and parenthesis part of the parser. Update the rest of the code to deal with the optional value.

Preparatory work for D106968.

Reviewed By: kiranchandramohan

Differential Revision: https://reviews.llvm.org/D106965
  • Loading branch information
clementval committed Jul 8, 2022
1 parent d1c51d4 commit 36e24da
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 33 deletions.
51 changes: 27 additions & 24 deletions flang/lib/Lower/OpenACC.cpp
Expand Up @@ -407,33 +407,36 @@ createParallelOp(Fortran::lower::AbstractConverter &converter,
genIfClause(converter, ifClause, ifCond, stmtCtx);
} else if (const auto *selfClause =
std::get_if<Fortran::parser::AccClause::Self>(&clause.u)) {
const Fortran::parser::AccSelfClause &accSelfClause = selfClause->v;
if (const auto *optCondition =
std::get_if<std::optional<Fortran::parser::ScalarLogicalExpr>>(
&accSelfClause.u)) {
if (*optCondition) {
mlir::Value cond = fir::getBase(converter.genExprValue(
*Fortran::semantics::GetExpr(*optCondition), stmtCtx));
selfCond = firOpBuilder.createConvert(currentLocation,
firOpBuilder.getI1Type(), cond);
} else {
addSelfAttr = true;
}
} else if (const auto *accClauseList =
std::get_if<Fortran::parser::AccObjectList>(
&accSelfClause.u)) {
// TODO This would be nicer to be done in canonicalization step.
if (accClauseList->v.size() == 1) {
const auto &accObject = accClauseList->v.front();
if (const auto *designator =
std::get_if<Fortran::parser::Designator>(&accObject.u)) {
if (const auto *name = getDesignatorNameIfDataRef(*designator)) {
auto cond = converter.getSymbolAddress(*name->symbol);
selfCond = firOpBuilder.createConvert(
currentLocation, firOpBuilder.getI1Type(), cond);
const std::optional<Fortran::parser::AccSelfClause> &accSelfClause =
selfClause->v;
if (accSelfClause) {
if (const auto *optCondition =
std::get_if<std::optional<Fortran::parser::ScalarLogicalExpr>>(
&(*accSelfClause).u)) {
if (*optCondition) {
mlir::Value cond = fir::getBase(converter.genExprValue(
*Fortran::semantics::GetExpr(*optCondition), stmtCtx));
selfCond = firOpBuilder.createConvert(
currentLocation, firOpBuilder.getI1Type(), cond);
}
} else if (const auto *accClauseList =
std::get_if<Fortran::parser::AccObjectList>(
&(*accSelfClause).u)) {
// TODO This would be nicer to be done in canonicalization step.
if (accClauseList->v.size() == 1) {
const auto &accObject = accClauseList->v.front();
if (const auto *designator =
std::get_if<Fortran::parser::Designator>(&accObject.u)) {
if (const auto *name = getDesignatorNameIfDataRef(*designator)) {
auto cond = converter.getSymbolAddress(*name->symbol);
selfCond = firOpBuilder.createConvert(
currentLocation, firOpBuilder.getI1Type(), cond);
}
}
}
}
} else {
addSelfAttr = true;
}
} else if (const auto *copyClause =
std::get_if<Fortran::parser::AccClause::Copy>(&clause.u)) {
Expand Down
8 changes: 4 additions & 4 deletions flang/lib/Parser/openacc-parsers.cpp
Expand Up @@ -98,8 +98,8 @@ TYPE_PARSER("AUTO" >> construct<AccClause>(construct<AccClause::Auto>()) ||
parenthesized(construct<AccObjectListWithReduction>(
Parser<AccReductionOperator>{} / ":",
Parser<AccObjectList>{})))) ||
"SELF" >> construct<AccClause>(
construct<AccClause::Self>(Parser<AccSelfClause>{})) ||
"SELF" >> construct<AccClause>(construct<AccClause::Self>(
maybe(parenthesized(Parser<AccSelfClause>{})))) ||
"SEQ" >> construct<AccClause>(construct<AccClause::Seq>()) ||
"TILE" >> construct<AccClause>(construct<AccClause::Tile>(
parenthesized(Parser<AccTileExprList>{}))) ||
Expand Down Expand Up @@ -178,8 +178,8 @@ TYPE_PARSER(construct<AccDefaultClause>(parenthesized(
// SELF clause is either a simple optional condition for compute construct
// or a synonym of the HOST clause for the update directive 2.14.4 holding
// an object list.
TYPE_PARSER(construct<AccSelfClause>(parenthesized(Parser<AccObjectList>{})) ||
construct<AccSelfClause>(maybe(parenthesized(scalarLogicalExpr))))
TYPE_PARSER(construct<AccSelfClause>(Parser<AccObjectList>{}) ||
construct<AccSelfClause>(scalarLogicalExpr))

// Modifier for copyin, copyout, cache and create
TYPE_PARSER(construct<AccDataModifier>(
Expand Down
13 changes: 8 additions & 5 deletions flang/lib/Semantics/check-acc-structure.cpp
Expand Up @@ -409,17 +409,20 @@ void AccStructureChecker::Enter(const parser::AccClause::Copyout &c) {

void AccStructureChecker::Enter(const parser::AccClause::Self &x) {
CheckAllowed(llvm::acc::Clause::ACCC_self);
const parser::AccSelfClause &accSelfClause = x.v;
const std::optional<parser::AccSelfClause> &accSelfClause = x.v;
if (GetContext().directive == llvm::acc::Directive::ACCD_update &&
std::holds_alternative<std::optional<parser::ScalarLogicalExpr>>(
accSelfClause.u)) {
((accSelfClause &&
std::holds_alternative<std::optional<parser::ScalarLogicalExpr>>(
(*accSelfClause).u)) ||
!accSelfClause)) {
context_.Say(GetContext().clauseSource,
"SELF clause on the %s directive must have a var-list"_err_en_US,
ContextDirectiveAsFortran());
} else if (GetContext().directive != llvm::acc::Directive::ACCD_update &&
std::holds_alternative<parser::AccObjectList>(accSelfClause.u)) {
accSelfClause &&
std::holds_alternative<parser::AccObjectList>((*accSelfClause).u)) {
const auto &accObjectList =
std::get<parser::AccObjectList>(accSelfClause.u);
std::get<parser::AccObjectList>((*accSelfClause).u);
if (accObjectList.v.size() != 1) {
context_.Say(GetContext().clauseSource,
"SELF clause on the %s directive only accepts optional scalar logical"
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/Frontend/OpenACC/ACC.td
Expand Up @@ -218,6 +218,7 @@ def ACCC_Reduction : Clause<"reduction"> {
// 2.5.6
def ACCC_Self : Clause<"self"> {
let flangClass = "AccSelfClause";
let isValueOptional = true;
}

// 2.9.5
Expand Down

0 comments on commit 36e24da

Please sign in to comment.