[flang-commits] [flang] [flang][debug] Support ClassType. (PR #114809)
Abid Qadeer via flang-commits
flang-commits at lists.llvm.org
Mon Nov 4 07:09:38 PST 2024
https://github.com/abidh created https://github.com/llvm/llvm-project/pull/114809
This PR adds the handling of `ClassType`. It is treated as pointer to the underlying type. Note that `ClassType` when passed to the function have double indirection so it is represented as pointer to type (compared to other types which may have a single indirection).
If `ClassType` wraps a pointer or allocatable then we take care to generate it as PTR -> type (and not PTR -> PTR -> type).
This is how it looks like in the debugger.
```
subroutine test_proc (this)
class(test_type), intent (inout) :: this
allocate (this%b (3, 2))
call fill_array_2d (this%b)
print *, this%a
end
```
```
(gdb) p this
$6 = (PTR TO -> ( Type test_type )) 0x2052a0
(gdb) p this%a
$7 = 0
(gdb) p this%b
$8 = ((1, 2, 3) (4, 5, 6))
```
>From 8fa049070f7e3749b8f99936611bc401037b01d4 Mon Sep 17 00:00:00 2001
From: Abid Qadeer <haqadeer at amd.com>
Date: Mon, 28 Oct 2024 17:52:56 +0000
Subject: [PATCH] [flang][debug] Support ClassType.
This PR adds the handling of ClassType. It is treated as pointer to
the underlying type. Note that ClassType when passed to the function
have double indirection so it is represented as pointer to type
(and not type as a RecordType will be for example).
If ClassType wraps a pointer or allocatable then we take care to
avoid double indirection.
This is how it looks like in the debugger.
subroutine test_proc (this)
class(test_type), intent (inout) :: this
allocate (this%b (3, 2))
call fill_array_2d (this%b)
print *, this%a
end
(gdb) p this
$6 = (PTR TO -> ( Type test_type )) 0x2052a0
(gdb) p this%a
$7 = 0
(gdb) p this%b
$8 = ((1, 2, 3) (4, 5, 6))
(gdb)
---
.../Transforms/DebugTypeGenerator.cpp | 14 ++++++++++
flang/test/Transforms/debug-class-type.fir | 27 +++++++++++++++++++
2 files changed, 41 insertions(+)
create mode 100644 flang/test/Transforms/debug-class-type.fir
diff --git a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
index a070c87137fa16..28c4b9fac74ec5 100644
--- a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
+++ b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
@@ -617,6 +617,20 @@ DebugTypeGenerator::convertType(mlir::Type Ty, mlir::LLVM::DIFileAttr fileAttr,
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 classTy = mlir::dyn_cast_if_present<fir::ClassType>(Ty)) {
+ // ClassType when passed to the function have double indirection so it
+ // is represented as pointer to type (and not type as a RecordType will be
+ // for example). If ClassType wraps a pointer or allocatable then we get
+ // the real underlying type to avoid translating the Ty to
+ // Ptr -> Ptr -> type.
+ mlir::Type elTy = classTy.getEleTy();
+ if (auto ptrTy = mlir::dyn_cast_if_present<fir::PointerType>(elTy))
+ elTy = ptrTy.getElementType();
+ else if (auto heapTy = mlir::dyn_cast_if_present<fir::HeapType>(elTy))
+ elTy = heapTy.getElementType();
+ return convertPointerLikeType(elTy, fileAttr, scope, declOp,
+ /*genAllocated=*/false,
+ /*genAssociated=*/false);
} 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/test/Transforms/debug-class-type.fir b/flang/test/Transforms/debug-class-type.fir
new file mode 100644
index 00000000000000..e11dc7b2a2086a
--- /dev/null
+++ b/flang/test/Transforms/debug-class-type.fir
@@ -0,0 +1,27 @@
+// RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s | FileCheck %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
+ fir.type_info @_QTtest_type nofinal : !fir.type<_QTtest_type{a:i32,b:!fir.box<!fir.heap<!fir.array<?x?xf32>>>}> dispatch_table {
+ fir.dt_entry "test_proc", @_QPtest_proc
+ } loc(#loc1)
+ func.func private @_QPtest_proc(%arg0: !fir.class<!fir.type<_QTtest_type{a:i32,b:!fir.box<!fir.heap<!fir.array<?x?xf32>>>}>>)
+
+ func.func @test() {
+ %0 = fir.address_of(@_QFEx) : !fir.ref<!fir.class<!fir.heap<!fir.type<_QTtest_type{a:i32,b:!fir.box<!fir.heap<!fir.array<?x?xf32>>>}>>>>
+ %1 = fircg.ext_declare %0 {uniq_name = "_QFEx"} : (!fir.ref<!fir.class<!fir.heap<!fir.type<_QTtest_type{a:i32,b:!fir.box<!fir.heap<!fir.array<?x?xf32>>>}>>>>) -> !fir.ref<!fir.class<!fir.heap<!fir.type<_QTtest_type{a:i32,b:!fir.box<!fir.heap<!fir.array<?x?xf32>>>}>>>> loc(#loc3)
+ %2 = fir.address_of(@_QFEy) : !fir.ref<!fir.class<!fir.ptr<!fir.type<_QTtest_type{a:i32,b:!fir.box<!fir.heap<!fir.array<?x?xf32>>>}>>>>
+ %3 = fircg.ext_declare %2 {uniq_name = "_QFEy"} : (!fir.ref<!fir.class<!fir.ptr<!fir.type<_QTtest_type{a:i32,b:!fir.box<!fir.heap<!fir.array<?x?xf32>>>}>>>>) -> !fir.ref<!fir.class<!fir.ptr<!fir.type<_QTtest_type{a:i32,b:!fir.box<!fir.heap<!fir.array<?x?xf32>>>}>>>> loc(#loc4)
+ return
+ } loc(#loc2)
+}
+
+#loc1 = loc("./simple.f90":2:1)
+#loc2 = loc("./simple.f90":10:1)
+#loc3 = loc("./simple.f90":15:1)
+#loc4 = loc("./simple.f90":22:1)
+
+// CHECK-DAG: #[[TY1:.*]] = #llvm.di_composite_type<{{.*}}name = "test_type"{{.*}}>
+// CHECK-DAG: #[[TY2:.*]] = #llvm.di_derived_type<tag = DW_TAG_pointer_type, name = "", baseType = #[[TY1]]{{.*}}>
+// CHECK-DAG: #llvm.di_subroutine_type<callingConvention = DW_CC_normal, types = #di_null_type, #[[TY2]]>
+// CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "x"{{.*}}type = #[[TY2]]>
+// CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "y"{{.*}}type = #[[TY2]]>
More information about the flang-commits
mailing list