[flang-commits] [flang] 4df2a5f - [flang][openacc] Add check for tile clause restriction
via flang-commits
flang-commits at lists.llvm.org
Thu Aug 27 19:13:58 PDT 2020
Author: Valentin Clement
Date: 2020-08-27T22:13:46-04:00
New Revision: 4df2a5f782db1d4e2e11ed1cf64e085e6fce7893
URL: https://github.com/llvm/llvm-project/commit/4df2a5f782db1d4e2e11ed1cf64e085e6fce7893
DIFF: https://github.com/llvm/llvm-project/commit/4df2a5f782db1d4e2e11ed1cf64e085e6fce7893.diff
LOG: [flang][openacc] Add check for tile clause restriction
The tile clause in OpenACC 3.0 imposes some restriction. Element in the tile size list are either * or a
constant positive integer expression. If there are n tile sizes in the list, the loop construct must be immediately
followed by n tightly-nested loops.
This patch implement these restrictions and add some tests.
Reviewed By: klausler
Differential Revision: https://reviews.llvm.org/D86655
Added:
Modified:
flang/include/flang/Parser/dump-parse-tree.h
flang/include/flang/Parser/parse-tree.h
flang/lib/Parser/openacc-parsers.cpp
flang/lib/Semantics/canonicalize-acc.cpp
flang/test/Semantics/acc-canonicalization-validity.f90
flang/test/Semantics/acc-clause-validity.f90
llvm/include/llvm/Frontend/OpenACC/ACC.td
Removed:
################################################################################
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index 37a16e7e812d..41ff9631d101 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -86,6 +86,8 @@ class ParseTreeDumper {
NODE(parser, AccSizeExpr)
NODE(parser, AccSizeExprList)
NODE(parser, AccStandaloneDirective)
+ NODE(parser, AccTileExpr)
+ NODE(parser, AccTileExprList)
NODE(parser, AccLoopDirective)
NODE(parser, AccWaitArgument)
static std::string GetNodeName(const llvm::acc::Directive &x) {
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 317d772889ee..7f9984bc5048 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -3857,6 +3857,16 @@ struct AccWaitArgument {
std::tuple<std::optional<ScalarIntExpr>, std::list<ScalarIntExpr>> t;
};
+struct AccTileExpr {
+ TUPLE_CLASS_BOILERPLATE(AccTileExpr);
+ CharBlock source;
+ std::tuple<std::optional<ScalarIntConstantExpr>> t; // if null then *
+};
+
+struct AccTileExprList {
+ WRAPPER_CLASS_BOILERPLATE(AccTileExprList, std::list<AccTileExpr>);
+};
+
struct AccSizeExpr {
TUPLE_CLASS_BOILERPLATE(AccSizeExpr);
CharBlock source;
diff --git a/flang/lib/Parser/openacc-parsers.cpp b/flang/lib/Parser/openacc-parsers.cpp
index 24b8a595ca5d..78ed940aa094 100644
--- a/flang/lib/Parser/openacc-parsers.cpp
+++ b/flang/lib/Parser/openacc-parsers.cpp
@@ -102,7 +102,7 @@ TYPE_PARSER("AUTO" >> construct<AccClause>(construct<AccClause::Auto>()) ||
maybe(parenthesized(scalarLogicalExpr)))) ||
"SEQ" >> construct<AccClause>(construct<AccClause::Seq>()) ||
"TILE" >> construct<AccClause>(construct<AccClause::Tile>(
- parenthesized(Parser<AccSizeExprList>{}))) ||
+ parenthesized(Parser<AccTileExprList>{}))) ||
"USE_DEVICE" >> construct<AccClause>(construct<AccClause::UseDevice>(
parenthesized(Parser<AccObjectList>{}))) ||
"VECTOR_LENGTH" >> construct<AccClause>(construct<AccClause::VectorLength>(
@@ -131,11 +131,20 @@ TYPE_PARSER(construct<AccWaitArgument>(maybe("DEVNUM:" >> scalarIntExpr / ":"),
"QUEUES:" >> nonemptyList(scalarIntExpr) || nonemptyList(scalarIntExpr)))
// 2.9 (1609) size-expr is one of:
+// * (represented as an empty std::optional<ScalarIntExpr>)
// int-expr
TYPE_PARSER(construct<AccSizeExpr>(scalarIntExpr) ||
- construct<AccSizeExpr>("*" >> maybe(scalarIntExpr)))
+ construct<AccSizeExpr>("*" >> construct<std::optional<ScalarIntExpr>>()))
TYPE_PARSER(construct<AccSizeExprList>(nonemptyList(Parser<AccSizeExpr>{})))
+// tile size is one of:
+// * (represented as an empty std::optional<ScalarIntExpr>)
+// constant-int-expr
+TYPE_PARSER(construct<AccTileExpr>(scalarIntConstantExpr) ||
+ construct<AccTileExpr>(
+ "*" >> construct<std::optional<ScalarIntConstantExpr>>()))
+TYPE_PARSER(construct<AccTileExprList>(nonemptyList(Parser<AccTileExpr>{})))
+
// 2.9 (1607) gang-arg is one of:
// [num:]int-expr
// static:size-expr
diff --git a/flang/lib/Semantics/canonicalize-acc.cpp b/flang/lib/Semantics/canonicalize-acc.cpp
index 8cf04910ba6e..4916f2269ceb 100644
--- a/flang/lib/Semantics/canonicalize-acc.cpp
+++ b/flang/lib/Semantics/canonicalize-acc.cpp
@@ -48,6 +48,40 @@ class CanonicalizationOfAcc {
}
private:
+ // Check constraint in 2.9.7
+ // If there are n tile sizes in the list, the loop construct must be
+ // immediately followed by n tightly-nested loops.
+ template <typename C, typename D>
+ void CheckTileClauseRestriction(const C &x) {
+ const auto &beginLoopDirective = std::get<D>(x.t);
+ const auto &accClauseList =
+ std::get<parser::AccClauseList>(beginLoopDirective.t);
+ for (const auto &clause : accClauseList.v) {
+ if (const auto *tileClause =
+ std::get_if<parser::AccClause::Tile>(&clause.u)) {
+ const parser::AccTileExprList &tileExprList = tileClause->v;
+ const std::list<parser::AccTileExpr> &listTileExpr = tileExprList.v;
+ std::size_t tileArgNb = listTileExpr.size();
+
+ const auto &outer{std::get<std::optional<parser::DoConstruct>>(x.t)};
+ for (const parser::DoConstruct *loop{&*outer}; loop && tileArgNb > 0;
+ --tileArgNb) {
+ const auto &block{std::get<parser::Block>(loop->t)};
+ const auto it{block.begin()};
+ loop = it != block.end() ? parser::Unwrap<parser::DoConstruct>(*it)
+ : nullptr;
+ }
+
+ if (tileArgNb > 0) {
+ messages_.Say(beginLoopDirective.source,
+ "The loop construct with the TILE clause must be followed by %d "
+ "tightly-nested loops"_err_en_US,
+ listTileExpr.size());
+ }
+ }
+ }
+ }
+
void RewriteOpenACCLoopConstruct(parser::OpenACCLoopConstruct &x,
parser::Block &block, parser::Block::iterator it) {
// Check the sequence of DoConstruct in the same iteration
@@ -78,6 +112,8 @@ class CanonicalizationOfAcc {
"DO loop after the %s directive must have loop control"_err_en_US,
parser::ToUpperCaseLetters(dir.source.ToString()));
}
+ CheckTileClauseRestriction<parser::OpenACCLoopConstruct,
+ parser::AccBeginLoopDirective>(x);
return; // found do-loop
}
}
@@ -127,6 +163,8 @@ class CanonicalizationOfAcc {
"DO loop after the %s directive must have loop control"_err_en_US,
parser::ToUpperCaseLetters(dir.source.ToString()));
}
+ CheckTileClauseRestriction<parser::OpenACCCombinedConstruct,
+ parser::AccBeginCombinedDirective>(x);
return; // found do-loop
}
}
diff --git a/flang/test/Semantics/acc-canonicalization-validity.f90 b/flang/test/Semantics/acc-canonicalization-validity.f90
index 06c63ed25ddb..350f6315867c 100644
--- a/flang/test/Semantics/acc-canonicalization-validity.f90
+++ b/flang/test/Semantics/acc-canonicalization-validity.f90
@@ -92,4 +92,18 @@ program openacc_clause_validity
do
end do
+ !$acc parallel
+ !ERROR: The loop construct with the TILE clause must be followed by 2 tightly-nested loops
+ !$acc loop tile(2, 2)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !ERROR: The loop construct with the TILE clause must be followed by 2 tightly-nested loops
+ !$acc parallel loop tile(2, 2)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
end program openacc_clause_validity
diff --git a/flang/test/Semantics/acc-clause-validity.f90 b/flang/test/Semantics/acc-clause-validity.f90
index e960e5ccc528..9e5d2c71e2a8 100644
--- a/flang/test/Semantics/acc-clause-validity.f90
+++ b/flang/test/Semantics/acc-clause-validity.f90
@@ -24,6 +24,7 @@ program openacc_clause_validity
logical, dimension(N) :: d, e
real :: reduction_r
logical :: reduction_l
+ real(8), dimension(N, N) :: aa
!ERROR: At least one clause is required on the DECLARE directive
!$acc declare
@@ -83,6 +84,25 @@ program openacc_clause_validity
end do
!$acc end parallel
+ !$acc parallel
+ !$acc loop tile(2)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !$acc parallel loop tile(2)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc parallel loop tile(2, 2)
+ do i = 1, N
+ do j = 1, N
+ aa(i, j) = 3.14
+ end do
+ end do
+
!$acc parallel device_type(*) num_gangs(2)
!$acc loop
do i = 1, N
diff --git a/llvm/include/llvm/Frontend/OpenACC/ACC.td b/llvm/include/llvm/Frontend/OpenACC/ACC.td
index d6ed93374013..b15f8348c8f4 100644
--- a/llvm/include/llvm/Frontend/OpenACC/ACC.td
+++ b/llvm/include/llvm/Frontend/OpenACC/ACC.td
@@ -192,7 +192,7 @@ def ACCC_Private : Clause<"private"> {
// 2.9.7
def ACCC_Tile : Clause <"tile"> {
- let flangClassValue = "AccSizeExprList";
+ let flangClassValue = "AccTileExprList";
}
// 2.8.1
More information about the flang-commits
mailing list