[flang-commits] [flang] [llvm] [flang-rt] Add APIs to retrive base_addr and DataSizeInBytes from Descriptor. (PR #152756)

via flang-commits flang-commits at lists.llvm.org
Mon Aug 18 06:36:03 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-fir-hlfir

Author: Chaitanya (skc7)

<details>
<summary>Changes</summary>

This PR adds below APIs to flang-rt:
DescriptorGetBaseAddress to retrive base_addr from Descriptor
DescriptorGetDataSizeInBytes to retrive the total Size in bytes of data from Descriptor.

---
Full diff: https://github.com/llvm/llvm-project/pull/152756.diff


5 Files Affected:

- (modified) flang-rt/lib/runtime/support.cpp (+24) 
- (modified) flang-rt/unittests/Runtime/Support.cpp (+23) 
- (modified) flang/include/flang/Optimizer/Builder/Runtime/Support.h (+13) 
- (modified) flang/include/flang/Runtime/support.h (+8) 
- (modified) flang/lib/Optimizer/Builder/Runtime/Support.cpp (+21) 


``````````diff
diff --git a/flang-rt/lib/runtime/support.cpp b/flang-rt/lib/runtime/support.cpp
index 9beb46e48a11e..ffeaafaa162ea 100644
--- a/flang-rt/lib/runtime/support.cpp
+++ b/flang-rt/lib/runtime/support.cpp
@@ -48,6 +48,30 @@ void RTDEF(CopyAndUpdateDescriptor)(Descriptor &to, const Descriptor &from,
   }
 }
 
+void *RTDEF(DescriptorGetBaseAddress)(
+    const Descriptor &desc, const char *sourceFile, int sourceLine) {
+  Terminator terminator{sourceFile, sourceLine};
+  void *baseAddr = desc.raw().base_addr;
+  if (!baseAddr) {
+    terminator.Crash("Could not retrieve Descriptor's base address");
+  }
+  return baseAddr;
+}
+
+std::size_t RTDEF(DescriptorGetDataSizeInBytes)(
+    const Descriptor &desc, const char *sourceFile, int sourceLine) {
+  Terminator terminator{sourceFile, sourceLine};
+  std::size_t descElements{desc.Elements()};
+  if (!descElements) {
+    terminator.Crash("Could not retrieve Descriptor's Elements");
+  }
+  std::size_t descElementBytes{desc.ElementBytes()};
+  if (!descElementBytes) {
+    terminator.Crash("Could not retrieve Descriptor's ElementBytes");
+  }
+  return descElements * descElementBytes;
+}
+
 RT_EXT_API_GROUP_END
 } // extern "C"
 } // namespace Fortran::runtime
diff --git a/flang-rt/unittests/Runtime/Support.cpp b/flang-rt/unittests/Runtime/Support.cpp
index 46c6805d5d238..264dde872c242 100644
--- a/flang-rt/unittests/Runtime/Support.cpp
+++ b/flang-rt/unittests/Runtime/Support.cpp
@@ -98,3 +98,26 @@ TEST(IsContiguous, Basic) {
   EXPECT_TRUE(RTNAME(IsContiguousUpTo)(section, 1));
   EXPECT_FALSE(RTNAME(IsContiguousUpTo)(section, 2));
 }
