From 79a1e32915631469b4ea50c0e00ccd7ecc828d00 Mon Sep 17 00:00:00 2001 From: Felipe de Azevedo Piovezan Date: Tue, 4 Apr 2023 09:35:23 -0400 Subject: [PATCH] [GlobalISel] Improve stack slot tracking in dbg.values For IR like: ``` %alloca = alloca ... dbg.value(%alloca, !myvar, OP_deref()) ``` GlobalISel lowers it to MIR: ``` %some_reg = G_FRAME_INDEX DBG_VALUE %some_reg, !myvar, OP_deref() ``` In other words, if the value of `!myvar` can be obtained by dereferencing an alloca, in MIR we say that the _location_ of a variable is obtained by dereferencing register %some_reg (plus some ``). We can instead remove the use of `%some_reg`: the location of `!myvar` _is_ `` (plus some ``). This patch implements this transformation, which improves debug information handling in O0, as these registers hardly ever survive register allocation. A note about testing: similar to what was done in D76934 (f24e2e9eebde4b7a1d), this patch exposed a bug in the Builder class when using `-debug`, where we tried to print an incomplete instruction. The changes in `MachineIRBuilder.cpp` address that. Differential Revision: https://reviews.llvm.org/D147536 --- llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 11 +++++++++++ llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp | 10 +++++----- llvm/test/CodeGen/AArch64/GlobalISel/debug-insts.ll | 5 ++++- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index 3df8325..50d2b21 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -1993,6 +1993,17 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID, MIRBuilder.buildIndirectDbgValue(0, DI.getVariable(), DI.getExpression()); } else if (const auto *CI = dyn_cast(V)) { MIRBuilder.buildConstDbgValue(*CI, DI.getVariable(), DI.getExpression()); + } else if (auto *AI = dyn_cast(V); + AI && AI->isStaticAlloca() && + DI.getExpression()->startsWithDeref()) { + // If the value is an alloca and the expression starts with a + // dereference, track a stack slot instead of a register, as registers + // may be clobbered. + auto ExprOperands = DI.getExpression()->getElements(); + auto *ExprDerefRemoved = + DIExpression::get(AI->getContext(), ExprOperands.drop_front()); + MIRBuilder.buildFIDbgValue(getOrCreateFrameIndex(*AI), DI.getVariable(), + ExprDerefRemoved); } else { for (Register Reg : getOrCreateVRegs(*V)) { // FIXME: This does not handle register-indirect values at offset 0. The diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp index c26f737..d64a20b 100644 --- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp +++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp @@ -80,11 +80,11 @@ MachineInstrBuilder MachineIRBuilder::buildFIDbgValue(int FI, assert( cast(Variable)->isValidLocationForIntrinsic(getDL()) && "Expected inlined-at fields to agree"); - return buildInstr(TargetOpcode::DBG_VALUE) - .addFrameIndex(FI) - .addImm(0) - .addMetadata(Variable) - .addMetadata(Expr); + return insertInstr(buildInstrNoInsert(TargetOpcode::DBG_VALUE) + .addFrameIndex(FI) + .addImm(0) + .addMetadata(Variable) + .addMetadata(Expr)); } MachineInstrBuilder MachineIRBuilder::buildConstDbgValue(const Constant &C, diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/debug-insts.ll b/llvm/test/CodeGen/AArch64/GlobalISel/debug-insts.ll index fbfa119..47ddca8 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/debug-insts.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/debug-insts.ll @@ -28,13 +28,16 @@ entry: @gv = global i32 zeroinitializer ; CHECK-LABEL: name: debug_value +; CHECK: stack: +; CHECK: - { id: {{.*}}, name: addr ; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $w0 define void @debug_value(i32 %in) #0 !dbg !16 { +; CHECK: G_FRAME_INDEX %[[stack_slot:.*]] %addr = alloca i32 ; CHECK: DBG_VALUE [[IN]](s32), $noreg, !17, !DIExpression(), debug-location !18 call void @llvm.dbg.value(metadata i32 %in, i64 0, metadata !17, metadata !DIExpression()), !dbg !18 store i32 %in, ptr %addr -; CHECK: DBG_VALUE %1(p0), $noreg, !17, !DIExpression(DW_OP_deref), debug-location !18 +; CHECK: DBG_VALUE %[[stack_slot]], 0, !17, !DIExpression(), debug-location !18 call void @llvm.dbg.value(metadata ptr %addr, i64 0, metadata !17, metadata !DIExpression(DW_OP_deref)), !dbg !18 ; CHECK: DBG_VALUE 123, 0, !17, !DIExpression(), debug-location !18 call void @llvm.dbg.value(metadata i32 123, i64 0, metadata !17, metadata !DIExpression()), !dbg !18 -- 2.7.4