Skip to content

Commit 76347ee

Browse files
authored
[flang][debug] Improve handling of dummy character arguments. (#108283)
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.
1 parent 9690b30 commit 76347ee

File tree

2 files changed

+48
-2
lines changed

2 files changed

+48
-2
lines changed

flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertCharacterType(
271271
uint64_t sizeInBits = 0;
272272
mlir::LLVM::DIExpressionAttr lenExpr = nullptr;
273273
mlir::LLVM::DIExpressionAttr locExpr = nullptr;
274+
mlir::LLVM::DIVariableAttr varAttr = nullptr;
274275

275276
if (hasDescriptor) {
276277
llvm::SmallVector<mlir::LLVM::DIExpressionElemAttr> ops;
@@ -289,7 +290,29 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertCharacterType(
289290
sizeInBits =
290291
charTy.getLen() * kindMapping.getCharacterBitsize(charTy.getFKind());
291292
} else {
292-
return genPlaceholderType(context);
293+
// In assumed length string, the len of the character is not part of the
294+
// type but can be found at the runtime. Here we create an artificial
295+
// variable that will contain that length. This variable is used as
296+
// 'stringLength' in DIStringTypeAttr.
297+
if (declOp && !declOp.getTypeparams().empty()) {
298+
mlir::Operation *op = declOp.getTypeparams()[0].getDefiningOp();
299+
if (auto unbox = mlir::dyn_cast_or_null<fir::UnboxCharOp>(op)) {
300+
auto name =
301+
mlir::StringAttr::get(context, "." + declOp.getUniqName().str());
302+
mlir::OpBuilder builder(context);
303+
builder.setInsertionPoint(declOp);
304+
mlir::Type i64Ty = builder.getIntegerType(64);
305+
auto convOp = builder.create<fir::ConvertOp>(unbox.getLoc(), i64Ty,
306+
unbox.getResult(1));
307+
mlir::LLVM::DITypeAttr Ty = convertType(i64Ty, fileAttr, scope, declOp);
308+
auto lvAttr = mlir::LLVM::DILocalVariableAttr::get(
309+
context, scope, name, fileAttr, /*line=*/0, /*argNo=*/0,
310+
/*alignInBits=*/0, Ty, mlir::LLVM::DIFlags::Artificial);
311+
builder.create<mlir::LLVM::DbgValueOp>(convOp.getLoc(), convOp, lvAttr,
312+
nullptr);
313+
varAttr = mlir::cast<mlir::LLVM::DIVariableAttr>(lvAttr);
314+
}
315+
}
293316
}
294317

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

305328
mlir::LLVM::DITypeAttr DebugTypeGenerator::convertPointerLikeType(
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s -o - | FileCheck %s
2+
3+
module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
4+
func.func @test(%arg0: !fir.ref<!fir.char<1,?>> {fir.bindc_name = "str"}, %arg1: i64) {
5+
%0 = fir.emboxchar %arg0, %arg1 : (!fir.ref<!fir.char<1,?>>, i64) -> !fir.boxchar<1>
6+
%1 = fir.undefined !fir.dscope
7+
%2:2 = fir.unboxchar %0 : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index) loc(#loc1)
8+
%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)
9+
return
10+
} loc(#loc2)
11+
}
12+
13+
#loc1 = loc("test.f90":5:1)
14+
#loc2 = loc("test.f90":15:1)
15+
16+
// CHECK: #[[VAR:.*]] = #llvm.di_local_variable<{{.*}}name = "._QFtestEstr"{{.*}}flags = Artificial>
17+
// CHECK: func.func @test
18+
// CHECK: %[[V1:.*]]:2 = fir.unboxchar{{.*}}
19+
// CHECK: %[[V2:.*]] = fir.convert %[[V1]]#1 : (index) -> i64
20+
// CHECK: llvm.intr.dbg.value #di_local_variable = %[[V2]] : i64
21+
// CHECK: #[[STR_TY:.*]] = #llvm.di_string_type<tag = DW_TAG_string_type, name = "", stringLength = #[[VAR]], encoding = DW_ATE_ASCII>
22+
// CHECK: #llvm.di_local_variable<{{.*}}name = "str"{{.*}}type = #[[STR_TY]]>
23+

0 commit comments

Comments
 (0)