Skip to content

Commit 652988b

Browse files
authored
[flang][debug] Support TupleType. (#113917)
Handling is similar to RecordType with following differences: 1. No check for cyclic references 2. No extra processing for lower bounds of array members. 3. No line information as TupleType is a lowering artefact and does not really represent an entity in the code.
1 parent e8b95a0 commit 652988b

File tree

3 files changed

+73
-9
lines changed

3 files changed

+73
-9
lines changed

flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp

+52-9
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,19 @@ static bool canCacheThisType(mlir::LLVM::DICompositeTypeAttr comTy) {
271271
return true;
272272
}
273273

274+
std::pair<std::uint64_t, unsigned short>
275+
DebugTypeGenerator::getFieldSizeAndAlign(mlir::Type fieldTy) {
276+
mlir::Type llvmTy;
277+
if (auto boxTy = mlir::dyn_cast_or_null<fir::BaseBoxType>(fieldTy))
278+
llvmTy = llvmTypeConverter.convertBoxTypeAsStruct(boxTy, getBoxRank(boxTy));
279+
else
280+
llvmTy = llvmTypeConverter.convertType(fieldTy);
281+
282+
uint64_t byteSize = dataLayout->getTypeSize(llvmTy);
283+
unsigned short byteAlign = dataLayout->getTypeABIAlignment(llvmTy);
284+
return std::pair{byteSize, byteAlign};
285+
}
286+
274287
mlir::LLVM::DITypeAttr DebugTypeGenerator::convertRecordType(
275288
fir::RecordType Ty, mlir::LLVM::DIFileAttr fileAttr,
276289
mlir::LLVM::DIScopeAttr scope, fir::cg::XDeclareOp declOp) {
@@ -303,15 +316,7 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertRecordType(
303316
mlir::IntegerType intTy = mlir::IntegerType::get(context, 64);
304317
std::uint64_t offset = 0;
305318
for (auto [fieldName, fieldTy] : Ty.getTypeList()) {
306-
mlir::Type llvmTy;
307-
if (auto boxTy = mlir::dyn_cast_or_null<fir::BaseBoxType>(fieldTy))
308-
llvmTy =
309-
llvmTypeConverter.convertBoxTypeAsStruct(boxTy, getBoxRank(boxTy));
310-
else
311-
llvmTy = llvmTypeConverter.convertType(fieldTy);
312-
313-
uint64_t byteSize = dataLayout->getTypeSize(llvmTy);
314-
unsigned short byteAlign = dataLayout->getTypeABIAlignment(llvmTy);
319+
auto [byteSize, byteAlign] = getFieldSizeAndAlign(fieldTy);
315320
std::optional<llvm::ArrayRef<int64_t>> lowerBounds =
316321
fir::getComponentLowerBoundsIfNonDefault(Ty, fieldName, module,
317322
symbolTable);
@@ -368,6 +373,42 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertRecordType(
368373
return finalAttr;
369374
}
370375

376+
mlir::LLVM::DITypeAttr DebugTypeGenerator::convertTupleType(
377+
mlir::TupleType Ty, mlir::LLVM::DIFileAttr fileAttr,
378+
mlir::LLVM::DIScopeAttr scope, fir::cg::XDeclareOp declOp) {
379+
// Check if this type has already been converted.
380+
auto iter = typeCache.find(Ty);
381+
if (iter != typeCache.end())
382+
return iter->second;
383+
384+
llvm::SmallVector<mlir::LLVM::DINodeAttr> elements;
385+
mlir::MLIRContext *context = module.getContext();
386+
387+
std::uint64_t offset = 0;
388+
for (auto fieldTy : Ty.getTypes()) {
389+
auto [byteSize, byteAlign] = getFieldSizeAndAlign(fieldTy);
390+
mlir::LLVM::DITypeAttr elemTy =
391+
convertType(fieldTy, fileAttr, scope, /*declOp=*/nullptr);
392+
offset = llvm::alignTo(offset, byteAlign);
393+
mlir::LLVM::DIDerivedTypeAttr tyAttr = mlir::LLVM::DIDerivedTypeAttr::get(
394+
context, llvm::dwarf::DW_TAG_member, mlir::StringAttr::get(context, ""),
395+
elemTy, byteSize * 8, byteAlign * 8, offset * 8,
396+
/*optional<address space>=*/std::nullopt,
397+
/*extra data=*/nullptr);
398+
elements.push_back(tyAttr);
399+
offset += llvm::alignTo(byteSize, byteAlign);
400+
}
401+
402+
auto typeAttr = mlir::LLVM::DICompositeTypeAttr::get(
403+
context, llvm::dwarf::DW_TAG_structure_type,
404+
mlir::StringAttr::get(context, ""), fileAttr, /*line=*/0, scope,
405+
/*baseType=*/nullptr, mlir::LLVM::DIFlags::Zero, offset * 8,
406+
/*alignInBits=*/0, elements, /*dataLocation=*/nullptr, /*rank=*/nullptr,
407+
/*allocated=*/nullptr, /*associated=*/nullptr);
408+
typeCache[Ty] = typeAttr;
409+
return typeAttr;
410+
}
411+
371412
mlir::LLVM::DITypeAttr DebugTypeGenerator::convertSequenceType(
372413
fir::SequenceType seqTy, mlir::LLVM::DIFileAttr fileAttr,
373414
mlir::LLVM::DIScopeAttr scope, fir::cg::XDeclareOp declOp) {
@@ -574,6 +615,8 @@ DebugTypeGenerator::convertType(mlir::Type Ty, mlir::LLVM::DIFileAttr fileAttr,
574615
/*hasDescriptor=*/false);
575616
} else if (auto recTy = mlir::dyn_cast_or_null<fir::RecordType>(Ty)) {
576617
return convertRecordType(recTy, fileAttr, scope, declOp);
618+
} else if (auto tupleTy = mlir::dyn_cast_if_present<mlir::TupleType>(Ty)) {
619+
return convertTupleType(tupleTy, fileAttr, scope, declOp);
577620
} else if (auto refTy = mlir::dyn_cast_if_present<fir::ReferenceType>(Ty)) {
578621
auto elTy = refTy.getEleTy();
579622
return convertPointerLikeType(elTy, fileAttr, scope, declOp,

flang/lib/Optimizer/Transforms/DebugTypeGenerator.h

+6
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ class DebugTypeGenerator {
3939
mlir::LLVM::DIFileAttr fileAttr,
4040
mlir::LLVM::DIScopeAttr scope,
4141
fir::cg::XDeclareOp declOp);
42+
mlir::LLVM::DITypeAttr convertTupleType(mlir::TupleType Ty,
43+
mlir::LLVM::DIFileAttr fileAttr,
44+
mlir::LLVM::DIScopeAttr scope,
45+
fir::cg::XDeclareOp declOp);
4246
mlir::LLVM::DITypeAttr convertSequenceType(fir::SequenceType seqTy,
4347
mlir::LLVM::DIFileAttr fileAttr,
4448
mlir::LLVM::DIScopeAttr scope,
@@ -73,6 +77,8 @@ class DebugTypeGenerator {
7377
mlir::LLVM::DIFileAttr fileAttr,
7478
mlir::LLVM::DIScopeAttr scope,
7579
fir::cg::XDeclareOp declOp);
80+
std::pair<std::uint64_t, unsigned short>
81+
getFieldSizeAndAlign(mlir::Type fieldTy);
7682

7783
mlir::ModuleOp module;
7884
mlir::SymbolTable *symbolTable;
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s | FileCheck %s
2+
3+
module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
4+
func.func private @fn1(!fir.ref<tuple<f64, f64>>)
5+
func.func private @_FortranAioOutputDerivedType(!fir.ref<tuple<>>)
6+
}
7+
8+
// CHECK: #[[F64:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "real", sizeInBits = 64, encoding = DW_ATE_float>
9+
// CHECK: #[[CU:.*]] = #llvm.di_compile_unit<{{.*}}>
10+
// CHECK: #[[DTY1:.*]] = #llvm.di_derived_type<tag = DW_TAG_member, name = "", baseType = #[[F64]], sizeInBits = 64, alignInBits = {{.*}}>
11+
// CHECK: #[[DTY2:.*]] = #llvm.di_derived_type<tag = DW_TAG_member, name = "", baseType = #[[F64]], sizeInBits = 64, alignInBits = {{.*}}, offsetInBits = {{.*}}>
12+
// CHECK: #[[COM_TY1:.*]] = #llvm.di_composite_type<tag = DW_TAG_structure_type, name = "", file = #{{.*}}, scope = #[[CU]]{{.*}}elements = #[[DTY1]], #[[DTY2]]>
13+
// CHECK: #[[COM_TY2:.*]] = #llvm.di_composite_type<tag = DW_TAG_structure_type, name = "", file = #{{.*}}, scope = #[[CU]]>
14+
// CHECK: #llvm.di_subroutine_type<callingConvention = DW_CC_normal, types = #di_null_type, #[[COM_TY1]]>
15+
// CHECK: #llvm.di_subroutine_type<callingConvention = DW_CC_normal, types = #di_null_type, #[[COM_TY2]]>

0 commit comments

Comments
 (0)