[flang-commits] [flang] [flang][debug] Handle allocatable strings. (PR #95906)
Abid Qadeer via flang-commits
flang-commits at lists.llvm.org
Wed Jun 19 03:04:02 PDT 2024
https://github.com/abidh updated https://github.com/llvm/llvm-project/pull/95906
>From 84bc2420008d6581f2cc7acbc8902909d172d75d Mon Sep 17 00:00:00 2001
From: Abid Qadeer <haqadeer at amd.com>
Date: Mon, 17 Jun 2024 17:31:46 +0100
Subject: [PATCH 1/2] [flang][debug] Handle allocatable strings.
The allocatable strings also use DIStringType but provide dwarf
expression to find the location and length of the string. With this
change in place, the debugging of the allocatable strings looks like
this:
character(len=:), allocatable :: first
character(len=:), allocatable :: second
character(len=:), allocatable :: third
first = 'Mount'
second = 'Everest'
third = first // " " // second
print *, third
(gdb) p third
$1 = ""
(gdb) n
18 print *, third
(gdb) p third
$2 = 'Mount Everest'
(gdb) ptype third
type = character (13)
---
.../Transforms/DebugTypeGenerator.cpp | 42 +++++++++++++++----
.../Optimizer/Transforms/DebugTypeGenerator.h | 4 +-
flang/test/Integration/debug-char-type-1.f90 | 6 ++-
flang/test/Transforms/debug-char-type-1.fir | 9 +++-
4 files changed, 50 insertions(+), 11 deletions(-)
diff --git a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
index 407ecc8e327b4..996b2c43a1159 100644
--- a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
+++ b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
@@ -61,9 +61,11 @@ DebugTypeGenerator::DebugTypeGenerator(mlir::ModuleOp m)
// descriptors like lower_bound and extent for each dimension.
mlir::Type llvmDimsType = getDescFieldTypeModel<kDimsPosInBox>()(context);
mlir::Type llvmPtrType = getDescFieldTypeModel<kAddrPosInBox>()(context);
+ mlir::Type llvmLenType = getDescFieldTypeModel<kElemLenPosInBox>()(context);
dimsOffset = getComponentOffset<kDimsPosInBox>(*dl, context, llvmDimsType);
dimsSize = dl->getTypeSize(llvmDimsType);
ptrSize = dl->getTypeSize(llvmPtrType);
+ lenOffset = getComponentOffset<kElemLenPosInBox>(*dl, context, llvmLenType);
}
static mlir::LLVM::DITypeAttr genBasicType(mlir::MLIRContext *context,
@@ -192,10 +194,8 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertSequenceType(
mlir::LLVM::DITypeAttr DebugTypeGenerator::convertCharacterType(
fir::CharacterType charTy, mlir::LLVM::DIFileAttr fileAttr,
- mlir::LLVM::DIScopeAttr scope, mlir::Location loc) {
+ mlir::LLVM::DIScopeAttr scope, mlir::Location loc, bool allocatable) {
mlir::MLIRContext *context = module.getContext();
- if (!charTy.hasConstantLen())
- return genPlaceholderType(context);
// DWARF 5 says the following about the character encoding in 5.1.1.2.
// "DW_ATE_ASCII and DW_ATE_UCS specify encodings for the Fortran 2003
@@ -205,16 +205,38 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertCharacterType(
if (charTy.getFKind() != 1)
encoding = llvm::dwarf::DW_ATE_UCS;
+ uint64_t sizeInBits = 0;
+ mlir::LLVM::DIExpressionAttr lenExpr = nullptr;
+ mlir::LLVM::DIExpressionAttr locExpr = nullptr;
+
+ if (allocatable) {
+ llvm::SmallVector<mlir::LLVM::DIExpressionElemAttr> ops;
+ auto addOp = [&](unsigned opc, llvm::ArrayRef<uint64_t> vals) {
+ ops.push_back(mlir::LLVM::DIExpressionElemAttr::get(context, opc, vals));
+ };
+ addOp(llvm::dwarf::DW_OP_push_object_address, {});
+ addOp(llvm::dwarf::DW_OP_plus_uconst, {lenOffset});
+ lenExpr = mlir::LLVM::DIExpressionAttr::get(context, ops);
+ ops.clear();
+
+ addOp(llvm::dwarf::DW_OP_push_object_address, {});
+ addOp(llvm::dwarf::DW_OP_deref, {});
+ locExpr = mlir::LLVM::DIExpressionAttr::get(context, ops);
+ } else if (charTy.hasConstantLen()) {
+ sizeInBits =
+ charTy.getLen() * kindMapping.getCharacterBitsize(charTy.getFKind());
+ } else {
+ return genPlaceholderType(context);
+ }
+
// FIXME: Currently the DIStringType in llvm does not have the option to set
// type of the underlying character. This restricts out ability to represent
// string with non-default characters. Please see issue #95440 for more
// details.
return mlir::LLVM::DIStringTypeAttr::get(
context, llvm::dwarf::DW_TAG_string_type,
- mlir::StringAttr::get(context, ""),
- charTy.getLen() * kindMapping.getCharacterBitsize(charTy.getFKind()),
- /*alignInBits=*/0, /*stringLength=*/nullptr,
- /*stringLengthExp=*/nullptr, /*stringLocationExp=*/nullptr, encoding);
+ mlir::StringAttr::get(context, ""), sizeInBits, /*alignInBits=*/0,
+ /*stringLength=*/nullptr, lenExpr, locExpr, encoding);
}
mlir::LLVM::DITypeAttr DebugTypeGenerator::convertPointerLikeType(
@@ -229,6 +251,9 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertPointerLikeType(
if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(elTy))
return convertBoxedSequenceType(seqTy, fileAttr, scope, loc, genAllocated,
genAssociated);
+ if (auto charTy = mlir::dyn_cast_or_null<fir::CharacterType>(elTy))
+ return convertCharacterType(charTy, fileAttr, scope, loc,
+ /*allocatable=*/true);
mlir::LLVM::DITypeAttr elTyAttr = convertType(elTy, fileAttr, scope, loc);
@@ -274,7 +299,8 @@ DebugTypeGenerator::convertType(mlir::Type Ty, mlir::LLVM::DIFileAttr fileAttr,
} else if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(Ty)) {
return convertSequenceType(seqTy, fileAttr, scope, loc);
} else if (auto charTy = mlir::dyn_cast_or_null<fir::CharacterType>(Ty)) {
- return convertCharacterType(charTy, fileAttr, scope, loc);
+ return convertCharacterType(charTy, fileAttr, scope, loc,
+ /*allocatable=*/false);
} else if (auto boxTy = mlir::dyn_cast_or_null<fir::BoxType>(Ty)) {
auto elTy = boxTy.getElementType();
if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(elTy))
diff --git a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h
index 7816363e98821..567f26aa41912 100644
--- a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h
+++ b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h
@@ -48,7 +48,8 @@ class DebugTypeGenerator {
mlir::LLVM::DITypeAttr convertCharacterType(fir::CharacterType charTy,
mlir::LLVM::DIFileAttr fileAttr,
mlir::LLVM::DIScopeAttr scope,
- mlir::Location loc);
+ mlir::Location loc,
+ bool allocatable);
mlir::LLVM::DITypeAttr
convertPointerLikeType(mlir::Type elTy, mlir::LLVM::DIFileAttr fileAttr,
@@ -60,6 +61,7 @@ class DebugTypeGenerator {
std::uint64_t dimsSize;
std::uint64_t dimsOffset;
std::uint64_t ptrSize;
+ std::uint64_t lenOffset;
};
} // namespace fir
diff --git a/flang/test/Integration/debug-char-type-1.f90 b/flang/test/Integration/debug-char-type-1.f90
index a0aebd3125c6e..5068663aa9e28 100644
--- a/flang/test/Integration/debug-char-type-1.f90
+++ b/flang/test/Integration/debug-char-type-1.f90
@@ -2,6 +2,7 @@
module helper
character(len=40) :: str
+ character(len=:), allocatable :: str2
end module helper
program test
@@ -11,11 +12,14 @@ program test
first = '3.14 = π'
second = 'Fortran'
str = 'Hello World!'
+ str2 = 'A quick brown fox jumps over a lazy dog'
end program test
! CHECK-DAG: !DIGlobalVariable(name: "str"{{.*}}type: ![[TY40:[0-9]+]]{{.*}})
! CHECK-DAG: ![[TY40]] = !DIStringType(size: 320, encoding: DW_ATE_ASCII)
+! CHECK-DAG: !DIGlobalVariable(name: "str2"{{.*}}type: ![[TY:[0-9]+]]{{.*}})
+! CHECK-DAG: ![[TY]] = !DIStringType(stringLengthExpression: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 8), stringLocationExpression: !DIExpression(DW_OP_push_object_address, DW_OP_deref), encoding: DW_ATE_ASCII)
! CHECK-DAG: !DILocalVariable(name: "first"{{.*}}type: ![[TY8:[0-9]+]])
! CHECK-DAG: ![[TY8]] = !DIStringType(size: 256, encoding: DW_ATE_UCS)
! CHECK-DAG: !DILocalVariable(name: "second"{{.*}}type: ![[TY10:[0-9]+]])
-! CHECK-DAG: ![[TY10]] = !DIStringType(size: 80, encoding: DW_ATE_ASCII)
\ No newline at end of file
+! CHECK-DAG: ![[TY10]] = !DIStringType(size: 80, encoding: DW_ATE_ASCII)
diff --git a/flang/test/Transforms/debug-char-type-1.fir b/flang/test/Transforms/debug-char-type-1.fir
index cdce3b7b8b334..630b52d96cb85 100644
--- a/flang/test/Transforms/debug-char-type-1.fir
+++ b/flang/test/Transforms/debug-char-type-1.fir
@@ -9,6 +9,12 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
%0 = fir.zero_bits !fir.char<4,20>
fir.has_value %0 : !fir.char<4,20>
} loc(#loc1)
+ fir.global @_QMhelperEstr3 : !fir.box<!fir.heap<!fir.char<1,?>>> {
+ %c0 = arith.constant 0 : index
+ %0 = fir.zero_bits !fir.heap<!fir.char<1,?>>
+ %1 = fir.embox %0 typeparams %c0 : (!fir.heap<!fir.char<1,?>>, index) -> !fir.box<!fir.heap<!fir.char<1,?>>>
+ fir.has_value %1 : !fir.box<!fir.heap<!fir.char<1,?>>>
+ } loc(#loc1)
}
#loc1 = loc("string.f90":1:1)
@@ -16,4 +22,5 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
// CHECK-DAG: #llvm.di_global_variable<{{.*}}name = "str1"{{.*}}type = #[[TY1]]{{.*}}>
// CHECK-DAG: #[[TY2:.*]] = #llvm.di_string_type<tag = DW_TAG_string_type, name = "", sizeInBits = 640, encoding = DW_ATE_UCS>
// CHECK-DAG: #llvm.di_global_variable<{{.*}}name = "str2"{{.*}}type = #[[TY2]]{{.*}}>
-
+// CHECK-DAG: #[[TY3:.*]] = #llvm.di_string_type<tag = DW_TAG_string_type{{.*}}stringLengthExp = <[DW_OP_push_object_address, DW_OP_plus_uconst(8)]>, stringLocationExp = <[DW_OP_push_object_address, DW_OP_deref]>, encoding = DW_ATE_ASCII>
+// CHECK-DAG: #llvm.di_global_variable<{{.*}}name = "str3"{{.*}}type = #[[TY3]]{{.*}}>
>From 68b8bec4d254cd2bca8ba4a338a8d385ed2facb7 Mon Sep 17 00:00:00 2001
From: Abid Qadeer <haqadeer at amd.com>
Date: Wed, 19 Jun 2024 11:00:18 +0100
Subject: [PATCH 2/2] Handle review comments.
Rename allocatable parameter to hasDescriptor.
---
flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp | 8 ++++----
flang/lib/Optimizer/Transforms/DebugTypeGenerator.h | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
index 996b2c43a1159..0673070af362c 100644
--- a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
+++ b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
@@ -194,7 +194,7 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertSequenceType(
mlir::LLVM::DITypeAttr DebugTypeGenerator::convertCharacterType(
fir::CharacterType charTy, mlir::LLVM::DIFileAttr fileAttr,
- mlir::LLVM::DIScopeAttr scope, mlir::Location loc, bool allocatable) {
+ mlir::LLVM::DIScopeAttr scope, mlir::Location loc, bool hasDescriptor) {
mlir::MLIRContext *context = module.getContext();
// DWARF 5 says the following about the character encoding in 5.1.1.2.
@@ -209,7 +209,7 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertCharacterType(
mlir::LLVM::DIExpressionAttr lenExpr = nullptr;
mlir::LLVM::DIExpressionAttr locExpr = nullptr;
- if (allocatable) {
+ if (hasDescriptor) {
llvm::SmallVector<mlir::LLVM::DIExpressionElemAttr> ops;
auto addOp = [&](unsigned opc, llvm::ArrayRef<uint64_t> vals) {
ops.push_back(mlir::LLVM::DIExpressionElemAttr::get(context, opc, vals));
@@ -253,7 +253,7 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertPointerLikeType(
genAssociated);
if (auto charTy = mlir::dyn_cast_or_null<fir::CharacterType>(elTy))
return convertCharacterType(charTy, fileAttr, scope, loc,
- /*allocatable=*/true);
+ /*hasDescriptor=*/true);
mlir::LLVM::DITypeAttr elTyAttr = convertType(elTy, fileAttr, scope, loc);
@@ -300,7 +300,7 @@ DebugTypeGenerator::convertType(mlir::Type Ty, mlir::LLVM::DIFileAttr fileAttr,
return convertSequenceType(seqTy, fileAttr, scope, loc);
} else if (auto charTy = mlir::dyn_cast_or_null<fir::CharacterType>(Ty)) {
return convertCharacterType(charTy, fileAttr, scope, loc,
- /*allocatable=*/false);
+ /*hasDescriptor=*/false);
} else if (auto boxTy = mlir::dyn_cast_or_null<fir::BoxType>(Ty)) {
auto elTy = boxTy.getElementType();
if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(elTy))
diff --git a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h
index 567f26aa41912..ec881e8be7cad 100644
--- a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h
+++ b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h
@@ -49,7 +49,7 @@ class DebugTypeGenerator {
mlir::LLVM::DIFileAttr fileAttr,
mlir::LLVM::DIScopeAttr scope,
mlir::Location loc,
- bool allocatable);
+ bool hasDescriptor);
mlir::LLVM::DITypeAttr
convertPointerLikeType(mlir::Type elTy, mlir::LLVM::DIFileAttr fileAttr,
More information about the flang-commits
mailing list