Skip to content

Commit

Permalink
[flang][debug] Improve handling of dummy character arguments. (#108283)
Browse files Browse the repository at this point in the history
As described in #107998, we were not handling the case well when length
of the character is not part of the type. This PR handles one of the
case when the length can be calculated by looking at the result of
corresponding `fir.unboxchar`.

The DIStringTypeAttr have a `stringLength` field that can be a variable.
We create an artificial variable that will hold the length and used as
value of `stringLength` field. The variable is then attached with
a `DbgValueOp`.

Fixes #107998.
  • Loading branch information
abidh authored Sep 18, 2024
1 parent 9690b30 commit 76347ee
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 2 deletions.
27 changes: 25 additions & 2 deletions flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertCharacterType(
uint64_t sizeInBits = 0;
mlir::LLVM::DIExpressionAttr lenExpr = nullptr;
mlir::LLVM::DIExpressionAttr locExpr = nullptr;
mlir::LLVM::DIVariableAttr varAttr = nullptr;

if (hasDescriptor) {
llvm::SmallVector<mlir::LLVM::DIExpressionElemAttr> ops;
Expand All @@ -289,7 +290,29 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertCharacterType(
sizeInBits =
charTy.getLen() * kindMapping.getCharacterBitsize(charTy.getFKind());
} else {
return genPlaceholderType(context);
// In assumed length string, the len of the character is not part of the
// type but can be found at the runtime. Here we create an artificial
// variable that will contain that length. This variable is used as
// 'stringLength' in DIStringTypeAttr.
if (declOp && !declOp.getTypeparams().empty()) {
mlir::Operation *op = declOp.getTypeparams()[0].getDefiningOp();
if (auto unbox = mlir::dyn_cast_or_null<fir::UnboxCharOp>(op)) {
auto name =
mlir::StringAttr::get(context, "." + declOp.getUniqName().str());
mlir::OpBuilder builder(context);
builder.setInsertionPoint(declOp);
mlir::Type i64Ty = builder.getIntegerType(64);
auto convOp = builder.create<fir::ConvertOp>(unbox.getLoc(), i64Ty,
unbox.getResult(1));
mlir::LLVM::DITypeAttr Ty = convertType(i64Ty, fileAttr, scope, declOp);
auto lvAttr = mlir::LLVM::DILocalVariableAttr::get(
context, scope, name, fileAttr, /*line=*/0, /*argNo=*/0,
/*alignInBits=*/0, Ty, mlir::LLVM::DIFlags::Artificial);
builder.create<mlir::LLVM::DbgValueOp>(convOp.getLoc(), convOp, lvAttr,
nullptr);
varAttr = mlir::cast<mlir::LLVM::DIVariableAttr>(lvAttr);
}
}
}

// FIXME: Currently the DIStringType in llvm does not have the option to set
Expand All @@ -299,7 +322,7 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertCharacterType(
return mlir::LLVM::DIStringTypeAttr::get(
context, llvm::dwarf::DW_TAG_string_type,
mlir::StringAttr::get(context, ""), sizeInBits, /*alignInBits=*/0,
/*stringLength=*/nullptr, lenExpr, locExpr, encoding);
/*stringLength=*/varAttr, lenExpr, locExpr, encoding);
}

mlir::LLVM::DITypeAttr DebugTypeGenerator::convertPointerLikeType(
Expand Down
23 changes: 23 additions & 0 deletions flang/test/Transforms/debug-107988.fir
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s -o - | FileCheck %s

module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
func.func @test(%arg0: !fir.ref<!fir.char<1,?>> {fir.bindc_name = "str"}, %arg1: i64) {
%0 = fir.emboxchar %arg0, %arg1 : (!fir.ref<!fir.char<1,?>>, i64) -> !fir.boxchar<1>
%1 = fir.undefined !fir.dscope
%2:2 = fir.unboxchar %0 : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index) loc(#loc1)
%3 = fircg.ext_declare %2#0 typeparams %2#1 dummy_scope %1 {uniq_name = "_QFtestEstr"} : (!fir.ref<!fir.char<1,?>>, index, !fir.dscope) -> !fir.ref<!fir.char<1,?>> loc(#loc1)
return
} loc(#loc2)
}

#loc1 = loc("test.f90":5:1)
#loc2 = loc("test.f90":15:1)

// CHECK: #[[VAR:.*]] = #llvm.di_local_variable<{{.*}}name = "._QFtestEstr"{{.*}}flags = Artificial>
// CHECK: func.func @test
// CHECK: %[[V1:.*]]:2 = fir.unboxchar{{.*}}
// CHECK: %[[V2:.*]] = fir.convert %[[V1]]#1 : (index) -> i64
// CHECK: llvm.intr.dbg.value #di_local_variable = %[[V2]] : i64
// CHECK: #[[STR_TY:.*]] = #llvm.di_string_type<tag = DW_TAG_string_type, name = "", stringLength = #[[VAR]], encoding = DW_ATE_ASCII>
// CHECK: #llvm.di_local_variable<{{.*}}name = "str"{{.*}}type = #[[STR_TY]]>

0 comments on commit 76347ee

Please sign in to comment.