[flang-commits] [flang] [flang][openacc] Support labeled DO loop after acc loop directive (PR #66294)
via flang-commits
flang-commits at lists.llvm.org
Wed Sep 13 14:38:44 PDT 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-parser
<details>
<summary>Changes</summary>
Make the `DoConstruct` in `OpenACCLoopConstruct` optional and move the labeled do construct in in the canonicalization step.
--
Full diff: https://github.com/llvm/llvm-project/pull/66294.diff
7 Files Affected:
- (modified) flang/include/flang/Parser/parse-tree.h (+5-1)
- (modified) flang/lib/Parser/openacc-parsers.cpp (+1-3)
- (modified) flang/lib/Parser/unparse.cpp (+1-1)
- (modified) flang/lib/Semantics/canonicalize-acc.cpp (+26-10)
- (modified) flang/lib/Semantics/resolve-directives.cpp (+2-2)
- (modified) flang/test/Lower/OpenACC/acc-loop.f90 (+6)
- (modified) flang/test/Semantics/OpenACC/acc-loop-validity.f90 (+6-2)
<pre>
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 5d92ecb05841767..cb4bb59bf312c7c 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -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 {
diff --git a/flang/lib/Parser/openacc-parsers.cpp b/flang/lib/Parser/openacc-parsers.cpp
index afa12b88019bd9a..e1cbe6b86df91e9 100644
--- a/flang/lib/Parser/openacc-parsers.cpp
+++ b/flang/lib/Parser/openacc-parsers.cpp
@@ -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),
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 398545d315e5cd5..6cac3fb5859f87b 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -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));
diff --git a/flang/lib/Semantics/canonicalize-acc.cpp b/flang/lib/Semantics/canonicalize-acc.cpp
index e79ab997637b083..3887e479cbce5d5 100644
--- a/flang/lib/Semantics/canonicalize-acc.cpp
+++ b/flang/lib/Semantics/canonicalize-acc.cpp
@@ -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,
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 9a2689c2e6c81d5..63a3e1cd31549c0 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -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) {
diff --git a/flang/test/Lower/OpenACC/acc-loop.f90 b/flang/test/Lower/OpenACC/acc-loop.f90
index f902728b67100f3..ec5eff5da78e7ed 100644
--- a/flang/test/Lower/OpenACC/acc-loop.f90
+++ b/flang/test/Lower/OpenACC/acc-loop.f90
@@ -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
diff --git a/flang/test/Semantics/OpenACC/acc-loop-validity.f90 b/flang/test/Semantics/OpenACC/acc-loop-validity.f90
index 906602640efacc7..205e67a4728fcbe 100644
--- a/flang/test/Semantics/OpenACC/acc-loop-validity.f90
+++ b/flang/test/Semantics/OpenACC/acc-loop-validity.f90
@@ -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
</pre>
</details>
https://github.com/llvm/llvm-project/pull/66294
More information about the flang-commits
mailing list