[PATCH] D95897: [flang] Add TypeAndShape::MeasureElementSizeInBytes()

Peter Klausler via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 2 14:41:29 PST 2021


klausler created this revision.
klausler added a reviewer: PeteSteinfeld.
klausler added a project: Flang.
Herald added a subscriber: jdoerfert.
klausler requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Split up MeasureSizeInBytes() so that array element sizes can be
calculated accurately; use the new API in some places where
DynamicType::MeasureSizeInBytes() was being used but the new
API performs better due to TypeAndShape having precise CHARACTER
length information.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D95897

Files:
  flang/include/flang/Evaluate/characteristics.h
  flang/lib/Evaluate/characteristics.cpp
  flang/lib/Evaluate/fold-integer.cpp
  flang/lib/Evaluate/shape.cpp
  flang/lib/Semantics/compute-offsets.cpp


Index: flang/lib/Semantics/compute-offsets.cpp
===================================================================
--- flang/lib/Semantics/compute-offsets.cpp
+++ flang/lib/Semantics/compute-offsets.cpp
@@ -323,7 +323,7 @@
             chars->type().GetAlignment(foldingContext)};
       }
     } else { // element size only
-      if (auto size{ToInt64(chars->type().MeasureSizeInBytes(
+      if (auto size{ToInt64(chars->MeasureElementSizeInBytes(
               foldingContext, true /*aligned*/))}) {
         return {static_cast<std::size_t>(*size),
             chars->type().GetAlignment(foldingContext)};
Index: flang/lib/Evaluate/shape.cpp
===================================================================
--- flang/lib/Evaluate/shape.cpp
+++ flang/lib/Evaluate/shape.cpp
@@ -724,7 +724,7 @@
               auto sourceBytes{
                   sourceTypeAndShape->MeasureSizeInBytes(*context_)};
               auto moldElementBytes{
-                  moldTypeAndShape->type().MeasureSizeInBytes(*context_, true)};
+                  moldTypeAndShape->MeasureElementSizeInBytes(*context_, true)};
               if (sourceBytes && moldElementBytes) {
                 ExtentExpr extent{Fold(*context_,
                     (std::move(*sourceBytes) +
Index: flang/lib/Evaluate/fold-integer.cpp
===================================================================
--- flang/lib/Evaluate/fold-integer.cpp
+++ flang/lib/Evaluate/fold-integer.cpp
@@ -598,12 +598,11 @@
       }
     }
   } else if (name == "storage_size") { // in bits
-    if (const auto *expr{UnwrapExpr<Expr<SomeType>>(args[0])}) {
-      if (auto type{expr->GetType()}) {
-        if (auto bytes{type->MeasureSizeInBytes(context, true)}) {
-          return Expr<T>{
-              Fold(context, Expr<T>{8} * ConvertToType<T>(std::move(*bytes)))};
-        }
+    if (auto info{
+            characteristics::TypeAndShape::Characterize(args[0], context)}) {
+      if (auto bytes{info->MeasureElementSizeInBytes(context, true)}) {
+        return Expr<T>{
+            Fold(context, Expr<T>{8} * ConvertToType<T>(std::move(*bytes)))};
       }
     }
   } else if (name == "ubound") {
Index: flang/lib/Evaluate/characteristics.cpp
===================================================================
--- flang/lib/Evaluate/characteristics.cpp
+++ flang/lib/Evaluate/characteristics.cpp
@@ -168,19 +168,26 @@
           thatIsDeferredShape);
 }
 
+std::optional<Expr<SubscriptInteger>> TypeAndShape::MeasureElementSizeInBytes(
+    FoldingContext &foldingContext, bool align) const {
+  if (LEN_) {
+    CHECK(type_.category() == TypeCategory::Character);
+    return Fold(foldingContext,
+        Expr<SubscriptInteger>{type_.kind()} * Expr<SubscriptInteger>{*LEN_});
+  }
+  if (auto elementBytes{type_.MeasureSizeInBytes(foldingContext, align)}) {
+    return Fold(foldingContext, std::move(*elementBytes));
+  }
+  return std::nullopt;
+}
+
 std::optional<Expr<SubscriptInteger>> TypeAndShape::MeasureSizeInBytes(
     FoldingContext &foldingContext) const {
   if (auto elements{GetSize(Shape{shape_})}) {
     // Sizes of arrays (even with single elements) are multiples of
     // their alignments.
-    if (LEN_) {
-      CHECK(type_.category() == TypeCategory::Character);
-      return Fold(foldingContext,
-          std::move(*elements) * Expr<SubscriptInteger>{type_.kind()} *
-              Expr<SubscriptInteger>{*LEN_});
-    }
     if (auto elementBytes{
-            type_.MeasureSizeInBytes(foldingContext, GetRank(shape_) > 0)}) {
+            MeasureElementSizeInBytes(foldingContext, GetRank(shape_) > 0)}) {
       return Fold(
           foldingContext, std::move(*elements) * std::move(*elementBytes));
     }
Index: flang/include/flang/Evaluate/characteristics.h
===================================================================
--- flang/include/flang/Evaluate/characteristics.h
+++ flang/include/flang/Evaluate/characteristics.h
@@ -146,6 +146,8 @@
       const char *thisIs = "pointer", const char *thatIs = "target",
       bool isElemental = false, bool thisIsDeferredShape = false,
       bool thatIsDeferredShape = false) const;
+  std::optional<Expr<SubscriptInteger>> MeasureElementSizeInBytes(
+      FoldingContext &, bool align) const;
   std::optional<Expr<SubscriptInteger>> MeasureSizeInBytes(
       FoldingContext &) const;
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D95897.320912.patch
Type: text/x-patch
Size: 4346 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210202/075e8a83/attachment.bin>


More information about the llvm-commits mailing list