[flang-commits] [flang] 3bbb2c2 - [flang] Preserve component array lower bounds in folding

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Fri Sep 23 17:13:21 PDT 2022


Author: Peter Klausler
Date: 2022-09-23T17:13:05-07:00
New Revision: 3bbb2c2d99b96a84306629d674ee00455f56b0fa

URL: https://github.com/llvm/llvm-project/commit/3bbb2c2d99b96a84306629d674ee00455f56b0fa
DIFF: https://github.com/llvm/llvm-project/commit/3bbb2c2d99b96a84306629d674ee00455f56b0fa.diff

LOG: [flang] Preserve component array lower bounds in folding

When a component array of a named constant is extracted as
a constant value, ensure that the lower bounds of the array
are properly acquired from the declaration of the component.

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

Added: 
    

Modified: 
    flang/include/flang/Evaluate/tools.h
    flang/lib/Evaluate/check-expression.cpp
    flang/lib/Evaluate/fold.cpp

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h
index 93e900b9e7e0..dc0c02669cbe 100644
--- a/flang/include/flang/Evaluate/tools.h
+++ b/flang/include/flang/Evaluate/tools.h
@@ -1109,6 +1109,33 @@ std::optional<Expr<SomeType>> DataConstantConversionExtension(
 std::optional<Expr<SomeType>> HollerithToBOZ(
     FoldingContext &, const Expr<SomeType> &, const DynamicType &);
 
+// Set explicit lower bounds on a constant array.
+class ArrayConstantBoundChanger {
+public:
+  explicit ArrayConstantBoundChanger(ConstantSubscripts &&lbounds)
+      : lbounds_{std::move(lbounds)} {}
+
+  template <typename A> A ChangeLbounds(A &&x) const {
+    return std::move(x); // default case
+  }
+  template <typename T> Constant<T> ChangeLbounds(Constant<T> &&x) {
+    x.set_lbounds(std::move(lbounds_));
+    return std::move(x);
+  }
+  template <typename T> Expr<T> ChangeLbounds(Parentheses<T> &&x) {
+    return ChangeLbounds(
+        std::move(x.left())); // Constant<> can be parenthesized
+  }
+  template <typename T> Expr<T> ChangeLbounds(Expr<T> &&x) {
+    return common::visit(
+        [&](auto &&x) { return Expr<T>{ChangeLbounds(std::move(x))}; },
+        std::move(x.u)); // recurse until we hit a constant
+  }
+
+private:
+  ConstantSubscripts &&lbounds_;
+};
+
 } // namespace Fortran::evaluate
 
 namespace Fortran::semantics {

diff  --git a/flang/lib/Evaluate/check-expression.cpp b/flang/lib/Evaluate/check-expression.cpp
index 4d5fd0ba9fab..34ade7157144 100644
--- a/flang/lib/Evaluate/check-expression.cpp
+++ b/flang/lib/Evaluate/check-expression.cpp
@@ -9,6 +9,7 @@
 #include "flang/Evaluate/check-expression.h"
 #include "flang/Evaluate/characteristics.h"
 #include "flang/Evaluate/intrinsics.h"
+#include "flang/Evaluate/tools.h"
 #include "flang/Evaluate/traverse.h"
 #include "flang/Evaluate/type.h"
 #include "flang/Semantics/symbol.h"
@@ -363,32 +364,6 @@ bool IsInitialProcedureTarget(const Expr<SomeType> &expr) {
   }
 }
 
-class ArrayConstantBoundChanger {
-public:
-  ArrayConstantBoundChanger(ConstantSubscripts &&lbounds)
-      : lbounds_{std::move(lbounds)} {}
-
-  template <typename A> A ChangeLbounds(A &&x) const {
-    return std::move(x); // default case
-  }
-  template <typename T> Constant<T> ChangeLbounds(Constant<T> &&x) {
-    x.set_lbounds(std::move(lbounds_));
-    return std::move(x);
-  }
-  template <typename T> Expr<T> ChangeLbounds(Parentheses<T> &&x) {
-    return ChangeLbounds(
-        std::move(x.left())); // Constant<> can be parenthesized
-  }
-  template <typename T> Expr<T> ChangeLbounds(Expr<T> &&x) {
-    return common::visit(
-        [&](auto &&x) { return Expr<T>{ChangeLbounds(std::move(x))}; },
-        std::move(x.u)); // recurse until we hit a constant
-  }
-
-private:
-  ConstantSubscripts &&lbounds_;
-};
-
 // Converts, folds, and then checks type, rank, and shape of an
 // initialization expression for a named constant, a non-pointer
 // variable static initialization, a component default initializer,

diff  --git a/flang/lib/Evaluate/fold.cpp b/flang/lib/Evaluate/fold.cpp
index 2f4ba2ae5ee1..3073aec2c6c7 100644
--- a/flang/lib/Evaluate/fold.cpp
+++ b/flang/lib/Evaluate/fold.cpp
@@ -10,6 +10,7 @@
 #include "fold-implementation.h"
 #include "flang/Evaluate/characteristics.h"
 #include "flang/Evaluate/initial-image.h"
+#include "flang/Evaluate/tools.h"
 
 namespace Fortran::evaluate {
 
@@ -92,6 +93,14 @@ Expr<SomeDerived> FoldOperation(
           } else {
             isConstant &= *valueShape == *componentShape;
           }
+          if (*valueShape == *componentShape) {
+            if (auto lbounds{AsConstantExtents(
+                    context, GetLBOUNDs(context, NamedEntity{symbol}))}) {
+              expr =
+                  ArrayConstantBoundChanger{std::move(*lbounds)}.ChangeLbounds(
+                      std::move(expr));
+            }
+          }
         }
       }
     }


        


More information about the flang-commits mailing list