[flang-commits] [flang] cbd445e - [flang] Re-fold bounds expressions in DATA implied DO loops

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Tue Nov 30 13:28:38 PST 2021


Author: Peter Klausler
Date: 2021-11-30T13:28:31-08:00
New Revision: cbd445e4a331114752093746e9d596dafb8580b8

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

LOG: [flang] Re-fold bounds expressions in DATA implied DO loops

To accommodate triangular implied DO loops in DATA statements, in which
the bounds of nested implied DO loops might depend on the values of the
indices of outer implied DO loops in the same DATA statement set, it
is necessary to run them through constant folding each time they are
encountered.

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

Added: 
    

Modified: 
    flang/lib/Semantics/data-to-inits.cpp

Removed: 
    


################################################################################
diff  --git a/flang/lib/Semantics/data-to-inits.cpp b/flang/lib/Semantics/data-to-inits.cpp
index 958184ca2b6a..4f540f3f9644 100644
--- a/flang/lib/Semantics/data-to-inits.cpp
+++ b/flang/lib/Semantics/data-to-inits.cpp
@@ -155,14 +155,24 @@ bool DataInitializationCompiler::Scan(const parser::DataImpliedDo &ido) {
   const auto *stepExpr{
       bounds.step ? GetExpr(bounds.step->thing.thing) : nullptr};
   if (lowerExpr && upperExpr) {
-    auto lower{ToInt64(*lowerExpr)};
-    auto upper{ToInt64(*upperExpr)};
-    auto step{stepExpr ? ToInt64(*stepExpr) : std::nullopt};
-    auto stepVal{step.value_or(1)};
-    if (stepVal == 0) {
-      exprAnalyzer_.Say(name.source,
-          "DATA statement implied DO loop has a step value of zero"_err_en_US);
-    } else if (lower && upper) {
+    // Fold the bounds expressions (again) in case any of them depend
+    // on outer implied DO loops.
+    evaluate::FoldingContext &context{exprAnalyzer_.GetFoldingContext()};
+    std::int64_t stepVal{1};
+    if (stepExpr) {
+      auto foldedStep{evaluate::Fold(context, SomeExpr{*stepExpr})};
+      stepVal = ToInt64(foldedStep).value_or(1);
+      if (stepVal == 0) {
+        exprAnalyzer_.Say(name.source,
+            "DATA statement implied DO loop has a step value of zero"_err_en_US);
+        return false;
+      }
+    }
+    auto foldedLower{evaluate::Fold(context, SomeExpr{*lowerExpr})};
+    auto lower{ToInt64(foldedLower)};
+    auto foldedUpper{evaluate::Fold(context, SomeExpr{*upperExpr})};
+    auto upper{ToInt64(foldedUpper)};
+    if (lower && upper) {
       int kind{evaluate::ResultType<evaluate::ImpliedDoIndex>::kind};
       if (const auto dynamicType{evaluate::DynamicType::From(*name.symbol)}) {
         if (dynamicType->category() == TypeCategory::Integer) {
@@ -170,8 +180,7 @@ bool DataInitializationCompiler::Scan(const parser::DataImpliedDo &ido) {
         }
       }
       if (exprAnalyzer_.AddImpliedDo(name.source, kind)) {
-        auto &value{exprAnalyzer_.GetFoldingContext().StartImpliedDo(
-            name.source, *lower)};
+        auto &value{context.StartImpliedDo(name.source, *lower)};
         bool result{true};
         for (auto n{(*upper - value + stepVal) / stepVal}; n > 0;
              --n, value += stepVal) {
@@ -183,7 +192,7 @@ bool DataInitializationCompiler::Scan(const parser::DataImpliedDo &ido) {
             }
           }
         }
-        exprAnalyzer_.GetFoldingContext().EndImpliedDo(name.source);
+        context.EndImpliedDo(name.source);
         exprAnalyzer_.RemoveImpliedDo(name.source);
         return result;
       }


        


More information about the flang-commits mailing list