[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