-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[flang][debug] Support complex types. #92559
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This PR adds supports for conversion of complex type to corresponding DITypeAttr. Both fir and mlir types are supported. Apart from lit testing, I have also tested the types in debugger and they work correctly. An exception is 128 bit complex which somehow requires that its name be different from `complex`. I am going to open a separate PR to add (kind=n) in the type names similar to what gfortran does.
@llvm/pr-subscribers-flang-fir-hlfir Author: Abid Qadeer (abidh) ChangesThis PR adds supports for conversion of complex type to corresponding DITypeAttr. Both fir and mlir types are supported. Apart from lit testing, I have also tested the types in debugger and they work correctly. An exception is 128 bit complex which somehow requires that its name be different from Full diff: https://github.com/llvm/llvm-project/pull/92559.diff 3 Files Affected:
diff --git a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
index 64c6547e06e0f..ad6e4813ef820 100644
--- a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
+++ b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
@@ -57,6 +57,16 @@ DebugTypeGenerator::convertType(mlir::Type Ty, mlir::LLVM::DIFileAttr fileAttr,
mlir::StringAttr::get(context, logTy.getMnemonic()),
kindMapping.getLogicalBitsize(logTy.getFKind()),
llvm::dwarf::DW_ATE_boolean);
+ } else if (fir::isa_complex(Ty)) {
+ unsigned bitWidth;
+ if (auto cplxTy = mlir::dyn_cast_or_null<mlir::ComplexType>(Ty)) {
+ auto floatTy = mlir::cast<mlir::FloatType>(cplxTy.getElementType());
+ bitWidth = floatTy.getWidth();
+ } else if (auto cplxTy = mlir::dyn_cast_or_null<fir::ComplexType>(Ty))
+ bitWidth = kindMapping.getRealBitsize(cplxTy.getFKind());
+
+ return genBasicType(context, mlir::StringAttr::get(context, "complex"),
+ bitWidth * 2, llvm::dwarf::DW_ATE_complex_float);
} else {
// FIXME: These types are currently unhandled. We are generating a
// placeholder type to allow us to test supported bits.
diff --git a/flang/test/Transforms/debug-complex-1.fir b/flang/test/Transforms/debug-complex-1.fir
new file mode 100644
index 0000000000000..fe50da5914476
--- /dev/null
+++ b/flang/test/Transforms/debug-complex-1.fir
@@ -0,0 +1,39 @@
+// RUN: fir-opt --cg-rewrite="preserve-declare=true" --mlir-print-debuginfo %s | fir-opt --add-debug-info --mlir-print-debuginfo | FileCheck %s
+
+// check conversion of complex type of different size. Both fir and mlir
+// variants are checked.
+
+module attributes {fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.target_triple = "native"} {
+ func.func @test1(%x : !fir.complex<4>) -> !fir.complex<8> {
+ %1 = fir.convert %x : (!fir.complex<4>) -> !fir.complex<8>
+ return %1 : !fir.complex<8>
+ }loc(#loc1)
+ func.func @test2(%x : !fir.complex<4>) -> complex<f64> {
+ %1 = fir.convert %x : (!fir.complex<4>) -> complex<f64>
+ return %1 : complex<f64>
+ }loc(#loc2)
+ func.func @test3(%x : !fir.complex<4>) -> !fir.complex<16> {
+ %1 = fir.convert %x : (!fir.complex<4>) -> !fir.complex<16>
+ return %1 : !fir.complex<16>
+ }loc(#loc3)
+ func.func @test4(%x : !fir.complex<4>) -> complex<f128> {
+ %1 = fir.convert %x : (!fir.complex<4>) -> complex<f128>
+ return %1 : complex<f128>
+ }loc(#loc4)
+}
+#loc1 = loc("./simple.f90":2:1)
+#loc2 = loc("./simple.f90":5:1)
+#loc3 = loc("./simple.f90":8:1)
+#loc4 = loc("./simple.f90":11:1)
+
+// CHECK-DAG: #[[CMPX8:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "complex", sizeInBits = 128, encoding = DW_ATE_complex_float>
+// CHECK-DAG: #[[CMPX4:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "complex", sizeInBits = 64, encoding = DW_ATE_complex_float>
+// CHECK-DAG: #[[CMPX16:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "complex", sizeInBits = 256, encoding = DW_ATE_complex_float>
+
+// CHECK-DAG: #[[TY1:.*]] = #llvm.di_subroutine_type<{{.*}}types = #[[CMPX8]], #[[CMPX4]]>
+// CHECK-DAG: #[[TY2:.*]] = #llvm.di_subroutine_type<{{.*}}types = #[[CMPX16]], #[[CMPX4]]>
+
+// CHECK-DAG: #llvm.di_subprogram<{{.*}}name = "test1"{{.*}}type = #[[TY1]]>
+// CHECK-DAG: #llvm.di_subprogram<{{.*}}name = "test2"{{.*}}type = #[[TY1]]>
+// CHECK-DAG: #llvm.di_subprogram<{{.*}}name = "test3"{{.*}}type = #[[TY2]]>
+// CHECK-DAG: #llvm.di_subprogram<{{.*}}name = "test4"{{.*}}type = #[[TY2]]>
diff --git a/flang/test/Transforms/debug-complex-2.f90 b/flang/test/Transforms/debug-complex-2.f90
new file mode 100644
index 0000000000000..9d44a80a9e34d
--- /dev/null
+++ b/flang/test/Transforms/debug-complex-2.f90
@@ -0,0 +1,39 @@
+! RUN: %flang_fc1 -emit-fir -debug-info-kind=standalone -mmlir --mlir-print-debuginfo %s -o - | \
+! RUN: fir-opt --cg-rewrite="preserve-declare=true" --mlir-print-debuginfo | fir-opt --add-debug-info --mlir-print-debuginfo | FileCheck %s
+! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck --check-prefix=LLVM %s
+
+program mn
+ complex(kind=4) :: c4
+ complex(kind=8) :: c8
+ complex(kind=16) :: r
+ r = fn1(c4, c8)
+ print *, r
+contains
+ function fn1(a, b) result (c)
+ complex(kind=4), intent(in) :: a
+ complex(kind=8), intent(in) :: b
+ complex(kind=16) :: c
+ c = a + b
+ end function
+end program
+
+! CHECK-DAG: #[[CMPX4:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "complex", sizeInBits = 64, encoding = DW_ATE_complex_float>
+! CHECK-DAG: #[[CMPX8:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "complex", sizeInBits = 128, encoding = DW_ATE_complex_float>
+! CHECK-DAG: #[[CMPX16:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "complex", sizeInBits = 256, encoding = DW_ATE_complex_float>
+
+! CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "c4"{{.*}}type = #[[CMPX4]]>
+! CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "c8"{{.*}}type = #[[CMPX8]]>
+! CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "r"{{.*}}type = #[[CMPX16]]>
+! CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "a"{{.*}}type = #[[CMPX4]]>
+! CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "b"{{.*}}type = #[[CMPX8]]>
+! CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "c"{{.*}}type = #[[CMPX16]]>
+
+! LLVM-DAG: ![[C4:.*]] = !DIBasicType(name: "complex", size: 64, encoding: DW_ATE_complex_float)
+! LLVM-DAG: ![[C8:.*]] = !DIBasicType(name: "complex", size: 128, encoding: DW_ATE_complex_float)
+! LLVM-DAG: ![[C16:.*]] = !DIBasicType(name: "complex", size: 256, encoding: DW_ATE_complex_float)
+! LLVM-DAG: !DILocalVariable(name: "c4"{{.*}}type: ![[C4]])
+! LLVM-DAG: !DILocalVariable(name: "c8"{{.*}}type: ![[C8]])
+! LLVM-DAG: !DILocalVariable(name: "r"{{.*}}type: ![[C16]])
+! LLVM-DAG: !DILocalVariable(name: "a"{{.*}}type: ![[C4]])
+! LLVM-DAG: !DILocalVariable(name: "b"{{.*}}type: ![[C8]])
+! LLVM-DAG: !DILocalVariable(name: "c"{{.*}}type: ![[C16]])
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this!
@@ -57,6 +57,16 @@ DebugTypeGenerator::convertType(mlir::Type Ty, mlir::LLVM::DIFileAttr fileAttr, | |||
mlir::StringAttr::get(context, logTy.getMnemonic()), | |||
kindMapping.getLogicalBitsize(logTy.getFKind()), | |||
llvm::dwarf::DW_ATE_boolean); | |||
} else if (fir::isa_complex(Ty)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LLVM has some guidelines regarding else after return. https://llvm.org/docs/CodingStandards.html#don-t-use-else-after-a-return
@@ -57,6 +57,16 @@ DebugTypeGenerator::convertType(mlir::Type Ty, mlir::LLVM::DIFileAttr fileAttr, | |||
mlir::StringAttr::get(context, logTy.getMnemonic()), | |||
kindMapping.getLogicalBitsize(logTy.getFKind()), | |||
llvm::dwarf::DW_ATE_boolean); | |||
} else if (fir::isa_complex(Ty)) { | |||
unsigned bitWidth; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to initialize this to some value to avoid an uninitialized warning or alternatively add an else case below to assert or llvm unreachable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is better to make the intention explicit. I have added an llvm_unreachable.
@@ -0,0 +1,39 @@ | |||
// RUN: fir-opt --cg-rewrite="preserve-declare=true" --mlir-print-debuginfo %s | fir-opt --add-debug-info --mlir-print-debuginfo | FileCheck %s |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the cg-rewrite pass do anything useful here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, only add-debug-info is needed. I have updated the test.
@@ -0,0 +1,28 @@ | |||
! RUN: %flang_fc1 -emit-fir -debug-info-kind=standalone -mmlir --mlir-print-debuginfo %s -o - | \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this test anything different from debug-complex-1.fir
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was going to remove it after the discussion in #91582. Done now.
1. Remove the fortran testcase as it was redundant. 2. Remove redundant command from RUN line. 3. Add an llvm_unreachable if we get a complex type which is not fir or mlir complex type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LG.
This PR adds supports for conversion of complex type to corresponding DITypeAttr. Both fir and mlir types are supported.
Apart from lit testing, I have also tested the types in debugger and they work correctly. An exception is 128 bit complex which somehow requires that its name be different from
complex
. I am going to open a separate PR to add (kind=n) in the type names similar to what gfortran does.