[flang-commits] [flang] Add support for assume_aligned directive (PR #81747)

Mats Petersson via flang-commits flang-commits at lists.llvm.org
Mon Feb 19 09:01:25 PST 2024


https://github.com/Leporacanthicus updated https://github.com/llvm/llvm-project/pull/81747

>From b3448b045160e2d7c37adc4e3299666b1db1ba59 Mon Sep 17 00:00:00 2001
From: Mats Petersson <mats.petersson at arm.com>
Date: Fri, 9 Feb 2024 16:48:30 +0000
Subject: [PATCH 1/2] Add support for assume_aligned directive

This adds the parsing (and unparse) of the compiler
drective assume_aligned.

The compiler will issue a warning that the directive is ignored.
---
 flang/include/flang/Parser/dump-parse-tree.h |  1 +
 flang/include/flang/Parser/parse-tree.h      |  8 +++-
 flang/lib/Parser/Fortran-parsers.cpp         |  4 ++
 flang/lib/Parser/unparse.cpp                 |  9 ++++
 flang/test/Parser/assume-aligned.f90         | 50 ++++++++++++++++++++
 5 files changed, 71 insertions(+), 1 deletion(-)
 create mode 100644 flang/test/Parser/assume-aligned.f90

diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index d067a7273540f0..048008a8d80c79 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -205,6 +205,7 @@ class ParseTreeDumper {
   NODE(parser, CompilerDirective)
   NODE(CompilerDirective, IgnoreTKR)
   NODE(CompilerDirective, LoopCount)
+  NODE(CompilerDirective, AssumeAligned)
   NODE(CompilerDirective, NameValue)
   NODE(parser, ComplexLiteralConstant)
   NODE(parser, ComplexPart)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index e9bfb728a2bef6..28215219b4943a 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -3309,12 +3309,18 @@ struct CompilerDirective {
   struct LoopCount {
     WRAPPER_CLASS_BOILERPLATE(LoopCount, std::list<std::uint64_t>);
   };
+  struct AssumeAligned {
+    TUPLE_CLASS_BOILERPLATE(AssumeAligned);
+    std::tuple<common::Indirection<Designator>, uint64_t> t;
+  };
   struct NameValue {
     TUPLE_CLASS_BOILERPLATE(NameValue);
     std::tuple<Name, std::optional<std::uint64_t>> t;
   };
   CharBlock source;
-  std::variant<std::list<IgnoreTKR>, LoopCount, std::list<NameValue>> u;
+  std::variant<std::list<IgnoreTKR>, LoopCount, AssumeAligned,
+      std::list<NameValue>>
+      u;
 };
 
 // (CUDA) ATTRIBUTE(attribute) [::] name-list
diff --git a/flang/lib/Parser/Fortran-parsers.cpp b/flang/lib/Parser/Fortran-parsers.cpp
index 0dd95d69d3c662..1bea0dc69f1c43 100644
--- a/flang/lib/Parser/Fortran-parsers.cpp
+++ b/flang/lib/Parser/Fortran-parsers.cpp
@@ -1268,9 +1268,13 @@ constexpr auto ignore_tkr{
 constexpr auto loopCount{
     "DIR$ LOOP COUNT" >> construct<CompilerDirective::LoopCount>(
                              parenthesized(nonemptyList(digitString64)))};
+constexpr auto assumeAligned{"DIR$ ASSUME_ALIGNED" >>
+    construct<CompilerDirective::AssumeAligned>(
+        indirect(designator), ":"_tok >> digitString64)};
 TYPE_PARSER(beginDirective >>
     sourced(construct<CompilerDirective>(ignore_tkr) ||
         construct<CompilerDirective>(loopCount) ||
+        construct<CompilerDirective>(assumeAligned) ||
         construct<CompilerDirective>(
             "DIR$" >> many(construct<CompilerDirective::NameValue>(name,
                           maybe(("="_tok || ":"_tok) >> digitString64))))) /
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 1df49a688a12a0..41c1a754d68682 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -1819,6 +1819,10 @@ class UnparseVisitor {
             [&](const CompilerDirective::LoopCount &lcount) {
               Walk("!DIR$ LOOP COUNT (", lcount.v, ", ", ")");
             },
+            [&](const CompilerDirective::AssumeAligned &assumeAligned) {
+              Word("!DIR$ ASSUME_ALIGNED ");
+              Walk(assumeAligned);
+            },
             [&](const std::list<CompilerDirective::NameValue> &names) {
               Walk("!DIR$ ", names, " ");
             },
@@ -1841,6 +1845,11 @@ class UnparseVisitor {
     Walk(std::get<Name>(x.t));
     Walk("=", std::get<std::optional<std::uint64_t>>(x.t));
   }
+  void Unparse(const CompilerDirective::AssumeAligned &x) {
+    Walk(std::get<common::Indirection<Designator>>(x.t));
+    Put(":");
+    Walk(std::get<uint64_t>(x.t));
+  }
 
   // OpenACC Directives & Clauses
   void Unparse(const AccAtomicCapture &x) {
diff --git a/flang/test/Parser/assume-aligned.f90 b/flang/test/Parser/assume-aligned.f90
new file mode 100644
index 00000000000000..426916f2544dbe
--- /dev/null
+++ b/flang/test/Parser/assume-aligned.f90
@@ -0,0 +1,50 @@
+! RUN: %flang_fc1 -fdebug-unparse-no-sema %s 2>&1 | FileCheck %s
+
+SUBROUTINE aa(a, nn)
+  IMPLICIT NONE
+  INTEGER, INTENT(IN) :: nn
+  COMPLEX(8), INTENT(INOUT), DIMENSION(1:nn) :: a
+  INTEGER :: i
+  !DIR$ assume_aligned a:16
+!CHECK:  !DIR$ ASSUME_ALIGNED a:16
+  !DIR$ assume_aligned a (1):16
+!CHECK:  !DIR$ ASSUME_ALIGNED a(1):16  
+  !DIR$ assume_aligned a(1):16
+!CHECK:  !DIR$ ASSUME_ALIGNED a(1):16
+  !DIR$ assume_aligned a(nn):16
+!CHECK:  !DIR$ ASSUME_ALIGNED a(nn):16  
+  !DIR$ assume_aligned a(44):16
+!CHECK:  !DIR$ ASSUME_ALIGNED a(44):16  
+  DO i=1,nn
+     a(i)=a(i)+1.5
+  END DO
+END SUBROUTINE aa
+
+SUBROUTINE bb(v, s, e)
+  IMPLICIT NONE
+  INTEGER, INTENT(IN) :: s(3), e(3)
+  INTEGER :: y,z
+  REAL(8),   INTENT(IN)  :: v(s(1):e(1),s(2):e(2),s(3):e(3))
+  !DIR$ assume_aligned v(s(1),y,z)     :64
+!CHECK: !DIR$ ASSUME_ALIGNED v(s(1),y,z):64
+END SUBROUTINE bb
+
+SUBROUTINE f(n)
+  IMPLICIT NONE
+  TYPE node 
+    REAL(KIND=8), POINTER :: a(:,:)
+  END TYPE NODE 
+  
+  TYPE(NODE), POINTER :: nodes
+  INTEGER :: i
+  INTEGER, INTENT(IN) :: n
+
+  ALLOCATE(nodes) 
+  ALLOCATE(nodes%a(1000,1000))
+
+  !DIR$ ASSUME_ALIGNED nodes%a(1,1) : 16               
+!CHECK: !DIR$ ASSUME_ALIGNED nodes%a(1,1):16
+  DO i=1,n 
+    nodes%a(1,i) = nodes%a(1,i)+1 
+  END DO 
+END SUBROUTINE f

>From 5ac481296e16683fd65e48ef77f4210992b14860 Mon Sep 17 00:00:00 2001
From: Mats Petersson <mats.petersson at arm.com>
Date: Mon, 19 Feb 2024 16:49:32 +0000
Subject: [PATCH 2/2] Fix review comments and bug-fix for multiple variables on
 one line

Add documentation added as per review comment.

Also, the directive should accept multiple pairs of variable (or designator)
and alignment values on the same line, so fix that and add test.
---
 flang/docs/Directives.md                | 6 ++++++
 flang/include/flang/Parser/parse-tree.h | 2 +-
 flang/lib/Parser/Fortran-parsers.cpp    | 4 ++--
 flang/lib/Parser/unparse.cpp            | 5 +++--
 flang/test/Parser/assume-aligned.f90    | 7 +++++++
 5 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/flang/docs/Directives.md b/flang/docs/Directives.md
index 134de36f884d70..fe08b4f855f23c 100644
--- a/flang/docs/Directives.md
+++ b/flang/docs/Directives.md
@@ -30,3 +30,9 @@ A list of non-standard directives supported by Flang
     end
   end interface
 ```
+* `!dir$ assume_aligned desginator:alignment`, where designator is a variable,
+  maybe with array indices, and alignment is what the compiler should assume the
+  alignment to be. E.g A:64 or B(1,1,1):128. The alignment should be a power of 2,
+  and is limited to 256.
+  [This directive is currently recognised by the parser, but not
+  handled by the other parts of the compiler].
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 28215219b4943a..a32676be0d6d97 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -3318,7 +3318,7 @@ struct CompilerDirective {
     std::tuple<Name, std::optional<std::uint64_t>> t;
   };
   CharBlock source;
-  std::variant<std::list<IgnoreTKR>, LoopCount, AssumeAligned,
+  std::variant<std::list<IgnoreTKR>, LoopCount, std::list<AssumeAligned>,
       std::list<NameValue>>
       u;
 };
diff --git a/flang/lib/Parser/Fortran-parsers.cpp b/flang/lib/Parser/Fortran-parsers.cpp
index 1bea0dc69f1c43..fc81a477897a3c 100644
--- a/flang/lib/Parser/Fortran-parsers.cpp
+++ b/flang/lib/Parser/Fortran-parsers.cpp
@@ -1269,8 +1269,8 @@ constexpr auto loopCount{
     "DIR$ LOOP COUNT" >> construct<CompilerDirective::LoopCount>(
                              parenthesized(nonemptyList(digitString64)))};
 constexpr auto assumeAligned{"DIR$ ASSUME_ALIGNED" >>
-    construct<CompilerDirective::AssumeAligned>(
-        indirect(designator), ":"_tok >> digitString64)};
+    optionalList(construct<CompilerDirective::AssumeAligned>(
+        indirect(designator), ":"_tok >> digitString64))};
 TYPE_PARSER(beginDirective >>
     sourced(construct<CompilerDirective>(ignore_tkr) ||
         construct<CompilerDirective>(loopCount) ||
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 41c1a754d68682..600aa01999dab7 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -1819,9 +1819,10 @@ class UnparseVisitor {
             [&](const CompilerDirective::LoopCount &lcount) {
               Walk("!DIR$ LOOP COUNT (", lcount.v, ", ", ")");
             },
-            [&](const CompilerDirective::AssumeAligned &assumeAligned) {
+            [&](const std::list<CompilerDirective::AssumeAligned>
+                    &assumeAligned) {
               Word("!DIR$ ASSUME_ALIGNED ");
-              Walk(assumeAligned);
+              Walk(" ", assumeAligned, ", ");
             },
             [&](const std::list<CompilerDirective::NameValue> &names) {
               Walk("!DIR$ ", names, " ");
diff --git a/flang/test/Parser/assume-aligned.f90 b/flang/test/Parser/assume-aligned.f90
index 426916f2544dbe..c61c10d61d72fe 100644
--- a/flang/test/Parser/assume-aligned.f90
+++ b/flang/test/Parser/assume-aligned.f90
@@ -48,3 +48,10 @@ SUBROUTINE f(n)
     nodes%a(1,i) = nodes%a(1,i)+1 
   END DO 
 END SUBROUTINE f
+
+SUBROUTINE g(a, b)
+  IMPLICIT NONE
+  INTEGER, INTENT(in) :: a(128), b(128)
+  !DIR$ ASSUME_ALIGNED a:32, b:64
+!CHECK: !DIR$ ASSUME_ALIGNED a:32, b:64
+END SUBROUTINE g



More information about the flang-commits mailing list