[flang-commits] [flang] 561a369 - [flang][openacc] Relax rule for end directive on combined construct

Valentin Clement via flang-commits flang-commits at lists.llvm.org
Tue Jun 13 13:58:26 PDT 2023


Author: Valentin Clement
Date: 2023-06-13T13:58:20-07:00
New Revision: 561a3697099aa74fcbaf426e6d0ebeb783b57a1e

URL: https://github.com/llvm/llvm-project/commit/561a3697099aa74fcbaf426e6d0ebeb783b57a1e
DIFF: https://github.com/llvm/llvm-project/commit/561a3697099aa74fcbaf426e6d0ebeb783b57a1e.diff

LOG: [flang][openacc] Relax rule for end directive on combined construct

Make the keyword `loop` optional for the end driective on combined
construct. This done to extend compatibility with other compiler that
allow this.

Reviewed By: razvanlupusoru

Differential Revision: https://reviews.llvm.org/D151856

Added: 
    flang/docs/OpenACC.md
    flang/test/Semantics/OpenACC/acc-combined-loop.f90

Modified: 
    flang/lib/Parser/executable-parsers.cpp
    flang/lib/Parser/openacc-parsers.cpp
    flang/lib/Parser/type-parsers.h
    flang/lib/Semantics/canonicalize-acc.cpp
    flang/test/Semantics/OpenACC/acc-canonicalization-validity.f90
    flang/test/Semantics/OpenACC/acc-kernels-loop.f90
    flang/test/Semantics/OpenACC/acc-parallel-loop-validity.f90
    flang/test/Semantics/OpenACC/acc-serial-loop.f90

Removed: 
    


################################################################################
diff  --git a/flang/docs/OpenACC.md b/flang/docs/OpenACC.md
new file mode 100644
index 0000000000000..8132a5beaef03
--- /dev/null
+++ b/flang/docs/OpenACC.md
@@ -0,0 +1,17 @@
+<!--===- docs/Extensions.md 
+  
+   Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+   See https://llvm.org/LICENSE.txt for license information.
+   SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+  
+-->
+
+# OpenACC in Flang
+
+```eval_rst
+.. contents::
+   :local:
+```
+
+## Intentional deviation from the specification
+* The end directive for combined construct can omit the `loop` keyword.

diff  --git a/flang/lib/Parser/executable-parsers.cpp b/flang/lib/Parser/executable-parsers.cpp
index 56ca3ed4991de..a61bf2ce1551e 100644
--- a/flang/lib/Parser/executable-parsers.cpp
+++ b/flang/lib/Parser/executable-parsers.cpp
@@ -52,8 +52,7 @@ constexpr auto executableConstruct{first(
     construct<ExecutableConstruct>(indirect(forallConstruct)),
     construct<ExecutableConstruct>(indirect(ompEndLoopDirective)),
     construct<ExecutableConstruct>(indirect(openmpConstruct)),
-    construct<ExecutableConstruct>(indirect(accEndCombinedDirective)),
-    construct<ExecutableConstruct>(indirect(openaccConstruct)),
+    construct<ExecutableConstruct>(indirect(Parser<OpenACCConstruct>{})),
     construct<ExecutableConstruct>(indirect(compilerDirective)),
     construct<ExecutableConstruct>(indirect(Parser<CUFKernelDoConstruct>{})))};
 

diff  --git a/flang/lib/Parser/openacc-parsers.cpp b/flang/lib/Parser/openacc-parsers.cpp
index 3ea5b78b980de..eed96307421c3 100644
--- a/flang/lib/Parser/openacc-parsers.cpp
+++ b/flang/lib/Parser/openacc-parsers.cpp
@@ -232,10 +232,19 @@ TYPE_CONTEXT_PARSER("OpenACC construct"_en_US,
             construct<OpenACCConstruct>(Parser<OpenACCWaitConstruct>{}),
             construct<OpenACCConstruct>(Parser<OpenACCAtomicConstruct>{})))
 
