Skip to content

Commit 16cf9c9

Browse files
authored
[flang][openacc] Support labeled DO loop after acc combined directive (#66296)
This patch adds support for labeled do loop after combined directive. It relaxes the initial parser and canonicalize labeled do loop into the OpenACCCombinedConstruct.
1 parent bc32346 commit 16cf9c9

File tree

4 files changed

+38
-10
lines changed

4 files changed

+38
-10
lines changed

flang/lib/Parser/openacc-parsers.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,7 @@ TYPE_PARSER(startAccLine >>
255255

256256
TYPE_PARSER(construct<OpenACCCombinedConstruct>(
257257
sourced(Parser<AccBeginCombinedDirective>{} / endAccLine),
258-
withMessage("A DO loop must follow the combined construct"_err_en_US,
259-
Parser<DoConstruct>{}),
258+
maybe(Parser<DoConstruct>{}),
260259
maybe(Parser<AccEndCombinedDirective>{} / endAccLine)))
261260

262261
} // namespace Fortran::parser

flang/lib/Semantics/canonicalize-acc.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -148,14 +148,24 @@ class CanonicalizationOfAcc {
148148
parser::Block::iterator nextIt;
149149
auto &beginDir{std::get<parser::AccBeginCombinedDirective>(x.t)};
150150
auto &dir{std::get<parser::AccCombinedDirective>(beginDir.t)};
151-
const auto &doConstruct{std::get<std::optional<parser::DoConstruct>>(x.t)};
151+
auto &nestedDo{std::get<std::optional<parser::DoConstruct>>(x.t)};
152152

153-
if (doConstruct) {
153+
if (!nestedDo) {
154+
nextIt = it;
155+
if (++nextIt != block.end()) {
156+
if (auto *doCons{parser::Unwrap<parser::DoConstruct>(*nextIt)}) {
157+
nestedDo = std::move(*doCons);
158+
nextIt = block.erase(nextIt);
159+
}
160+
}
161+
}
162+
163+
if (nestedDo) {
154164
CheckDoConcurrentClauseRestriction<parser::OpenACCCombinedConstruct,
155-
parser::AccBeginCombinedDirective>(x, *doConstruct);
165+
parser::AccBeginCombinedDirective>(x, *nestedDo);
156166
CheckTileClauseRestriction<parser::OpenACCCombinedConstruct,
157-
parser::AccBeginCombinedDirective>(x, *doConstruct);
158-
if (!doConstruct->GetLoopControl()) {
167+
parser::AccBeginCombinedDirective>(x, *nestedDo);
168+
if (!nestedDo->GetLoopControl()) {
159169
messages_.Say(dir.source,
160170
"DO loop after the %s directive must have loop control"_err_en_US,
161171
parser::ToUpperCaseLetters(dir.source.ToString()));

flang/test/Lower/OpenACC/acc-parallel-loop.f90

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -803,4 +803,11 @@ subroutine acc_parallel_loop
803803
! CHECK: acc.yield
804804
! CHECK-NEXT: }{{$}}
805805

806+
!$acc parallel loop
807+
do 10 i=0, n
808+
10 continue
809+
! CHECK: acc.parallel
810+
! CHECK: acc.loop
811+
! CHECK: fir.do_loop
812+
806813
end subroutine acc_parallel_loop

flang/test/Semantics/OpenACC/acc-combined-loop.f90

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,28 @@ program openacc_combined_loop
66

77
i = 1
88

9+
!ERROR: A DO loop must follow the PARALLEL LOOP directive
910
!$acc parallel loop
10-
!ERROR: A DO loop must follow the combined construct
1111
i = 1
1212

13+
!ERROR: A DO loop must follow the KERNELS LOOP directive
1314
!$acc kernels loop
14-
!ERROR: A DO loop must follow the combined construct
1515
i = 1
1616

17+
!ERROR: A DO loop must follow the SERIAL LOOP directive
1718
!$acc serial loop
18-
!ERROR: A DO loop must follow the combined construct
1919
i = 1
2020

21+
!$acc parallel loop
22+
do 10 i=0, n
23+
10 continue
24+
25+
!$acc kernels loop
26+
do 20 i=0, n
27+
20 continue
28+
29+
!$acc serial loop
30+
do 30 i=0, n
31+
30 continue
32+
2133
end

0 commit comments

Comments
 (0)