+
+TEST(DescriptorGetBaseAddress, Basic) {
+  auto array{MakeArray<TypeCategory::Integer, 4>(
+      std::vector<int>{2, 3}, std::vector<std::int32_t>{0, 1, 2, 3, 4, 5})};
+  void *baseAddr = RTNAME(DescriptorGetBaseAddress)(*array);
+  EXPECT_NE(baseAddr, nullptr);
+  EXPECT_EQ(baseAddr, array->raw().base_addr);
+}
+
+TEST(DescriptorGetDataSizeInBytes, Basic) {
+  // Test with a 2x3 integer*4 array
+  auto int4Array{MakeArray<TypeCategory::Integer, 4>({2, 3})};
+  EXPECT_EQ(RTNAME(DescriptorGetDataSizeInBytes)(*int4Array),
+      6 * sizeof(std::int32_t));
+  // Test with a 1D, 5-element real*8 array
+  auto real8Array{MakeArray<TypeCategory::Real, 8>({5})};
+  EXPECT_EQ(
+      RTNAME(DescriptorGetDataSizeInBytes)(*real8Array), 5 * sizeof(double));
+  // Test with a scalar logical*1
+  auto logical1Scalar{MakeArray<TypeCategory::Logical, 1>({})};
+  EXPECT_EQ(
+      RTNAME(DescriptorGetDataSizeInBytes)(*logical1Scalar), 1 * sizeof(bool));
+}
diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Support.h b/flang/include/flang/Optimizer/Builder/Runtime/Support.h
index d0a474d75d2eb..41db61c19b07e 100644
--- a/flang/include/flang/Optimizer/Builder/Runtime/Support.h
+++ b/flang/include/flang/Optimizer/Builder/Runtime/Support.h
@@ -31,5 +31,18 @@ void genCopyAndUpdateDescriptor(fir::FirOpBuilder &builder, mlir::Location loc,
 mlir::Value genIsAssumedSize(fir::FirOpBuilder &builder, mlir::Location loc,
                              mlir::Value box);
 
+/// Generate call to `DescriptorGetBaseAddress` runtime routine.
+mlir::Value genDescriptorGetBaseAddress(fir::FirOpBuilder &builder,
+                                        mlir::Location loc, mlir::Value desc,
+                                        mlir::Value sourceFile,
+                                        mlir::Value sourceLine);
+
+/// Generate call to `DescriptorGetDataSizeInBytes` runtime routine.
+mlir::Value genDescriptorGetDataSizeInBytes(fir::FirOpBuilder &builder,
+                                            mlir::Location loc,
+                                            mlir::Value desc,
+                                            mlir::Value sourceFile,
+                                            mlir::Value sourceLine);
+
 } // namespace fir::runtime
 #endif // FORTRAN_OPTIMIZER_BUILDER_RUNTIME_SUPPORT_H
diff --git a/flang/include/flang/Runtime/support.h b/flang/include/flang/Runtime/support.h
index 8a345bee7f867..5ebe6c6406a01 100644
--- a/flang/include/flang/Runtime/support.h
+++ b/flang/include/flang/Runtime/support.h
@@ -49,6 +49,14 @@ void RTDECL(CopyAndUpdateDescriptor)(Descriptor &to, const Descriptor &from,
     const typeInfo::DerivedType *newDynamicType,
     ISO::CFI_attribute_t newAttribute, enum LowerBoundModifier newLowerBounds);
 
+// Retrieve the base_addr from Descriptor
+void *RTDECL(DescriptorGetBaseAddress)(const Descriptor &desc,
+    const char *sourceFile = nullptr, int sourceLine = 0);
+
+// Retrieve the totalSizeInBytes of data from Descriptor
+std::size_t RTDECL(DescriptorGetDataSizeInBytes)(const Descriptor &desc,
+    const char *sourceFile = nullptr, int sourceLine = 0);
+
 } // extern "C"
 } // namespace Fortran::runtime
 #endif // FORTRAN_RUNTIME_SUPPORT_H_
diff --git a/flang/lib/Optimizer/Builder/Runtime/Support.cpp b/flang/lib/Optimizer/Builder/Runtime/Support.cpp
index d0d48ad718da4..12994b596df4b 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Support.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Support.cpp
@@ -54,3 +54,24 @@ mlir::Value fir::runtime::genIsAssumedSize(fir::FirOpBuilder &builder,
   auto args = fir::runtime::createArguments(builder, loc, fTy, box);
   return fir::CallOp::create(builder, loc, func, args).getResult(0);
 }
+
+mlir::Value fir::runtime::genDescriptorGetBaseAddress(
+    fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value desc,
+    mlir::Value sourceFile, mlir::Value sourceLine) {
+  mlir::func::FuncOp baseAddrFunc =
+      fir::runtime::getRuntimeFunc<mkRTKey(DescriptorGetBaseAddress)>(loc,
+                                                                      builder);
+  llvm::SmallVector<mlir::Value> args{desc, sourceFile, sourceLine};
+  return fir::CallOp::create(builder, loc, baseAddrFunc, args).getResult(0);
+}
+
+mlir::Value fir::runtime::genDescriptorGetDataSizeInBytes(
+    fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value desc,
+    mlir::Value sourceFile, mlir::Value sourceLine) {
+  mlir::func::FuncOp getDataSizeInBytesFunc =
+      fir::runtime::getRuntimeFunc<mkRTKey(DescriptorGetDataSizeInBytes)>(
+          loc, builder);
+  llvm::SmallVector<mlir::Value> args{desc, sourceFile, sourceLine};
+  return fir::CallOp::create(builder, loc, getDataSizeInBytesFunc, args)
+      .getResult(0);
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/152756


More information about the flang-commits mailing list