-TYPE_PARSER(startAccLine >> sourced(construct<AccEndCombinedDirective>(sourced(
-                                "END"_tok >> Parser<AccCombinedDirective>{}))))
+TYPE_PARSER(startAccLine >>
+    sourced(construct<AccEndCombinedDirective>(sourced("END"_tok >>
+        construct<AccCombinedDirective>("KERNELS"_tok >> maybe("LOOP"_tok) >>
+                pure(llvm::acc::Directive::ACCD_kernels_loop) ||
+            "PARALLEL"_tok >> maybe("LOOP"_tok) >>
+                pure(llvm::acc::Directive::ACCD_parallel_loop) ||
+            "SERIAL"_tok >> maybe("LOOP"_tok) >>
+                pure(llvm::acc::Directive::ACCD_serial_loop))))))
 
 TYPE_PARSER(construct<OpenACCCombinedConstruct>(
-    sourced(Parser<AccBeginCombinedDirective>{} / endAccLine)))
+    sourced(Parser<AccBeginCombinedDirective>{} / endAccLine),
+    withMessage("A DO loop must follow the combined construct"_err_en_US,
+        Parser<DoConstruct>{}),
+    maybe(Parser<AccEndCombinedDirective>{} / endAccLine)))
 
 } // namespace Fortran::parser

diff  --git a/flang/lib/Parser/type-parsers.h b/flang/lib/Parser/type-parsers.h
index b886af4a72a09..da7d017d59768 100644
--- a/flang/lib/Parser/type-parsers.h
+++ b/flang/lib/Parser/type-parsers.h
@@ -132,7 +132,6 @@ constexpr Parser<EntryStmt> entryStmt; // R1541
 constexpr Parser<ContainsStmt> containsStmt; // R1543
 constexpr Parser<CompilerDirective> compilerDirective;
 constexpr Parser<OpenACCConstruct> openaccConstruct;
-constexpr Parser<AccEndCombinedDirective> accEndCombinedDirective;
 constexpr Parser<OpenACCDeclarativeConstruct> openaccDeclarativeConstruct;
 constexpr Parser<OpenMPConstruct> openmpConstruct;
 constexpr Parser<OpenMPDeclarativeConstruct> openmpDeclarativeConstruct;

