Change the flang reshape runtime routine interface to use a result
authorMark Leair <leairmark@gmail.com>
Thu, 24 Jun 2021 23:55:45 +0000 (16:55 -0700)
committerMark Leair <leairmark@gmail.com>
Fri, 25 Jun 2021 00:05:12 +0000 (17:05 -0700)
argument instead of a result result object.

Change the reshape flang unit test to use the new interface. Also, add an
order argument to exercise the order subscript code in the rehsape runtime
routine.

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

flang/runtime/transformational.cpp
flang/runtime/transformational.h
flang/unittests/Evaluate/reshape.cpp

index bf3618b..a6e4400 100644 (file)
@@ -350,9 +350,9 @@ void RTNAME(Pack)(Descriptor &result, const Descriptor &source,
   }
 }
 
-} // extern "C" - TODO put Reshape under extern "C"
+// RESHAPE
 // F2018 16.9.163
-OwningPtr<Descriptor> RTNAME(Reshape)(const Descriptor &source,
+void RTNAME(Reshape)(Descriptor &result, const Descriptor &source,
     const Descriptor &shape, const Descriptor *pad, const Descriptor *order,
     const char *sourceFile, int line) {
   // Compute and check the rank of the result.
@@ -394,9 +394,10 @@ OwningPtr<Descriptor> RTNAME(Reshape)(const Descriptor &source,
     RUNTIME_CHECK(terminator, order->GetDimension(0).Extent() == resultRank);
     std::uint64_t values{0};
     SubscriptValue orderSubscript{order->GetDimension(0).LowerBound()};
+    std::size_t orderElementBytes{order->ElementBytes()};
     for (SubscriptValue j{0}; j < resultRank; ++j, ++orderSubscript) {
-      auto k{GetInt64(order->OffsetElement<char>(orderSubscript),
-          shapeElementBytes, terminator)};
+      auto k{GetInt64(order->Element<char>(&orderSubscript), orderElementBytes,
+          terminator)};
       RUNTIME_CHECK(
           terminator, k >= 1 && k <= resultRank && !((values >> k) & 1));
       values |= std::uint64_t{1} << k;
@@ -408,64 +409,33 @@ OwningPtr<Descriptor> RTNAME(Reshape)(const Descriptor &source,
     }
   }
 
-  // Create and populate the result's descriptor.
-  const DescriptorAddendum *sourceAddendum{source.Addendum()};
-  const typeInfo::DerivedType *sourceDerivedType{
-      sourceAddendum ? sourceAddendum->derivedType() : nullptr};
-  OwningPtr<Descriptor> result;
-  if (sourceDerivedType) {
-    result = Descriptor::Create(*sourceDerivedType, nullptr, resultRank,
-        resultExtent, CFI_attribute_allocatable);
-  } else {
-    result = Descriptor::Create(source.type(), elementBytes, nullptr,
-        resultRank, resultExtent,
-        CFI_attribute_allocatable); // TODO rearrange these arguments
-  }
-  DescriptorAddendum *resultAddendum{result->Addendum()};
-  RUNTIME_CHECK(terminator, resultAddendum);
-  resultAddendum->flags() |= DescriptorAddendum::DoNotFinalize;
-  if (sourceDerivedType) {
-    std::size_t lenParameters{sourceAddendum->LenParameters()};
-    for (std::size_t j{0}; j < lenParameters; ++j) {
-      resultAddendum->SetLenParameterValue(
-          j, sourceAddendum->LenParameterValue(j));
-    }
-  }
-  // Allocate storage for the result's data.
-  for (int j{0}; j < resultRank; ++j) {
-    result->GetDimension(j).SetBounds(1, resultExtent[j]);
-  }
-  int status{result->Allocate()};
-  if (status != CFI_SUCCESS) {
-    terminator.Crash("RESHAPE: Allocate failed (error %d)", status);
-  }
+  // Allocate result descriptor
+  AllocateResult(
+      result, source, resultRank, resultExtent, terminator, "RESHAPE");
 
   // Populate the result's elements.
   SubscriptValue resultSubscript[maxRank];
-  result->GetLowerBounds(resultSubscript);
+  result.GetLowerBounds(resultSubscript);
   SubscriptValue sourceSubscript[maxRank];
   source.GetLowerBounds(sourceSubscript);
   std::size_t resultElement{0};
   std::size_t elementsFromSource{std::min(resultElements, sourceElements)};
   for (; resultElement < elementsFromSource; ++resultElement) {
-    CopyElement(*result, resultSubscript, source, sourceSubscript, terminator);
+    CopyElement(result, resultSubscript, source, sourceSubscript, terminator);
     source.IncrementSubscripts(sourceSubscript);
-    result->IncrementSubscripts(resultSubscript, dimOrder);
+    result.IncrementSubscripts(resultSubscript, dimOrder);
   }
   if (resultElement < resultElements) {
     // Remaining elements come from the optional PAD= argument.
     SubscriptValue padSubscript[maxRank];
     pad->GetLowerBounds(padSubscript);
     for (; resultElement < resultElements; ++resultElement) {
-      CopyElement(*result, resultSubscript, *pad, padSubscript, terminator);
+      CopyElement(result, resultSubscript, *pad, padSubscript, terminator);
       pad->IncrementSubscripts(padSubscript);
-      result->IncrementSubscripts(resultSubscript, dimOrder);
+      result.IncrementSubscripts(resultSubscript, dimOrder);
     }
   }
-
-  return result;
 }
-extern "C" { // TODO - remove when Reshape is under extern "C"
 
 // SPREAD
 void RTNAME(Spread)(Descriptor &result, const Descriptor &source, int dim,
index 97d5664..08f2d9a 100644 (file)
 
 namespace Fortran::runtime {
 
-// TODO: redo API, put under extern "C"
-OwningPtr<Descriptor> RTNAME(Reshape)(const Descriptor &source,
+extern "C" {
+
+void RTNAME(Reshape)(Descriptor &result, const Descriptor &source,
     const Descriptor &shape, const Descriptor *pad = nullptr,
     const Descriptor *order = nullptr, const char *sourceFile = nullptr,
     int line = 0);
 
-extern "C" {
-
 void RTNAME(Cshift)(Descriptor &result, const Descriptor &source,
     const Descriptor &shift, int dim = 1, const char *sourceFile = nullptr,
     int line = 0);
index 719d220..b4c1eff 100644 (file)
@@ -53,10 +53,22 @@ int main() {
   MATCH(2, pad.GetDimension(0).Extent());
   MATCH(2, pad.GetDimension(1).Extent());
   MATCH(3, pad.GetDimension(2).Extent());
+  StaticDescriptor<1> orderDescriptor;
+  Descriptor &order{orderDescriptor.descriptor()};
+  static const std::int32_t orderData[]{1, 2};
+  static const SubscriptValue orderExtent[]{2};
+  order.Establish(TypeCategory::Integer, static_cast<int>(sizeof orderData[0]),
+      const_cast<void *>(reinterpret_cast<const void *>(orderData)), 1,
+      orderExtent, CFI_attribute_pointer);
+  orderDescriptor.Check();
+  order.Check();
+  MATCH(1, order.rank());
+  MATCH(2, order.GetDimension(0).Extent());
 
-  auto result{
-      RTNAME(Reshape)(*source, *shape, &pad, nullptr, __FILE__, __LINE__)};
+  auto result{Descriptor::Create(TypeCategory::Integer, sizeof(std::int32_t),
+      nullptr, 2, nullptr, CFI_attribute_allocatable)};
   TEST(result.get() != nullptr);
+  RTNAME(Reshape)(*result, *source, *shape, &pad, &order, __FILE__, __LINE__);
   result->Check();
   MATCH(sizeof(std::int32_t), result->ElementBytes());
   MATCH(2, result->rank());
@@ -69,7 +81,5 @@ int main() {
     MATCH(j, *result->Element<std::int32_t>(ss));
   }
 
-  // TODO: test ORDER=
-
   return testing::Complete();
 }