[llvm] [NVPTX] Fix DWARF address space for globals (PR #122715)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 13 06:43:55 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-nvptx
Author: Alexander Peskov (apeskov)
<details>
<summary>Changes</summary>
Fix an issue with defining actual DWARF address space for module scope globals. Previously it was always `ADDR_global_space`.
Also, this patch introduces CUDA-specific DWARF codes for address space specification in correspondence with:
https://docs.nvidia.com/cuda/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf-definitions
Previously hardcoded constant values are replaced with enum values.
---
Full diff: https://github.com/llvm/llvm-project/pull/122715.diff
3 Files Affected:
- (modified) llvm/include/llvm/Support/NVPTXAddrSpace.h (+24-1)
- (modified) llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp (+39-30)
- (added) llvm/test/DebugInfo/NVPTX/debug-addr-space.ll (+25)
``````````diff
diff --git a/llvm/include/llvm/Support/NVPTXAddrSpace.h b/llvm/include/llvm/Support/NVPTXAddrSpace.h
index 93eae39e3d2305..fc8ae7c37793b6 100644
--- a/llvm/include/llvm/Support/NVPTXAddrSpace.h
+++ b/llvm/include/llvm/Support/NVPTXAddrSpace.h
@@ -17,6 +17,7 @@
namespace llvm {
namespace NVPTXAS {
+
enum AddressSpace : unsigned {
ADDRESS_SPACE_GENERIC = 0,
ADDRESS_SPACE_GLOBAL = 1,
@@ -26,8 +27,30 @@ enum AddressSpace : unsigned {
ADDRESS_SPACE_PARAM = 101,
};
-} // end namespace NVPTXAS
+// According to official PTX Writer's Guide, DWARF debug information should
+// contain DW_AT_address_class attribute for all variables and parameters.
+// It's required for cuda-gdb to be able to properly reflect the memory space
+// of variable address. Acceptable address class codes are listed in this enum.
+//
+// More detailed information:
+// https://docs.nvidia.com/cuda/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf-definitions
+enum DWARF_AddressSpace : unsigned {
+ DWARF_ADDR_code_space = 1,
+ DWARF_ADDR_reg_space = 2,
+ DWARF_ADDR_sreg_space = 3,
+ DWARF_ADDR_const_space = 4,
+ DWARF_ADDR_global_space = 5,
+ DWARF_ADDR_local_space = 6,
+ DWARF_ADDR_param_space = 7,
+ DWARF_ADDR_shared_space = 8,
+ DWARF_ADDR_surf_space = 9,
+ DWARF_ADDR_tex_space = 10,
+ DWARF_ADDR_tex_sampler_space = 11,
+ DWARF_ADDR_generic_space = 12
+};
+
+} // end namespace NVPTXAS
} // end namespace llvm
#endif // LLVM_SUPPORT_NVPTXADDRSPACE_H
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index 2f96366b78e97d..f87c43e28003a3 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -33,6 +33,7 @@
#include "llvm/MC/MCSymbolWasm.h"
#include "llvm/MC/MachineLocation.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/NVPTXAddrSpace.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
@@ -75,6 +76,25 @@ static dwarf::Tag GetCompileUnitType(UnitKind Kind, DwarfDebug *DW) {
return dwarf::DW_TAG_compile_unit;
}
+static unsigned translateToNVVMDWARFAddrSpace(unsigned AddrSpace) {
+ switch (AddrSpace) {
+ case NVPTXAS::ADDRESS_SPACE_GENERIC:
+ return NVPTXAS::DWARF_ADDR_generic_space;
+ case NVPTXAS::ADDRESS_SPACE_GLOBAL:
+ return NVPTXAS::DWARF_ADDR_global_space;
+ case NVPTXAS::ADDRESS_SPACE_SHARED:
+ return NVPTXAS::DWARF_ADDR_shared_space;
+ case NVPTXAS::ADDRESS_SPACE_CONST:
+ return NVPTXAS::DWARF_ADDR_const_space;
+ case NVPTXAS::ADDRESS_SPACE_LOCAL:
+ return NVPTXAS::DWARF_ADDR_local_space;
+ default:
+ llvm_unreachable(
+ "Cannot translate unknown address space to DWARF address space");
+ return AddrSpace;
+ }
+}
+
DwarfCompileUnit::DwarfCompileUnit(unsigned UID, const DICompileUnit *Node,
AsmPrinter *A, DwarfDebug *DW,
DwarfFile *DWU, UnitKind Kind)
@@ -264,14 +284,11 @@ void DwarfCompileUnit::addLocationAttribute(
}
if (Expr) {
- // According to
- // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf
- // cuda-gdb requires DW_AT_address_class for all variables to be able to
- // correctly interpret address space of the variable address.
+ // cuda-gdb special requirement. See NVPTXAS::DWARF_AddressSpace
// Decode DW_OP_constu <DWARF Address Space> DW_OP_swap DW_OP_xderef
- // sequence for the NVPTX + gdb target.
- unsigned LocalNVPTXAddressSpace;
+ // sequence to specify corresponding address space.
if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {
+ unsigned LocalNVPTXAddressSpace;
const DIExpression *NewExpr =
DIExpression::extractAddressClass(Expr, LocalNVPTXAddressSpace);
if (NewExpr != Expr) {
@@ -363,6 +380,10 @@ void DwarfCompileUnit::addLocationAttribute(
DD->addArangeLabel(SymbolCU(this, Sym));
addOpAddress(*Loc, Sym);
}
+ if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB() &&
+ !NVPTXAddressSpace)
+ NVPTXAddressSpace = translateToNVVMDWARFAddrSpace(
+ Global->getType()->getAddressSpace());
}
// Global variables attached to symbols are memory locations.
// It would be better if this were unconditional, but malformed input that
@@ -373,13 +394,9 @@ void DwarfCompileUnit::addLocationAttribute(
DwarfExpr->addExpression(Expr);
}
if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {
- // According to
- // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf
- // cuda-gdb requires DW_AT_address_class for all variables to be able to
- // correctly interpret address space of the variable address.
- const unsigned NVPTX_ADDR_global_space = 5;
+ // cuda-gdb special requirement. See NVPTXAS::DWARF_AddressSpace
addUInt(*VariableDIE, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1,
- NVPTXAddressSpace.value_or(NVPTX_ADDR_global_space));
+ NVPTXAddressSpace.value_or(NVPTXAS::DWARF_ADDR_global_space));
}
if (Loc)
addBlock(*VariableDIE, dwarf::DW_AT_location, DwarfExpr->finalize());
@@ -793,10 +810,10 @@ void DwarfCompileUnit::applyConcreteDbgVariableAttributes(
const DbgValueLoc *DVal = &Single.getValueLoc();
if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB() &&
!Single.getExpr()) {
- // Lack of expression means it is a register. Registers for PTX need to
- // be marked with DW_AT_address_class = 2. See
- // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf
- addUInt(VariableDie, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1, 2);
+ // cuda-gdb special requirement. See NVPTXAS::DWARF_AddressSpace
+ // Lack of expression means it is a register.
+ addUInt(VariableDie, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1,
+ NVPTXAS::DWARF_ADDR_reg_space);
}
if (!DVal->isVariadic()) {
const DbgValueLocEntry *Entry = DVal->getLocEntries().begin();
@@ -922,14 +939,11 @@ void DwarfCompileUnit::applyConcreteDbgVariableAttributes(const Loc::MMI &MMI,
SmallVector<uint64_t, 8> Ops;
TRI->getOffsetOpcodes(Offset, Ops);
- // According to
- // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf
- // cuda-gdb requires DW_AT_address_class for all variables to be
- // able to correctly interpret address space of the variable
- // address. Decode DW_OP_constu <DWARF Address Space> DW_OP_swap
- // DW_OP_xderef sequence for the NVPTX + gdb target.
- unsigned LocalNVPTXAddressSpace;
+ // cuda-gdb special requirement. See NVPTXAS::DWARF_AddressSpace.
+ // Decode DW_OP_constu <DWARF Address Space> DW_OP_swap
+ // DW_OP_xderef sequence to specify address space.
if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {
+ unsigned LocalNVPTXAddressSpace;
const DIExpression *NewExpr =
DIExpression::extractAddressClass(Expr, LocalNVPTXAddressSpace);
if (NewExpr != Expr) {
@@ -949,14 +963,9 @@ void DwarfCompileUnit::applyConcreteDbgVariableAttributes(const Loc::MMI &MMI,
DwarfExpr.addExpression(std::move(Cursor));
}
if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {
- // According to
- // https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf
- // cuda-gdb requires DW_AT_address_class for all variables to be
- // able to correctly interpret address space of the variable
- // address.
- const unsigned NVPTX_ADDR_local_space = 6;
+ // cuda-gdb special requirement. See NVPTXAS::DWARF_AddressSpace.
addUInt(VariableDie, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1,
- NVPTXAddressSpace.value_or(NVPTX_ADDR_local_space));
+ NVPTXAddressSpace.value_or(NVPTXAS::DWARF_ADDR_local_space));
}
addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
if (DwarfExpr.TagOffset)
diff --git a/llvm/test/DebugInfo/NVPTX/debug-addr-space.ll b/llvm/test/DebugInfo/NVPTX/debug-addr-space.ll
new file mode 100644
index 00000000000000..1bde05c77147e2
--- /dev/null
+++ b/llvm/test/DebugInfo/NVPTX/debug-addr-space.ll
@@ -0,0 +1,25 @@
+; RUN: llc < %s -march=nvptx64 | FileCheck %s
+
+; Test that translateToNVVMDWARFAddrSpace() function translates NVVM IR address space
+; value `Shared` (3) to the corresponding DWARF DW_AT_address_class attributeĀ for PTX.
+
+; CHECK: .section .debug_info
+; CHECK: .b8 103 // DW_AT_name
+; CHECK-NEXT: .b8 0
+; CHECK-NEXT: .b32 55 // DW_AT_type
+; CHECK-NEXT: .b8 1 // DW_AT_decl_file
+; CHECK-NEXT: .b8 1 // DW_AT_decl_line
+; CHECK-NEXT: .b8 8 // DW_AT_address_class
+
+ at g = internal addrspace(3) global i32 0, align 4, !dbg !0
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!6}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "g", linkageName: "g", scope: !2, file: !3, line: 1, type: !5, isLocal: true, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4)
+!3 = !DIFile(filename: "test.cu", directory: "test")
+!4 = !{!0}
+!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!6 = !{i32 1, !"Debug Info Version", i32 3}
``````````
</details>
https://github.com/llvm/llvm-project/pull/122715
More information about the llvm-commits
mailing list