diff  --git a/flang/lib/Semantics/canonicalize-acc.cpp b/flang/lib/Semantics/canonicalize-acc.cpp
index c188450a92d46..5ad8257bec694 100644
--- a/flang/lib/Semantics/canonicalize-acc.cpp
+++ b/flang/lib/Semantics/canonicalize-acc.cpp
@@ -169,36 +169,20 @@ class CanonicalizationOfAcc {
     parser::Block::iterator nextIt;
     auto &beginDir{std::get<parser::AccBeginCombinedDirective>(x.t)};
     auto &dir{std::get<parser::AccCombinedDirective>(beginDir.t)};
-
-    nextIt = it;
-    if (++nextIt != block.end()) {
-      if (auto *doCons{parser::Unwrap<parser::DoConstruct>(*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()));
-          return;
-        }
-        // move DoConstruct
-        std::get<std::optional<parser::DoConstruct>>(x.t) = std::move(*doCons);
-        nextIt = block.erase(nextIt);
-        // try to match AccEndCombinedDirective
-        if (nextIt != block.end()) {
-          if (auto *endDir{
-                  parser::Unwrap<parser::AccEndCombinedDirective>(*nextIt)}) {
-            std::get<std::optional<parser::AccEndCombinedDirective>>(x.t) =
-                std::move(*endDir);
-            block.erase(nextIt);
-          }
-        }
-
-        CheckDoConcurrentClauseRestriction<parser::OpenACCCombinedConstruct,
-            parser::AccBeginCombinedDirective>(x);
-        CheckTileClauseRestriction<parser::OpenACCCombinedConstruct,
-            parser::AccBeginCombinedDirective>(x);
-
-        return; // found do-loop
+    auto &doConstruct{std::get<std::optional<parser::DoConstruct>>(x.t)};
+
+    if (doConstruct) {
+      CheckDoConcurrentClauseRestriction<parser::OpenACCCombinedConstruct,
+          parser::AccBeginCombinedDirective>(x);
+      CheckTileClauseRestriction<parser::OpenACCCombinedConstruct,
+          parser::AccBeginCombinedDirective>(x);
+      if (!doConstruct->GetLoopControl()) {
+        messages_.Say(dir.source,
+            "DO loop after the %s directive must have loop control"_err_en_US,
+            parser::ToUpperCaseLetters(dir.source.ToString()));
+        return;
       }
+      return;
     }
     messages_.Say(dir.source,
         "A DO loop must follow the %s directive"_err_en_US,

diff  --git a/flang/test/Semantics/OpenACC/acc-canonicalization-validity.f90 b/flang/test/Semantics/OpenACC/acc-canonicalization-validity.f90
index ad179d3b5f494..b431e4fb06850 100644
--- a/flang/test/Semantics/OpenACC/acc-canonicalization-validity.f90
+++ b/flang/test/Semantics/OpenACC/acc-canonicalization-validity.f90
@@ -24,27 +24,6 @@ program openacc_clause_validity
   do
   end do
 
-  !ERROR: A DO loop must follow the PARALLEL LOOP directive
-  !$acc parallel loop
-  i = 1
-
-  !ERROR: A DO loop must follow the KERNELS LOOP directive
-  !$acc kernels loop
-  i = 1
-
-  !ERROR: A DO loop must follow the SERIAL LOOP directive
-  !$acc serial loop
-  i = 1
-
-  !ERROR: The END PARALLEL LOOP directive must follow the DO loop associated with the loop construct
-  !$acc end parallel loop
-
-  !ERROR: The END KERNELS LOOP directive must follow the DO loop associated with the loop construct
-  !$acc end kernels loop
-
-  !ERROR: The END SERIAL LOOP directive must follow the DO loop associated with the loop construct
-  !$acc end serial loop
-
   !$acc parallel loop
   do i = 1, N
     a(i) = 3.14

diff  --git a/flang/test/Semantics/OpenACC/acc-combined-loop.f90 b/flang/test/Semantics/OpenACC/acc-combined-loop.f90
new file mode 100644
index 0000000000000..04ff6a308d55f
--- /dev/null
+++ b/flang/test/Semantics/OpenACC/acc-combined-loop.f90
@@ -0,0 +1,21 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc
+
+program openacc_combined_loop
+  implicit none
+  integer :: i
+
+  i = 1
+
+  !$acc parallel loop
+  !ERROR: A DO loop must follow the combined construct
+  i = 1
+
+  !$acc kernels loop
+  !ERROR: A DO loop must follow the combined construct
+  i = 1
+
+  !$acc serial loop
+  !ERROR: A DO loop must follow the combined construct
+  i = 1
+
+end

diff  --git a/flang/test/Semantics/OpenACC/acc-kernels-loop.f90 b/flang/test/Semantics/OpenACC/acc-kernels-loop.f90
index d84e1c2dedf40..5facd47377880 100644
--- a/flang/test/Semantics/OpenACC/acc-kernels-loop.f90
+++ b/flang/test/Semantics/OpenACC/acc-kernels-loop.f90
@@ -34,6 +34,18 @@ program openacc_kernels_loop_validity
     a(i) = 3.14
   end do
 
+  !$acc kernels loop
+  do i = 1, N
+    a(i) = 3.14
+  end do
+  !$acc end kernels loop
+
+  !$acc kernels loop
+  do i = 1, N
+    a(i) = 3.14
+  end do
+  !$acc end kernels loop
+
   !$acc kernels loop num_gangs(8)
   do i = 1, N
     a(i) = 3.14

diff  --git a/flang/test/Semantics/OpenACC/acc-parallel-loop-validity.f90 b/flang/test/Semantics/OpenACC/acc-parallel-loop-validity.f90
index 312baacbc00a8..9f231851c4410 100644
--- a/flang/test/Semantics/OpenACC/acc-parallel-loop-validity.f90
+++ b/flang/test/Semantics/OpenACC/acc-parallel-loop-validity.f90
@@ -17,6 +17,23 @@ program openacc_parallel_loop_validity
   real(8), dimension(N) :: a, f, g, h
   real(8), dimension(N, N) :: aa, bb, cc
 
+  !$acc parallel loop
+  do i = 1, N
+    a(i) = 3.14
+  end do
+
+  !$acc parallel loop
+  do i = 1, N
+    a(i) = 3.14
+  end do
+  !$acc end parallel loop
+
+  !$acc parallel loop
+  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

diff  --git a/flang/test/Semantics/OpenACC/acc-serial-loop.f90 b/flang/test/Semantics/OpenACC/acc-serial-loop.f90
index b0e04dd25a800..bef117b71f931 100644
--- a/flang/test/Semantics/OpenACC/acc-serial-loop.f90
+++ b/flang/test/Semantics/OpenACC/acc-serial-loop.f90
@@ -94,4 +94,16 @@ program openacc_serial_loop_validity
   !ERROR: Unmatched END PARALLEL LOOP directive
   !$acc end parallel loop
 
+  !$acc serial loop
+  do i = 1, N
+    a(i) = 3.14
+  end do
+  !$acc end serial loop
+
+  !$acc serial loop
+  do i = 1, N
+    a(i) = 3.14
+  end do
+  !$acc end serial
+
 end program openacc_serial_loop_validity


        


More information about the flang-commits mailing list