[flang-commits] [flang] [flang][debug] Support TupleType. (PR #113917)

via flang-commits flang-commits at lists.llvm.org
Mon Oct 28 07:43:20 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

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

Author: Abid Qadeer (abidh)

<details>
<summary>Changes</summary>

Handling is similar to RecordType.

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


3 Files Affected:

- (modified) flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp (+52-9) 
- (modified) flang/lib/Optimizer/Transforms/DebugTypeGenerator.h (+6) 
- (added) flang/test/Transforms/debug-tuple-type.fir (+15) 


``````````diff
diff --git a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
index e387e27533a006..0337bfa573fb3c 100644
--- a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
+++ b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
@@ -271,6 +271,19 @@ static bool canCacheThisType(mlir::LLVM::DICompositeTypeAttr comTy) {
   return true;
 }
 
+std::pair<std::uint64_t, unsigned short>
+DebugTypeGenerator::getFieldSizeAndAlign(mlir::Type fieldTy) {
+  mlir::Type llvmTy;
+  if (auto boxTy = mlir::dyn_cast_or_null<fir::BaseBoxType>(fieldTy))
+    llvmTy = llvmTypeConverter.convertBoxTypeAsStruct(boxTy, getBoxRank(boxTy));
+  else
+    llvmTy = llvmTypeConverter.convertType(fieldTy);
+
+  uint64_t byteSize = dataLayout->getTypeSize(llvmTy);
+  unsigned short byteAlign = dataLayout->getTypeABIAlignment(llvmTy);
+  return std::pair{byteSize, byteAlign};
+}
+
 mlir::LLVM::DITypeAttr DebugTypeGenerator::convertRecordType(
     fir::RecordType Ty, mlir::LLVM::DIFileAttr fileAttr,
     mlir::LLVM::DIScopeAttr scope, fir::cg::XDeclareOp declOp) {
@@ -303,15 +316,7 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertRecordType(
   mlir::IntegerType intTy = mlir::IntegerType::get(context, 64);
   std::uint64_t offset = 0;
   for (auto [fieldName, fieldTy] : Ty.getTypeList()) {
-    mlir::Type llvmTy;
-    if (auto boxTy = mlir::dyn_cast_or_null<fir::BaseBoxType>(fieldTy))
-      llvmTy =
-          llvmTypeConverter.convertBoxTypeAsStruct(boxTy, getBoxRank(boxTy));
-    else
-      llvmTy = llvmTypeConverter.convertType(fieldTy);
-
-    uint64_t byteSize = dataLayout->getTypeSize(llvmTy);
-    unsigned short byteAlign = dataLayout->getTypeABIAlignment(llvmTy);
+    auto [byteSize, byteAlign] = getFieldSizeAndAlign(fieldTy);
     std::optional<llvm::ArrayRef<int64_t>> lowerBounds =
         fir::getComponentLowerBoundsIfNonDefault(Ty, fieldName, module,
                                                  symbolTable);
@@ -368,6 +373,42 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertRecordType(
   return finalAttr;
 }
 
+mlir::LLVM::DITypeAttr DebugTypeGenerator::convertTupleType(
+    mlir::TupleType Ty, mlir::LLVM::DIFileAttr fileAttr,
+    mlir::LLVM::DIScopeAttr scope, fir::cg::XDeclareOp declOp) {
+  // Check if this type has already been converted.
+  auto iter = typeCache.find(Ty);
+  if (iter != typeCache.end())
+    return iter->second;
+
+  llvm::SmallVector<mlir::LLVM::DINodeAttr> elements;
+  mlir::MLIRContext *context = module.getContext();
+
+  std::uint64_t offset = 0;
+  for (auto fieldTy : Ty.getTypes()) {
+    auto [byteSize, byteAlign] = getFieldSizeAndAlign(fieldTy);
+    mlir::LLVM::DITypeAttr elemTy =
+        convertType(fieldTy, fileAttr, scope, /*declOp=*/nullptr);
+    offset = llvm::alignTo(offset, byteAlign);
+    mlir::LLVM::DIDerivedTypeAttr tyAttr = mlir::LLVM::DIDerivedTypeAttr::get(
+        context, llvm::dwarf::DW_TAG_member, mlir::StringAttr::get(context, ""),
+        elemTy, byteSize * 8, byteAlign * 8, offset * 8,
+        /*optional<address space>=*/std::nullopt,
+        /*extra data=*/nullptr);
+    elements.push_back(tyAttr);
+    offset += llvm::alignTo(byteSize, byteAlign);
+  }
+
+  auto typeAttr = mlir::LLVM::DICompositeTypeAttr::get(
+      context, llvm::dwarf::DW_TAG_structure_type,
+      mlir::StringAttr::get(context, ""), fileAttr, /*line=*/0, scope,
+      /*baseType=*/nullptr, mlir::LLVM::DIFlags::Zero, offset * 8,
+      /*alignInBits=*/0, elements, /*dataLocation=*/nullptr, /*rank=*/nullptr,
+      /*allocated=*/nullptr, /*associated=*/nullptr);
+  typeCache[Ty] = typeAttr;
+  return typeAttr;
+}
+
 mlir::LLVM::DITypeAttr DebugTypeGenerator::convertSequenceType(
     fir::SequenceType seqTy, mlir::LLVM::DIFileAttr fileAttr,
     mlir::LLVM::DIScopeAttr scope, fir::cg::XDeclareOp declOp) {
@@ -574,6 +615,8 @@ DebugTypeGenerator::convertType(mlir::Type Ty, mlir::LLVM::DIFileAttr fileAttr,
                                 /*hasDescriptor=*/false);
   } else if (auto recTy = mlir::dyn_cast_or_null<fir::RecordType>(Ty)) {
     return convertRecordType(recTy, fileAttr, scope, declOp);
+  } else if (auto tupleTy = mlir::dyn_cast_if_present<mlir::TupleType>(Ty)) {
+    return convertTupleType(tupleTy, fileAttr, scope, declOp);
   } else if (auto refTy = mlir::dyn_cast_if_present<fir::ReferenceType>(Ty)) {
     auto elTy = refTy.getEleTy();
     return convertPointerLikeType(elTy, fileAttr, scope, declOp,
diff --git a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h
index eeefb6c463d936..c1fce4bdae5ce5 100644
--- a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h
+++ b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h
@@ -39,6 +39,10 @@ class DebugTypeGenerator {
                                            mlir::LLVM::DIFileAttr fileAttr,
                                            mlir::LLVM::DIScopeAttr scope,
                                            fir::cg::XDeclareOp declOp);
+  mlir::LLVM::DITypeAttr convertTupleType(mlir::TupleType Ty,
+                                          mlir::LLVM::DIFileAttr fileAttr,
+                                          mlir::LLVM::DIScopeAttr scope,
+                                          fir::cg::XDeclareOp declOp);
   mlir::LLVM::DITypeAttr convertSequenceType(fir::SequenceType seqTy,
                                              mlir::LLVM::DIFileAttr fileAttr,
                                              mlir::LLVM::DIScopeAttr scope,
@@ -73,6 +77,8 @@ class DebugTypeGenerator {
                              mlir::LLVM::DIFileAttr fileAttr,
                              mlir::LLVM::DIScopeAttr scope,
                              fir::cg::XDeclareOp declOp);
+  std::pair<std::uint64_t, unsigned short>
+  getFieldSizeAndAlign(mlir::Type fieldTy);
 
   mlir::ModuleOp module;
   mlir::SymbolTable *symbolTable;
diff --git a/flang/test/Transforms/debug-tuple-type.fir b/flang/test/Transforms/debug-tuple-type.fir
new file mode 100644
index 00000000000000..c9b0d16c06e1ae
--- /dev/null
+++ b/flang/test/Transforms/debug-tuple-type.fir
@@ -0,0 +1,15 @@
+// RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s | FileCheck %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
+  func.func private @fn1(!fir.ref<tuple<f64, f64>>)
+  func.func private @_FortranAioOutputDerivedType(!fir.ref<tuple<>>)
+}
+
+// CHECK: #[[F64:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "real", sizeInBits = 64, encoding = DW_ATE_float>
+// CHECK: #[[CU:.*]] = #llvm.di_compile_unit<{{.*}}>
+// CHECK: #[[DTY1:.*]] = #llvm.di_derived_type<tag = DW_TAG_member, name = "", baseType = #[[F64]], sizeInBits = 64, alignInBits = {{.*}}>
+// CHECK: #[[DTY2:.*]] = #llvm.di_derived_type<tag = DW_TAG_member, name = "", baseType = #[[F64]], sizeInBits = 64, alignInBits = {{.*}}, offsetInBits = {{.*}}>
+// CHECK: #[[COM_TY1:.*]] = #llvm.di_composite_type<tag = DW_TAG_structure_type, name = "", file = #{{.*}}, scope = #[[CU]]{{.*}}elements = #[[DTY1]], #[[DTY2]]>
+// CHECK: #[[COM_TY2:.*]] = #llvm.di_composite_type<tag = DW_TAG_structure_type, name = "", file = #{{.*}}, scope = #[[CU]]>
+// CHECK: #llvm.di_subroutine_type<callingConvention = DW_CC_normal, types = #di_null_type, #[[COM_TY1]]>
+// CHECK: #llvm.di_subroutine_type<callingConvention = DW_CC_normal, types = #di_null_type, #[[COM_TY2]]>

``````````

</details>


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


More information about the flang-commits mailing list