Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion llvm/include/llvm/Support/NVPTXAddrSpace.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

namespace llvm {
namespace NVPTXAS {

enum AddressSpace : unsigned {
ADDRESS_SPACE_GENERIC = 0,
ADDRESS_SPACE_GLOBAL = 1,
Expand All @@ -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
69 changes: 39 additions & 30 deletions llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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
Expand All @@ -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());
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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) {
Expand All @@ -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)
Expand Down
25 changes: 25 additions & 0 deletions llvm/test/DebugInfo/NVPTX/debug-addr-space.ll
Original file line number Diff line number Diff line change
@@ -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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this correct, maybe 8, not 3?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is correct. The task is to translate addrspace(3) which means ADDRESS_SPACE_SHARED = 3 to DWARF value DWARF_ADDR_shared_space = 8. So the conversion 3 -> 8.


; 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

@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}
Loading