[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