Skip to content

Commit 3bde1a3

Browse files
clementvalZijunZhaoCCK
authored andcommitted
[flang][openacc] Support labeled DO loop after acc loop directive (llvm#66294)
Make the `DoConstruct` in `OpenACCLoopConstruct` optional and move the labeled do construct in in the canonicalization step.
1 parent e44692e commit 3bde1a3

File tree

7 files changed

+47
-19
lines changed

7 files changed

+47
-19
lines changed

flang/include/flang/Parser/parse-tree.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4247,7 +4247,11 @@ struct OpenACCDeclarativeConstruct {
42474247
EMPTY_CLASS(AccEndLoop);
42484248
struct OpenACCLoopConstruct {
42494249
TUPLE_CLASS_BOILERPLATE(OpenACCLoopConstruct);
4250-
std::tuple<AccBeginLoopDirective, DoConstruct, std::optional<AccEndLoop>> t;
4250+
OpenACCLoopConstruct(AccBeginLoopDirective &&a)
4251+
: t({std::move(a), std::nullopt, std::nullopt}) {}
4252+
std::tuple<AccBeginLoopDirective, std::optional<DoConstruct>,
4253+
std::optional<AccEndLoop>>
4254+
t;
42514255
};
42524256

42534257
struct OpenACCStandaloneConstruct {

flang/lib/Parser/openacc-parsers.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,7 @@ TYPE_PARSER(construct<AccEndLoop>(startAccLine >> "END LOOP"_tok))
154154

155155
TYPE_PARSER(construct<OpenACCLoopConstruct>(
156156
sourced(Parser<AccBeginLoopDirective>{} / endAccLine),
157-
withMessage("A DO loop must follow the loop construct"_err_en_US,
158-
Parser<DoConstruct>{}),
159-
maybe(Parser<AccEndLoop>{} / endAccLine)))
157+
maybe(Parser<DoConstruct>{}), maybe(Parser<AccEndLoop>{} / endAccLine)))
160158

161159
// 2.15.1 Routine directive
162160
TYPE_PARSER(sourced(construct<OpenACCRoutineConstruct>(verbatim("ROUTINE"_tok),

flang/lib/Parser/unparse.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1947,7 +1947,7 @@ class UnparseVisitor {
19471947
Walk(std::get<AccBeginLoopDirective>(x.t));
19481948
Put("\n");
19491949
EndOpenACC();
1950-
Walk(std::get<DoConstruct>(x.t));
1950+
Walk(std::get<std::optional<DoConstruct>>(x.t));
19511951
}
19521952
void Unparse(const AccBeginLoopDirective &x) {
19531953
Walk(std::get<AccLoopDirective>(x.t));

flang/lib/Semantics/canonicalize-acc.cpp

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -109,21 +109,37 @@ class CanonicalizationOfAcc {
109109

110110
void RewriteOpenACCLoopConstruct(parser::OpenACCLoopConstruct &x,
111111
parser::Block &block, parser::Block::iterator it) {
112+
parser::Block::iterator nextIt;
112113
auto &beginDir{std::get<parser::AccBeginLoopDirective>(x.t)};
113114
auto &dir{std::get<parser::AccLoopDirective>(beginDir.t)};
114-
const auto &doCons{std::get<parser::DoConstruct>(x.t)};
115+
auto &nestedDo{std::get<std::optional<parser::DoConstruct>>(x.t)};
116+
117+
if (!nestedDo) {
118+
nextIt = it;
119+
if (++nextIt != block.end()) {
120+
if (auto *doCons{parser::Unwrap<parser::DoConstruct>(*nextIt)}) {
121+
nestedDo = std::move(*doCons);
122+
nextIt = block.erase(nextIt);
123+
}
124+
}
125+
}
115126

116-
if (!doCons.GetLoopControl()) {
117-
messages_.Say(dir.source,
118-
"DO loop after the %s directive must have loop control"_err_en_US,
119-
parser::ToUpperCaseLetters(dir.source.ToString()));
127+
if (nestedDo) {
128+
if (!nestedDo->GetLoopControl()) {
129+
messages_.Say(dir.source,
130+
"DO loop after the %s directive must have loop control"_err_en_US,
131+
parser::ToUpperCaseLetters(dir.source.ToString()));
132+
return;
133+
}
134+
CheckDoConcurrentClauseRestriction<parser::OpenACCLoopConstruct,
135+
parser::AccBeginLoopDirective>(x, *nestedDo);
136+
CheckTileClauseRestriction<parser::OpenACCLoopConstruct,
137+
parser::AccBeginLoopDirective>(x, *nestedDo);
120138
return;
121139
}
122-
123-
CheckDoConcurrentClauseRestriction<parser::OpenACCLoopConstruct,
124-
parser::AccBeginLoopDirective>(x, doCons);
125-
CheckTileClauseRestriction<parser::OpenACCLoopConstruct,
126-
parser::AccBeginLoopDirective>(x, doCons);
140+
messages_.Say(dir.source,
141+
"A DO loop must follow the %s directive"_err_en_US,
142+
parser::ToUpperCaseLetters(dir.source.ToString()));
127143
}
128144

129145
void RewriteOpenACCCombinedConstruct(parser::OpenACCCombinedConstruct &x,

flang/lib/Semantics/resolve-directives.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,8 +1153,8 @@ void AccAttributeVisitor::PrivatizeAssociatedLoopIndex(
11531153
return nullptr;
11541154
};
11551155

1156-
const auto &outer{std::get<parser::DoConstruct>(x.t)};
1157-
for (const parser::DoConstruct *loop{&outer}; loop && level > 0; --level) {
1156+
const auto &outer{std::get<std::optional<parser::DoConstruct>>(x.t)};
1157+
for (const parser::DoConstruct *loop{&*outer}; loop && level > 0; --level) {
11581158
// go through all the nested do-loops and resolve index variables
11591159
const parser::Name *iv{GetLoopIndex(*loop)};
11601160
if (iv) {

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,4 +315,10 @@ program acc_loop
315315
! CHECK: %[[CACHE:.*]] = acc.cache varPtr(%{{.*}} : !fir.ref<!fir.array<10xf32>>) bounds(%{{.*}}) -> !fir.ref<!fir.array<10xf32>> {name = "b"}
316316
! CHECK: acc.loop cache(%[[CACHE]] : !fir.ref<!fir.array<10xf32>>)
317317

318+
!$acc loop
319+
do 100 i=0, n
320+
100 continue
321+
! CHECK: acc.loop
322+
! CHECK: fir.do_loop
323+
318324
end program

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@ program openacc_clause_validity
44

55
implicit none
66

7-
integer :: i
7+
integer :: i, n
88

99
i = 0
1010

11+
!ERROR: A DO loop must follow the LOOP directive
1112
!$acc loop
12-
!ERROR: A DO loop must follow the loop construct
1313
i = 1
1414

15+
!$acc loop
16+
do 100 i=0, n
17+
100 continue
18+
1519
end

0 commit comments

Comments
 (0)