Skip to content

Commit

Permalink
[flang][openacc] Support labeled DO loop after acc loop directive (#6…
Browse files Browse the repository at this point in the history
…6294)

Make the `DoConstruct` in `OpenACCLoopConstruct` optional and move the
labeled do construct in in the canonicalization step.
  • Loading branch information
clementval committed Sep 14, 2023
1 parent b1341e2 commit bc32346
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 19 deletions.
6 changes: 5 additions & 1 deletion flang/include/flang/Parser/parse-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -4247,7 +4247,11 @@ struct OpenACCDeclarativeConstruct {
EMPTY_CLASS(AccEndLoop);
struct OpenACCLoopConstruct {
TUPLE_CLASS_BOILERPLATE(OpenACCLoopConstruct);
std::tuple<AccBeginLoopDirective, DoConstruct, std::optional<AccEndLoop>> t;
OpenACCLoopConstruct(AccBeginLoopDirective &&a)
: t({std::move(a), std::nullopt, std::nullopt}) {}
std::tuple<AccBeginLoopDirective, std::optional<DoConstruct>,
std::optional<AccEndLoop>>
t;
};

struct OpenACCStandaloneConstruct {
Expand Down
4 changes: 1 addition & 3 deletions flang/lib/Parser/openacc-parsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,7 @@ TYPE_PARSER(construct<AccEndLoop>(startAccLine >> "END LOOP"_tok))

TYPE_PARSER(construct<OpenACCLoopConstruct>(
sourced(Parser<AccBeginLoopDirective>{} / endAccLine),
withMessage("A DO loop must follow the loop construct"_err_en_US,
Parser<DoConstruct>{}),
maybe(Parser<AccEndLoop>{} / endAccLine)))
maybe(Parser<DoConstruct>{}), maybe(Parser<AccEndLoop>{} / endAccLine)))

// 2.15.1 Routine directive
TYPE_PARSER(sourced(construct<OpenACCRoutineConstruct>(verbatim("ROUTINE"_tok),
Expand Down
2 changes: 1 addition & 1 deletion flang/lib/Parser/unparse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1947,7 +1947,7 @@ class UnparseVisitor {
Walk(std::get<AccBeginLoopDirective>(x.t));
Put("\n");
EndOpenACC();
Walk(std::get<DoConstruct>(x.t));
Walk(std::get<std::optional<DoConstruct>>(x.t));
}
void Unparse(const AccBeginLoopDirective &x) {
Walk(std::get<AccLoopDirective>(x.t));
Expand Down
36 changes: 26 additions & 10 deletions flang/lib/Semantics/canonicalize-acc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,21 +109,37 @@ class CanonicalizationOfAcc {

void RewriteOpenACCLoopConstruct(parser::OpenACCLoopConstruct &x,
parser::Block &block, parser::Block::iterator it) {
parser::Block::iterator nextIt;
auto &beginDir{std::get<parser::AccBeginLoopDirective>(x.t)};
auto &dir{std::get<parser::AccLoopDirective>(beginDir.t)};
const auto &doCons{std::get<parser::DoConstruct>(x.t)};
auto &nestedDo{std::get<std::optional<parser::DoConstruct>>(x.t)};

if (!nestedDo) {
nextIt = it;
if (++nextIt != block.end()) {
if (auto *doCons{parser::Unwrap<parser::DoConstruct>(*nextIt)}) {
nestedDo = std::move(*doCons);
nextIt = block.erase(nextIt);
}
}
}

if (!doCons.GetLoopControl()) {
messages_.Say(dir.source,
"DO loop after the %s directive must have loop control"_err_en_US,
parser::ToUpperCaseLetters(dir.source.ToString()));
if (nestedDo) {
if (!nestedDo->GetLoopControl()) {
messages_.Say(dir.source,
"DO loop after the %s directive must have loop control"_err_en_US,
parser::ToUpperCaseLetters(dir.source.ToString()));
return;
}
CheckDoConcurrentClauseRestriction<parser::OpenACCLoopConstruct,
parser::AccBeginLoopDirective>(x, *nestedDo);
CheckTileClauseRestriction<parser::OpenACCLoopConstruct,
parser::AccBeginLoopDirective>(x, *nestedDo);
return;
}

CheckDoConcurrentClauseRestriction<parser::OpenACCLoopConstruct,
parser::AccBeginLoopDirective>(x, doCons);
CheckTileClauseRestriction<parser::OpenACCLoopConstruct,
parser::AccBeginLoopDirective>(x, doCons);
messages_.Say(dir.source,
"A DO loop must follow the %s directive"_err_en_US,
parser::ToUpperCaseLetters(dir.source.ToString()));
}

void RewriteOpenACCCombinedConstruct(parser::OpenACCCombinedConstruct &x,
Expand Down
4 changes: 2 additions & 2 deletions flang/lib/Semantics/resolve-directives.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1153,8 +1153,8 @@ void AccAttributeVisitor::PrivatizeAssociatedLoopIndex(
return nullptr;
};

const auto &outer{std::get<parser::DoConstruct>(x.t)};
for (const parser::DoConstruct *loop{&outer}; loop && level > 0; --level) {
const auto &outer{std::get<std::optional<parser::DoConstruct>>(x.t)};
for (const parser::DoConstruct *loop{&*outer}; loop && level > 0; --level) {
// go through all the nested do-loops and resolve index variables
const parser::Name *iv{GetLoopIndex(*loop)};
if (iv) {
Expand Down
6 changes: 6 additions & 0 deletions flang/test/Lower/OpenACC/acc-loop.f90
Original file line number Diff line number Diff line change
Expand Up @@ -315,4 +315,10 @@ program acc_loop
! CHECK: %[[CACHE:.*]] = acc.cache varPtr(%{{.*}} : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<10xf32>> {name = "b"}
! CHECK: acc.loop cache(%[[CACHE]] : !fir.ref<!fir.array<10xf32>>)

!$acc loop
do 100 i=0, n
100 continue
! CHECK: acc.loop
! CHECK: fir.do_loop

end program
8 changes: 6 additions & 2 deletions flang/test/Semantics/OpenACC/acc-loop-validity.f90
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@ program openacc_clause_validity

implicit none

integer :: i
integer :: i, n

i = 0

!ERROR: A DO loop must follow the LOOP directive
!$acc loop
!ERROR: A DO loop must follow the loop construct
i = 1

!$acc loop
do 100 i=0, n
100 continue

end

0 comments on commit bc32346

Please sign in to comment.