Skip to content

Commit 5182ae0

Browse files
slinder1jmmartinezepilk
committed
[Dwarf] Support heterogeneous DW_{OP,AT}s needed for AMDGPU CFI
These are defined in the user range until standard versions of them get adopted into dwarf, which is expected in DWARF6. Some of these amount to reservations currently as no code to use them is included. It would be very helpful to get them committed to avoid conflicts necessitating encoding changes while we are in the process of upstreaming. Co-authored-by: Juan Martinez Fernandez <[email protected]> Co-authored-by: Emma Pilkington <[email protected]>
1 parent 21a5729 commit 5182ae0

File tree

10 files changed

+237
-67
lines changed

10 files changed

+237
-67
lines changed

clang/lib/Basic/Targets/AMDGPU.h

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -400,15 +400,12 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo {
400400
/// in the DWARF.
401401
std::optional<unsigned>
402402
getDWARFAddressSpace(unsigned AddressSpace) const override {
403-
const unsigned DWARF_Private = 1;
404-
const unsigned DWARF_Local = 2;
405-
if (AddressSpace == llvm::AMDGPUAS::PRIVATE_ADDRESS) {
406-
return DWARF_Private;
407-
} else if (AddressSpace == llvm::AMDGPUAS::LOCAL_ADDRESS) {
408-
return DWARF_Local;
409-
} else {
403+
int DWARFAS = llvm::AMDGPU::mapToDWARFAddrSpace(AddressSpace);
404+
// If there is no corresponding address space identifier, or it would be
405+
// the default, then don't emit the attribute.
406+
if (DWARFAS == -1 || DWARFAS == llvm::AMDGPU::DWARFAS::DEFAULT)
410407
return std::nullopt;
411-
}
408+
return DWARFAS;
412409
}
413410

414411
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {

clang/test/CodeGenOpenCL/amdgpu-debug-info-pointer-address-space.cl

Lines changed: 33 additions & 32 deletions
Large diffs are not rendered by default.

clang/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -52,31 +52,31 @@ int *constant FileVar14 = 0;
5252

5353
kernel void kernel1(
5454
// CHECK-DAG: ![[KERNELARG0:[0-9]+]] = !DILocalVariable(name: "KernelArg0", arg: {{[0-9]+}}, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
55-
// CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[KERNELARG0]], !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}}
55+
// CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[KERNELARG0]], !DIExpression(DW_OP_constu, 5, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}}
5656
global int *KernelArg0,
5757
// CHECK-DAG: ![[KERNELARG1:[0-9]+]] = !DILocalVariable(name: "KernelArg1", arg: {{[0-9]+}}, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
58-
// CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[KERNELARG1]], !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}}
58+
// CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[KERNELARG1]], !DIExpression(DW_OP_constu, 5, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}}
5959
constant int *KernelArg1,
6060
// CHECK-DAG: ![[KERNELARG2:[0-9]+]] = !DILocalVariable(name: "KernelArg2", arg: {{[0-9]+}}, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
61-
// CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[KERNELARG2]], !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}}
61+
// CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[KERNELARG2]], !DIExpression(DW_OP_constu, 5, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}}
6262
local int *KernelArg2) {
6363
private int *Tmp0;
6464
int *Tmp1;
6565

6666
// CHECK-DAG: ![[FUNCVAR0:[0-9]+]] = !DILocalVariable(name: "FuncVar0", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
67-
// CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR0]], !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}}
67+
// CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR0]], !DIExpression(DW_OP_constu, 5, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}}
6868
global int *FuncVar0 = KernelArg0;
6969
// CHECK-DAG: ![[FUNCVAR1:[0-9]+]] = !DILocalVariable(name: "FuncVar1", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
70-
// CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR1]], !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}}
70+
// CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR1]], !DIExpression(DW_OP_constu, 5, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}}
7171
constant int *FuncVar1 = KernelArg1;
7272
// CHECK-DAG: ![[FUNCVAR2:[0-9]+]] = !DILocalVariable(name: "FuncVar2", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
73-
// CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR2]], !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}}
73+
// CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR2]], !DIExpression(DW_OP_constu, 5, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}}
7474
local int *FuncVar2 = KernelArg2;
7575
// CHECK-DAG: ![[FUNCVAR3:[0-9]+]] = !DILocalVariable(name: "FuncVar3", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
76-
// CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR3]], !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}}
76+
// CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR3]], !DIExpression(DW_OP_constu, 5, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}}
7777
private int *FuncVar3 = Tmp0;
7878
// CHECK-DAG: ![[FUNCVAR4:[0-9]+]] = !DILocalVariable(name: "FuncVar4", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
79-
// CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR4]], !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}}
79+
// CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR4]], !DIExpression(DW_OP_constu, 5, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}}
8080
int *FuncVar4 = Tmp1;
8181

8282
// CHECK-DAG: ![[FUNCVAR5:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar5", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
@@ -96,34 +96,34 @@ kernel void kernel1(
9696
int *constant FuncVar9 = 0;
9797

9898
// CHECK-DAG: ![[FUNCVAR10:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar10", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
99-
// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR10]], expr: !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef))
99+
// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR10]], expr: !DIExpression(DW_OP_constu, 3, DW_OP_swap, DW_OP_xderef))
100100
global int *local FuncVar10; FuncVar10 = KernelArg0;
101101
// CHECK-DAG: ![[FUNCVAR11:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar11", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
102-
// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR11]], expr: !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef))
102+
// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR11]], expr: !DIExpression(DW_OP_constu, 3, DW_OP_swap, DW_OP_xderef))
103103
constant int *local FuncVar11; FuncVar11 = KernelArg1;
104104
// CHECK-DAG: ![[FUNCVAR12:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar12", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
105-
// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR12]], expr: !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef))
105+
// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR12]], expr: !DIExpression(DW_OP_constu, 3, DW_OP_swap, DW_OP_xderef))
106106
local int *local FuncVar12; FuncVar12 = KernelArg2;
107107
// CHECK-DAG: ![[FUNCVAR13:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar13", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
108-
// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR13]], expr: !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef))
108+
// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR13]], expr: !DIExpression(DW_OP_constu, 3, DW_OP_swap, DW_OP_xderef))
109109
private int *local FuncVar13; FuncVar13 = Tmp0;
110110
// CHECK-DAG: ![[FUNCVAR14:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar14", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
111-
// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR14]], expr: !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef))
111+
// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR14]], expr: !DIExpression(DW_OP_constu, 3, DW_OP_swap, DW_OP_xderef))
112112
int *local FuncVar14; FuncVar14 = Tmp1;
113113

114114
// CHECK-DAG: ![[FUNCVAR15:[0-9]+]] = !DILocalVariable(name: "FuncVar15", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
115-
// CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR15]], !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}}
115+
// CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR15]], !DIExpression(DW_OP_constu, 5, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}}
116116
global int *private FuncVar15 = KernelArg0;
117117
// CHECK-DAG: ![[FUNCVAR16:[0-9]+]] = !DILocalVariable(name: "FuncVar16", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
118-
// CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR16]], !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}}
118+
// CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR16]], !DIExpression(DW_OP_constu, 5, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}}
119119
constant int *private FuncVar16 = KernelArg1;
120120
// CHECK-DAG: ![[FUNCVAR17:[0-9]+]] = !DILocalVariable(name: "FuncVar17", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
121-
// CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR17]], !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}}
121+
// CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR17]], !DIExpression(DW_OP_constu, 5, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}}
122122
local int *private FuncVar17 = KernelArg2;
123123
// CHECK-DAG: ![[FUNCVAR18:[0-9]+]] = !DILocalVariable(name: "FuncVar18", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
124-
// CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR18]], !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}}
124+
// CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR18]], !DIExpression(DW_OP_constu, 5, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}}
125125
private int *private FuncVar18 = Tmp0;
126126
// CHECK-DAG: ![[FUNCVAR19:[0-9]+]] = !DILocalVariable(name: "FuncVar19", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
127-
// CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR19]], !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}}
127+
// CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR19]], !DIExpression(DW_OP_constu, 5, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}}
128128
int *private FuncVar19 = Tmp1;
129129
}

llvm/include/llvm/BinaryFormat/Dwarf.def

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525
defined HANDLE_DW_APPLE_PROPERTY || defined HANDLE_DW_UT || \
2626
defined HANDLE_DWARF_SECTION || defined HANDLE_DW_IDX || \
2727
defined HANDLE_DW_END || defined HANDLE_DW_SECT || \
28-
defined HANDLE_DW_APPLE_ENUM_KIND)
28+
defined HANDLE_DW_APPLE_ENUM_KIND || \
29+
( defined HANDLE_DW_ASPACE && defined HANDLE_DW_ASPACE_PRED) )
2930
#error "Missing macro definition of HANDLE_DW*"
3031
#endif
3132

@@ -151,6 +152,14 @@
151152
#define HANDLE_DW_APPLE_ENUM_KIND(ID, NAME)
152153
#endif
153154

155+
#ifndef HANDLE_DW_ASPACE
156+
#define HANDLE_DW_ASPACE(ID, NAME)
157+
#endif
158+
159+
#ifndef HANDLE_DW_ASPACE_PRED
160+
#define HANDLE_DW_ASPACE_PRED(ID, NAME, PRED)
161+
#endif
162+
154163
HANDLE_DW_TAG(0x0000, null, 2, DWARF, DW_KIND_NONE)
155164
HANDLE_DW_TAG(0x0001, array_type, 2, DWARF, DW_KIND_TYPE)
156165
HANDLE_DW_TAG(0x0002, class_type, 2, DWARF, DW_KIND_TYPE)
@@ -628,6 +637,21 @@ HANDLE_DW_AT(0x3e0d, LLVM_coro_suspend_idx, 0, LLVM)
628637
// The DWARF v6 working draft defines DW_AT_alloc_type; use this LLVM-private ID
629638
// until that is released as an official standard.
630639
HANDLE_DW_AT(0x3e0e, LLVM_alloc_type, 0, LLVM)
640+
// Heterogeneous Debugging Extension defined at
641+
// https://llvm.org/docs/AMDGPUDwarfProposalForHeterogeneousDebugging.html.
642+
HANDLE_DW_AT(0x3e0f, LLVM_memory_space, 0, LLVM)
643+
HANDLE_DW_AT(0x3e10, LLVM_address_space, 0, LLVM)
644+
HANDLE_DW_AT(0x3e11, LLVM_lanes, 0, LLVM)
645+
HANDLE_DW_AT(0x3e12, LLVM_lane_pc, 0, LLVM)
646+
HANDLE_DW_AT(0x3e13, LLVM_vector_size, 0, LLVM)
647+
648+
// https://llvm.org/docs/AMDGPUUsage.html#address-space-identifier
649+
HANDLE_DW_ASPACE(0x0, none)
650+
HANDLE_DW_ASPACE_PRED(AMDGPU::DWARFAS::GENERIC, AMDGPU_generic, SELECT_AMDGPU)
651+
HANDLE_DW_ASPACE_PRED(AMDGPU::DWARFAS::REGION, AMDGPU_region, SELECT_AMDGPU)
652+
HANDLE_DW_ASPACE_PRED(AMDGPU::DWARFAS::LOCAL, AMDGPU_local, SELECT_AMDGPU)
653+
HANDLE_DW_ASPACE_PRED(AMDGPU::DWARFAS::PRIVATE_LANE, AMDGPU_private_lane, SELECT_AMDGPU)
654+
HANDLE_DW_ASPACE_PRED(AMDGPU::DWARFAS::PRIVATE_WAVE, AMDGPU_private_wave, SELECT_AMDGPU)
631655

632656
// Apple extensions.
633657

@@ -916,6 +940,19 @@ HANDLE_DW_OP(0xe9, LLVM_user, -1, -1, 0, LLVM)
916940
// location stack or any of its values. It is defined as a placeholder for
917941
// testing purposes.
918942
HANDLE_DW_OP_LLVM_USEROP(0x0001, nop)
943+
// Heterogeneous Debugging Extension defined at
944+
// https://llvm.org/docs/AMDGPUDwarfProposalForHeterogeneousDebugging.html.
945+
HANDLE_DW_OP_LLVM_USEROP(0x0002, form_aspace_address)
946+
HANDLE_DW_OP_LLVM_USEROP(0x0003, push_lane)
947+
HANDLE_DW_OP_LLVM_USEROP(0x0004, offset)
948+
HANDLE_DW_OP_LLVM_USEROP(0x0005, offset_uconst)
949+
HANDLE_DW_OP_LLVM_USEROP(0x0006, bit_offset)
950+
HANDLE_DW_OP_LLVM_USEROP(0x0007, call_frame_entry_reg)
951+
HANDLE_DW_OP_LLVM_USEROP(0x0008, undefined)
952+
HANDLE_DW_OP_LLVM_USEROP(0x0009, aspace_bregx)
953+
HANDLE_DW_OP_LLVM_USEROP(0x000a, piece_end)
954+
HANDLE_DW_OP_LLVM_USEROP(0x000b, extend)
955+
HANDLE_DW_OP_LLVM_USEROP(0x000c, select_bit_piece)
919956

920957
// DWARF languages.
921958
HANDLE_DW_LANG(0x0001, C89, 0, 2, DWARF)
@@ -1385,3 +1422,5 @@ HANDLE_DW_SECT(8, RNGLISTS)
13851422
#undef HANDLE_DW_END
13861423
#undef HANDLE_DW_SECT
13871424
#undef HANDLE_DW_APPLE_ENUM_KIND
1425+
#undef HANDLE_DW_ASPACE
1426+
#undef HANDLE_DW_ASPACE_PRED

llvm/include/llvm/BinaryFormat/Dwarf.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#ifndef LLVM_BINARYFORMAT_DWARF_H
2020
#define LLVM_BINARYFORMAT_DWARF_H
2121

22+
#include "llvm/Support/AMDGPUAddrSpace.h"
2223
#include "llvm/Support/Compiler.h"
2324
#include "llvm/Support/DataTypes.h"
2425
#include "llvm/Support/ErrorHandling.h"
@@ -757,6 +758,12 @@ enum CallingConvention {
757758
DW_CC_hi_user = 0xff
758759
};
759760

761+
enum AddressSpace {
762+
#define HANDLE_DW_ASPACE(ID, NAME) DW_ASPACE_LLVM_##NAME = ID,
763+
#define HANDLE_DW_ASPACE_PRED(ID, NAME, PRED) DW_ASPACE_LLVM_##NAME = ID,
764+
#include "llvm/BinaryFormat/Dwarf.def"
765+
};
766+
760767
enum InlineAttribute {
761768
// Inline codes
762769
DW_INL_not_inlined = 0x00,
@@ -1011,6 +1018,7 @@ LLVM_ABI StringRef IndexString(unsigned Idx);
10111018
LLVM_ABI StringRef FormatString(DwarfFormat Format);
10121019
LLVM_ABI StringRef FormatString(bool IsDWARF64);
10131020
LLVM_ABI StringRef RLEString(unsigned RLE);
1021+
LLVM_ABI StringRef AddressSpaceString(unsigned AS, llvm::Triple TT);
10141022
/// @}
10151023

10161024
/// \defgroup DwarfConstantsParsing Dwarf constants parsing functions

llvm/include/llvm/Support/AMDGPUAddrSpace.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,46 @@ inline bool isConstantAddressSpace(unsigned AS) {
120120
return false;
121121
}
122122
}
123+
124+
namespace DWARFAS {
125+
enum : unsigned {
126+
GLOBAL = 0,
127+
GENERIC = 1,
128+
REGION = 2,
129+
LOCAL = 3,
130+
PRIVATE_LANE = 5,
131+
PRIVATE_WAVE = 6,
132+
DEFAULT = GLOBAL,
133+
};
134+
} // namespace DWARFAS
135+
136+
/// If @p LLVMAddressSpace has a corresponding DWARF encoding,
137+
/// return it; otherwise return the sentinel value -1 to indicate
138+
/// no such mapping exists.
139+
///
140+
/// This maps private/scratch to the focused lane view.
141+
///
142+
/// These mappings must be kept in sync with llvm/docs/AMDGPUUsage.rst
143+
/// table "AMDGPU DWARF Address Space Mapping".
144+
///
145+
/// Note: This could return std::optional<int> but that would require
146+
/// an extra #include.
147+
inline int mapToDWARFAddrSpace(unsigned LLVMAddrSpace) {
148+
static constexpr unsigned LLVMToDWARFAddrSpaceMapping[] = {
149+
DWARFAS::GENERIC, //< AMDGPUAS::FLAT_ADDRESS
150+
DWARFAS::GLOBAL, //< AMDGPUAS::GLOBAL_ADDRESS
151+
DWARFAS::REGION, //< AMDGPUAS::REGION_ADDRESS
152+
DWARFAS::LOCAL, //< AMDGPUAS::LOCAL_ADDRESS
153+
DWARFAS::GLOBAL, //< AMDGPUAS::CONSTANT_ADDRESS
154+
DWARFAS::PRIVATE_LANE //< AMDGPUAS::PRIVATE_ADDRESS
155+
};
156+
static constexpr unsigned SizeOfLLVMToDWARFAddrSpaceMapping =
157+
sizeof(LLVMToDWARFAddrSpaceMapping) /
158+
sizeof(LLVMToDWARFAddrSpaceMapping[0]);
159+
if (LLVMAddrSpace < SizeOfLLVMToDWARFAddrSpaceMapping)
160+
return LLVMToDWARFAddrSpaceMapping[LLVMAddrSpace];
161+
return -1;
162+
}
123163
} // end namespace AMDGPU
124164

