Skip to content

Commit 2afc9bd

Browse files
abidhaaryanshukla
authored andcommitted
[flang][debug] Support assumed size arrays. (llvm#96316)
Here we don't know the size of last dimension and use a null subrange for that. User will have to provide the dimension when evaluating variable of this type. The debugging looks like as follows: subroutine fn(a1, a2) integer a1(5, *), a2(*) ... end (gdb) p a1(1,2) $2 = 2 (gdb) p a2(3) $3 = 3 (gdb) ptype a1 type = integer (5,*) (gdb) ptype a2 type = integer (*)
1 parent 5b53ce1 commit 2afc9bd

File tree

4 files changed

+86
-16
lines changed

4 files changed

+86
-16
lines changed

flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -157,28 +157,35 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertSequenceType(
157157
fir::SequenceType seqTy, mlir::LLVM::DIFileAttr fileAttr,
158158
mlir::LLVM::DIScopeAttr scope, mlir::Location loc) {
159159
mlir::MLIRContext *context = module.getContext();
160-
// FIXME: Only fixed sizes arrays handled at the moment.
161-
if (seqTy.hasDynamicExtents())
162-
return genPlaceholderType(context);
163160

164161
llvm::SmallVector<mlir::LLVM::DINodeAttr> elements;
165162
mlir::LLVM::DITypeAttr elemTy =
166163
convertType(seqTy.getEleTy(), fileAttr, scope, loc);
167164

168165
for (fir::SequenceType::Extent dim : seqTy.getShape()) {
169-
auto intTy = mlir::IntegerType::get(context, 64);
170-
// FIXME: Only supporting lower bound of 1 at the moment. The
171-
// 'SequenceType' has information about the shape but not the shift. In
172-
// cases where the conversion originated during the processing of
173-
// 'DeclareOp', it may be possible to pass on this information. But the
174-
// type conversion should ideally be based on what information present in
175-
// the type class so that it works from everywhere (e.g. when it is part
176-
// of a module or a derived type.)
177-
auto countAttr = mlir::IntegerAttr::get(intTy, llvm::APInt(64, dim));
178-
auto lowerAttr = mlir::IntegerAttr::get(intTy, llvm::APInt(64, 1));
179-
auto subrangeTy = mlir::LLVM::DISubrangeAttr::get(
180-
context, countAttr, lowerAttr, nullptr, nullptr);
181-
elements.push_back(subrangeTy);
166+
if (dim == seqTy.getUnknownExtent()) {
167+
// FIXME: This path is taken for assumed size arrays but also for arrays
168+
// with non constant extent. For the latter case, the DISubrangeAttr
169+
// should point to a variable which will have the extent at runtime.
170+
auto subrangeTy = mlir::LLVM::DISubrangeAttr::get(
171+
context, /*count=*/nullptr, /*lowerBound=*/nullptr,
172+
/*upperBound*/ nullptr, /*stride*/ nullptr);
173+
elements.push_back(subrangeTy);
174+
} else {
175+
auto intTy = mlir::IntegerType::get(context, 64);
176+
// FIXME: Only supporting lower bound of 1 at the moment. The
177+
// 'SequenceType' has information about the shape but not the shift. In
178+
// cases where the conversion originated during the processing of
179+
// 'DeclareOp', it may be possible to pass on this information. But the
180+
// type conversion should ideally be based on what information present in
181+
// the type class so that it works from everywhere (e.g. when it is part
182+
// of a module or a derived type.)
183+
auto countAttr = mlir::IntegerAttr::get(intTy, llvm::APInt(64, dim));
184+
auto lowerAttr = mlir::IntegerAttr::get(intTy, llvm::APInt(64, 1));
185+
auto subrangeTy = mlir::LLVM::DISubrangeAttr::get(
186+
context, countAttr, lowerAttr, nullptr, nullptr);
187+
elements.push_back(subrangeTy);
188+
}
182189
}
183190
// Apart from arrays, the `DICompositeTypeAttr` is used for other things like
184191
// structure types. Many of its fields which are not applicable to arrays
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck %s
2+
3+
XFAIL: *
4+
5+
! Test that debug info for arrays with non constant extent is different from
6+
! assumed size arrays.
7+
8+
module helper
9+
implicit none
10+
contains
11+
subroutine fn (a1, n)
12+
integer n
13+
integer a1(5, n)
14+
print *, a1(1,1)
15+
end subroutine fn
16+
end module helper
17+
18+
! CHECK-DAG: ![[TY1:[0-9]+]] = !DICompositeType(tag: DW_TAG_array_type{{.*}}elements: ![[ELEMS1:[0-9]+]]{{.*}})
19+
! CHECK-DAG: ![[ELEMS1]] = !{![[ELM1:[0-9]+]], ![[ELM2:[0-9]+]]}
20+
! CHECK-DAG: ![[ELM1]] = !DISubrange(count: 5, lowerBound: 1)
21+
! CHECK-DAG: ![[ELM2]] = !DISubrange(count: [[VAR:[0-9]+]], lowerBound: 1)
22+
! CHECK-DAG: ![[VAR]] = !DILocalVariable
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck %s
2+
3+
module helper
4+
implicit none
5+
contains
6+
subroutine fn (a1, a2)
7+
integer a1(5, *), a2(*)
8+
print *, a1(1,1)
9+
print *, a2(2)
10+
end subroutine fn
11+
end module helper
12+
13+
! CHECK-DAG: ![[TY1:[0-9]+]] = !DICompositeType(tag: DW_TAG_array_type{{.*}}elements: ![[ELEMS1:[0-9]+]]{{.*}})
14+
! CHECK-DAG: ![[ELEMS1]] = !{![[ELM1:[0-9]+]], ![[EMPTY:[0-9]+]]}
15+
! CHECK-DAG: ![[ELM1]] = !DISubrange(count: 5, lowerBound: 1)
16+
! CHECK-DAG: ![[EMPTY]] = !DISubrange()
17+
! CHECK-DAG: ![[TY2:[0-9]+]] = !DICompositeType(tag: DW_TAG_array_type{{.*}}elements: ![[ELEMS2:[0-9]+]]{{.*}})
18+
! CHECK-DAG: ![[ELEMS2]] = !{![[EMPTY:[0-9]+]]}
19+
! CHECK-DAG: !DILocalVariable(name: "a1"{{.*}}type: ![[TY1:[0-9]+]])
20+
! CHECK-DAG: !DILocalVariable(name: "a2"{{.*}}type: ![[TY2:[0-9]+]])
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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 @_QMhelperPfn(%arg0: !fir.ref<!fir.array<5x?xi32>> {fir.bindc_name = "a1"}, %arg1: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "a2"}, %arg2: !fir.ref<!fir.array<2x?xi32>> {fir.bindc_name = "a3"}) {
5+
%c5 = arith.constant 5 : index
6+
%c1 = arith.constant 1 : index
7+
%c-1 = arith.constant -1 : index
8+
%0 = fir.undefined !fir.dscope
9+
%1 = fircg.ext_declare %arg0(%c5, %c-1) dummy_scope %0 {uniq_name = "_QMhelperFfnEa1"} : (!fir.ref<!fir.array<5x?xi32>>, index, index, !fir.dscope) -> !fir.ref<!fir.array<5x?xi32>> loc(#loc1)
10+
%2 = fircg.ext_declare %arg1(%c-1) dummy_scope %0 {uniq_name = "_QMhelperFfnEa2"} : (!fir.ref<!fir.array<?xi32>>, index, !fir.dscope) -> !fir.ref<!fir.array<?xi32>> loc(#loc2)
11+
return
12+
} loc(#loc3)
13+
}
14+
#loc3 = loc("test.f90":1:1)
15+
#loc1 = loc("test.f90":3:1)
16+
#loc2 = loc("test.f90":4:1)
17+
18+
// CHECK-DAG: #[[TY1:.*]] = #llvm.di_composite_type<tag = DW_TAG_array_type{{.*}}elements = #llvm.di_subrange<count = 5 : i64, lowerBound = 1 : i64>, #llvm.di_subrange<>>
19+
// CHECK-DAG: #[[TY2:.*]] = #llvm.di_composite_type<tag = DW_TAG_array_type{{.*}}elements = #llvm.di_subrange<>>
20+
// CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "a1"{{.*}}type = #[[TY1]]>
21+
// CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "a2"{{.*}}type = #[[TY2]]>

0 commit comments

Comments
 (0)