Skip to content

Commit 47c1abf

Browse files
authored
[flang][debug] Fix array lower bounds in derived type members. (#113183)
The lower bound information for the array members of a derived type can't be obtained from the `DeclareOp`. It has to be extracted from the `TypeInfoOp`. That was left as FIXME in the code. This PR adds the missing functionality to fix the issue. I tried the following approaches before settling on the current one that is to generate `DITypeAttr` for array members right where the components are being processed. 1. Generate a temp XDeclareOp with the shift information obtained from the `TypeInfoOp`. This caused a few issues mostly related to `unrealized_conversion_cast`. 2. Change the shift operands in the `declOp` that was passed in the function before calling `convertType`. The code can be seen in the abcf031. It essentially looked like the following. It works correctly but I was not sure if temporarily changing the `declOp` is the safe thing to do. ``` mlir::OperandRange originalShift = declOp.getShift(); mlir::MutableOperandRange mutableOpRange = declOp.getShiftMutable(); mutableOpRange.assign(shiftOpers); elemTy = convertType(fieldTy, fileAttr, scope, declOp); mutableOpRange.assign(originalShift); ``` Fixes #113178.
1 parent 76edf72 commit 47c1abf

File tree

2 files changed

+49
-3
lines changed

2 files changed

+49
-3
lines changed

flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "DebugTypeGenerator.h"
1616
#include "flang/Optimizer/CodeGen/DescriptorModel.h"
1717
#include "flang/Optimizer/Support/InternalNames.h"
18+
#include "flang/Optimizer/Support/Utils.h"
1819
#include "mlir/Pass/Pass.h"
1920
#include "llvm/ADT/ScopeExit.h"
2021
#include "llvm/BinaryFormat/Dwarf.h"
@@ -298,6 +299,8 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertRecordType(
298299
fir::TypeInfoOp tiOp = symbolTable->lookup<fir::TypeInfoOp>(Ty.getName());
299300
unsigned line = (tiOp) ? getLineFromLoc(tiOp.getLoc()) : 1;
300301

302+
mlir::OpBuilder builder(context);
303+
mlir::IntegerType intTy = mlir::IntegerType::get(context, 64);
301304
std::uint64_t offset = 0;
302305
for (auto [fieldName, fieldTy] : Ty.getTypeList()) {
303306
mlir::Type llvmTy;
@@ -307,11 +310,38 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertRecordType(
307310
else
308311
llvmTy = llvmTypeConverter.convertType(fieldTy);
309312

310-
// FIXME: Handle non defaults array bound in derived types
311313
uint64_t byteSize = dataLayout->getTypeSize(llvmTy);
312314
unsigned short byteAlign = dataLayout->getTypeABIAlignment(llvmTy);
313-
mlir::LLVM::DITypeAttr elemTy =
314-
convertType(fieldTy, fileAttr, scope, /*declOp=*/nullptr);
315+
std::optional<llvm::ArrayRef<int64_t>> lowerBounds =
316+
fir::getComponentLowerBoundsIfNonDefault(Ty, fieldName, module,
317+
symbolTable);
318+
auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(fieldTy);
319+
320+
// For members of the derived types, the information about the shift in
321+
// lower bounds is not part of the declOp but has to be extracted from the
322+
// TypeInfoOp (using getComponentLowerBoundsIfNonDefault).
323+
mlir::LLVM::DITypeAttr elemTy;
324+
if (lowerBounds && seqTy &&
325+
lowerBounds->size() == seqTy.getShape().size()) {
326+
llvm::SmallVector<mlir::LLVM::DINodeAttr> elements;
327+
for (auto [bound, dim] :
328+
llvm::zip_equal(*lowerBounds, seqTy.getShape())) {
329+
auto countAttr = mlir::IntegerAttr::get(intTy, llvm::APInt(64, dim));
330+
auto lowerAttr = mlir::IntegerAttr::get(intTy, llvm::APInt(64, bound));
331+
auto subrangeTy = mlir::LLVM::DISubrangeAttr::get(
332+
context, countAttr, lowerAttr, /*upperBound=*/nullptr,
333+
/*stride=*/nullptr);
334+
elements.push_back(subrangeTy);
335+
}
336+
elemTy = mlir::LLVM::DICompositeTypeAttr::get(
337+
context, llvm::dwarf::DW_TAG_array_type, /*name=*/nullptr,
338+
/*file=*/nullptr, /*line=*/0, /*scope=*/nullptr,
339+
convertType(seqTy.getEleTy(), fileAttr, scope, declOp),
340+
mlir::LLVM::DIFlags::Zero, /*sizeInBits=*/0, /*alignInBits=*/0,
341+
elements, /*dataLocation=*/nullptr, /*rank=*/nullptr,
342+
/*allocated=*/nullptr, /*associated=*/nullptr);
343+
} else
344+
elemTy = convertType(fieldTy, fileAttr, scope, /*declOp=*/nullptr);
315345
offset = llvm::alignTo(offset, byteAlign);
316346
mlir::LLVM::DIDerivedTypeAttr tyAttr = mlir::LLVM::DIDerivedTypeAttr::get(
317347
context, llvm::dwarf::DW_TAG_member,
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s | FileCheck %s
2+
3+
module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
4+
fir.global @_QMmEvar : !fir.type<_QMmTt1{elm:!fir.array<5xi32>,elm2:!fir.array<5x8xi32>}> {} loc(#loc1)
5+
fir.type_info @_QMmTt1 noinit nodestroy nofinal : !fir.type<_QMmTt1{elm:!fir.array<5xi32>,elm2:!fir.array<5x8xi32>}> component_info {
6+
fir.dt_component "elm" lbs [2]
7+
fir.dt_component "elm2" lbs [1, 3]
8+
} loc(#loc1)
9+
}
10+
#loc1 = loc("derived.f90":24:1)
11+
12+
13+
// CHECK-DAG: #[[TY1:.*]] = #llvm.di_composite_type<tag = DW_TAG_array_type, {{.*}} = #{{.*}}, elements = #llvm.di_subrange<count = 5 : i64, lowerBound = 2 : i64>>
14+
// CHECK-DAG: #[[TY2:.*]] = #llvm.di_composite_type<tag = DW_TAG_array_type, baseType = #{{.*}}, elements = #llvm.di_subrange<count = 5 : i64, lowerBound = 1 : i64>, #llvm.di_subrange<count = 8 : i64, lowerBound = 3 : i64>>
15+
// CHECK-DAG: #llvm.di_derived_type<tag = DW_TAG_member, name = "elm", baseType = #[[TY1]], sizeInBits = {{.*}}, alignInBits = {{.*}}>
16+
// CHECK-DAG: #llvm.di_derived_type<tag = DW_TAG_member, name = "elm2", baseType = #[[TY2]], sizeInBits = {{.*}}, alignInBits = {{.*}}>

0 commit comments

Comments
 (0)