125165
} // end namespace llvm

llvm/lib/BinaryFormat/Dwarf.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -911,6 +911,27 @@ StringRef llvm::dwarf::RLEString(unsigned RLE) {
911911
}
912912
}
913913

914+
StringRef llvm::dwarf::AddressSpaceString(unsigned AS, llvm::Triple TT) {
915+
switch (AS) {
916+
#define HANDLE_DW_ASPACE(ID, NAME) \
917+
case DW_ASPACE_LLVM_##NAME: \
918+
return "DW_ASPACE_LLVM_" #NAME;
919+
#define HANDLE_DW_ASPACE_PRED(ID, NAME, PRED)
920+
#include "llvm/BinaryFormat/Dwarf.def"
921+
default:
922+
break;
923+
}
924+
925+
bool SELECT_AMDGPU = TT.isAMDGPU();
926+
#define HANDLE_DW_ASPACE(ID, NAME)
927+
#define HANDLE_DW_ASPACE_PRED(ID, NAME, PRED) \
928+
if (DW_ASPACE_LLVM_##NAME == AS && PRED) \
929+
return "DW_ASPACE_LLVM_" #NAME;
930+
#include "llvm/BinaryFormat/Dwarf.def"
931+
932+
return "";
933+
}
934+
914935
StringRef (*const llvm::dwarf::EnumTraits<Tag>::StringFn)(unsigned) = TagString;
915936
StringRef (*const llvm::dwarf::EnumTraits<Attribute>::StringFn)(unsigned) =
916937
AttributeString;

llvm/lib/DebugInfo/DWARF/DWARFExpressionPrinter.cpp

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,19 @@ static bool printOp(const DWARFExpression::Operation *Op, raw_ostream &OS,
5656
assert(!Name.empty() && "DW_OP has no name!");
5757
OS << Name;
5858

59+
std::optional<unsigned> SubOpcode = Op->getSubCode();
60+
if (SubOpcode) {
61+
StringRef SubName = SubOperationEncodingString(Op->getCode(), *SubOpcode);
62+
assert(!SubName.empty() && "DW_OP SubOp has no name!");
63+
OS << " " << SubName;
64+
}
65+
5966
if ((Op->getCode() >= DW_OP_breg0 && Op->getCode() <= DW_OP_breg31) ||
6067
(Op->getCode() >= DW_OP_reg0 && Op->getCode() <= DW_OP_reg31) ||
6168
Op->getCode() == DW_OP_bregx || Op->getCode() == DW_OP_regx ||
62-
Op->getCode() == DW_OP_regval_type)
69+
Op->getCode() == DW_OP_regval_type ||
70+
(SubOpcode && (*SubOpcode == DW_OP_LLVM_call_frame_entry_reg ||
71+
*SubOpcode == DW_OP_LLVM_aspace_bregx)))
6372
if (prettyPrintRegisterOp(U, OS, DumpOpts, Op->getCode(),
6473
Op->getRawOperands()))
6574
return true;
@@ -70,10 +79,8 @@ static bool printOp(const DWARFExpression::Operation *Op, raw_ostream &OS,
7079
unsigned Signed = Size & DWARFExpression::Operation::SignBit;
7180

7281
if (Size == DWARFExpression::Operation::SizeSubOpLEB) {
73-
StringRef SubName =
74-
SubOperationEncodingString(Op->getCode(), Op->getRawOperand(Operand));
75-
assert(!SubName.empty() && "DW_OP SubOp has no name!");
76-
OS << " " << SubName;
82+
assert(Operand == 0);
83+
assert(SubOpcode);
7784
} else if (Size == DWARFExpression::Operation::BaseTypeRef && U) {
7885
// For DW_OP_convert the operand may be 0 to indicate that conversion to
7986
// the generic type should be done. The same holds for DW_OP_reinterpret,
@@ -219,7 +226,7 @@ static bool printCompactDWARFExpr(
219226
break;
220227
}
221228
case dwarf::DW_OP_LLVM_user: {
222-
assert(Op.getSubCode() == dwarf::DW_OP_LLVM_nop);
229+
assert(Op.getSubCode());
223230
break;
224231
}
225232
default:
@@ -283,8 +290,14 @@ bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS,
283290
uint64_t DwarfRegNum;
284291
unsigned OpNum = 0;
285292

293+
std::optional<unsigned> SubOpcode;
294+
if (Opcode == DW_OP_LLVM_user)
295+
SubOpcode = Operands[OpNum++];
296+
286297
if (Opcode == DW_OP_bregx || Opcode == DW_OP_regx ||
287-
Opcode == DW_OP_regval_type)
298+
Opcode == DW_OP_regval_type ||
299+
(SubOpcode && (*SubOpcode == DW_OP_LLVM_aspace_bregx ||
300+
*SubOpcode == DW_OP_LLVM_call_frame_entry_reg)))
288301
DwarfRegNum = Operands[OpNum++];
289302
else if (Opcode >= DW_OP_breg0 && Opcode < DW_OP_bregx)
290303
DwarfRegNum = Opcode - DW_OP_breg0;
@@ -294,7 +307,8 @@ bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS,
294307
auto RegName = DumpOpts.GetNameForDWARFReg(DwarfRegNum, DumpOpts.IsEH);
295308
if (!RegName.empty()) {
296309
if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) ||
297-
Opcode == DW_OP_bregx)
310+
Opcode == DW_OP_bregx ||
311+
(SubOpcode && *SubOpcode == DW_OP_LLVM_aspace_bregx))
298312
OS << ' ' << RegName << format("%+" PRId64, Operands[OpNum]);
299313
else
300314
OS << ' ' << RegName.data();

0 commit comments

Comments
 (0)