diff --git a/clang/lib/Basic/Targets/AMDGPU.h b/clang/lib/Basic/Targets/AMDGPU.h index 8b7fab3d439e0..552698a680d3e 100644 --- a/clang/lib/Basic/Targets/AMDGPU.h +++ b/clang/lib/Basic/Targets/AMDGPU.h @@ -400,15 +400,12 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo { /// in the DWARF. std::optional getDWARFAddressSpace(unsigned AddressSpace) const override { - const unsigned DWARF_Private = 1; - const unsigned DWARF_Local = 2; - if (AddressSpace == llvm::AMDGPUAS::PRIVATE_ADDRESS) { - return DWARF_Private; - } else if (AddressSpace == llvm::AMDGPUAS::LOCAL_ADDRESS) { - return DWARF_Local; - } else { + int DWARFAS = llvm::AMDGPU::mapToDWARFAddrSpace(AddressSpace); + // If there is no corresponding address space identifier, or it would be + // the default, then don't emit the attribute. + if (DWARFAS == -1 || DWARFAS == llvm::AMDGPU::DWARFAS::DEFAULT) return std::nullopt; - } + return DWARFAS; } CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { diff --git a/clang/test/CodeGenOpenCL/amdgpu-debug-info-pointer-address-space.cl b/clang/test/CodeGenOpenCL/amdgpu-debug-info-pointer-address-space.cl index ab625f3154b20..e6a783fff4bc5 100644 --- a/clang/test/CodeGenOpenCL/amdgpu-debug-info-pointer-address-space.cl +++ b/clang/test/CodeGenOpenCL/amdgpu-debug-info-pointer-address-space.cl @@ -2,122 +2,123 @@ // RUN: %clang -cl-std=CL2.0 -emit-llvm -g -O0 -S -nogpulib -target amdgcn-amd-amdhsa -mcpu=fiji -o - %s | FileCheck %s // RUN: %clang -cl-std=CL2.0 -emit-llvm -g -O0 -S -nogpulib -target amdgcn-amd-amdhsa-opencl -mcpu=fiji -o - %s | FileCheck %s -// CHECK-DAG: ![[DWARF_ADDRESS_SPACE_NONE:[0-9]+]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !{{[0-9]+}}, size: {{[0-9]+}}) -// CHECK-DAG: ![[DWARF_ADDRESS_SPACE_LOCAL:[0-9]+]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !{{[0-9]+}}, size: {{[0-9]+}}, dwarfAddressSpace: 2) -// CHECK-DAG: ![[DWARF_ADDRESS_SPACE_PRIVATE:[0-9]+]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !{{[0-9]+}}, size: {{[0-9]+}}, dwarfAddressSpace: 1) +// CHECK-DAG: ![[DWARF_ADDRESS_SPACE_GLOBAL:[0-9]+]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !{{[0-9]+}}, size: {{[0-9]+}}) +// CHECK-DAG: ![[DWARF_ADDRESS_SPACE_LOCAL:[0-9]+]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !{{[0-9]+}}, size: {{[0-9]+}}, dwarfAddressSpace: 3) +// CHECK-DAG: ![[DWARF_ADDRESS_SPACE_PRIVATE:[0-9]+]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !{{[0-9]+}}, size: {{[0-9]+}}, dwarfAddressSpace: 5) +// CHECK-DAG: ![[DWARF_ADDRESS_SPACE_GENERIC:[0-9]+]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !{{[0-9]+}}, size: {{[0-9]+}}, dwarfAddressSpace: 1) -// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar0", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: false, isDefinition: true) +// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar0", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_GLOBAL]], isLocal: false, isDefinition: true) global int *FileVar0; -// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar1", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: false, isDefinition: true) +// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar1", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_GLOBAL]], isLocal: false, isDefinition: true) constant int *FileVar1; // CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar2", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_LOCAL]], isLocal: false, isDefinition: true) local int *FileVar2; // CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar3", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_PRIVATE]], isLocal: false, isDefinition: true) private int *FileVar3; -// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar4", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: false, isDefinition: true) +// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar4", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_GENERIC]], isLocal: false, isDefinition: true) int *FileVar4; -// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar5", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: false, isDefinition: true) +// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar5", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_GLOBAL]], isLocal: false, isDefinition: true) global int *global FileVar5; -// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar6", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: false, isDefinition: true) +// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar6", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_GLOBAL]], isLocal: false, isDefinition: true) constant int *global FileVar6; // CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar7", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_LOCAL]], isLocal: false, isDefinition: true) local int *global FileVar7; // CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar8", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_PRIVATE]], isLocal: false, isDefinition: true) private int *global FileVar8; -// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar9", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: false, isDefinition: true) +// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar9", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_GENERIC]], isLocal: false, isDefinition: true) int *global FileVar9; -// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar10", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: false, isDefinition: true) +// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar10", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_GLOBAL]], isLocal: false, isDefinition: true) global int *constant FileVar10 = 0; -// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar11", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: false, isDefinition: true) +// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar11", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_GLOBAL]], isLocal: false, isDefinition: true) constant int *constant FileVar11 = 0; // CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar12", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_LOCAL]], isLocal: false, isDefinition: true) local int *constant FileVar12 = 0; // CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar13", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_PRIVATE]], isLocal: false, isDefinition: true) private int *constant FileVar13 = 0; -// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar14", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: false, isDefinition: true) +// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar14", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_GENERIC]], isLocal: false, isDefinition: true) int *constant FileVar14 = 0; kernel void kernel1( - // CHECK-DAG: !DILocalVariable(name: "KernelArg0", arg: {{[0-9]+}}, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]]) + // CHECK-DAG: !DILocalVariable(name: "KernelArg0", arg: {{[0-9]+}}, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_GLOBAL]]) global int *KernelArg0, - // CHECK-DAG: !DILocalVariable(name: "KernelArg1", arg: {{[0-9]+}}, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]]) + // CHECK-DAG: !DILocalVariable(name: "KernelArg1", arg: {{[0-9]+}}, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_GLOBAL]]) constant int *KernelArg1, // CHECK-DAG: !DILocalVariable(name: "KernelArg2", arg: {{[0-9]+}}, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_LOCAL]]) local int *KernelArg2) { private int *Tmp0; int *Tmp1; - // CHECK-DAG: !DILocalVariable(name: "FuncVar0", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]]) + // CHECK-DAG: !DILocalVariable(name: "FuncVar0", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_GLOBAL]]) global int *FuncVar0 = KernelArg0; - // CHECK-DAG: !DILocalVariable(name: "FuncVar1", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]]) + // CHECK-DAG: !DILocalVariable(name: "FuncVar1", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_GLOBAL]]) constant int *FuncVar1 = KernelArg1; // CHECK-DAG: !DILocalVariable(name: "FuncVar2", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_LOCAL]]) local int *FuncVar2 = KernelArg2; // CHECK-DAG: !DILocalVariable(name: "FuncVar3", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_PRIVATE]]) private int *FuncVar3 = Tmp0; - // CHECK-DAG: !DILocalVariable(name: "FuncVar4", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]]) + // CHECK-DAG: !DILocalVariable(name: "FuncVar4", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_GENERIC]]) int *FuncVar4 = Tmp1; - // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar5", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: true, isDefinition: true) + // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar5", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_GLOBAL]], isLocal: true, isDefinition: true) global int *constant FuncVar5 = 0; - // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar6", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: true, isDefinition: true) + // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar6", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_GLOBAL]], isLocal: true, isDefinition: true) constant int *constant FuncVar6 = 0; // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar7", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_LOCAL]], isLocal: true, isDefinition: true) local int *constant FuncVar7 = 0; // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar8", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_PRIVATE]], isLocal: true, isDefinition: true) private int *constant FuncVar8 = 0; - // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar9", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: true, isDefinition: true) + // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar9", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_GENERIC]], isLocal: true, isDefinition: true) int *constant FuncVar9 = 0; - // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar10", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: true, isDefinition: true) + // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar10", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_GLOBAL]], isLocal: true, isDefinition: true) global int *local FuncVar10; FuncVar10 = KernelArg0; - // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar11", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: true, isDefinition: true) + // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar11", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_GLOBAL]], isLocal: true, isDefinition: true) constant int *local FuncVar11; FuncVar11 = KernelArg1; // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar12", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_LOCAL]], isLocal: true, isDefinition: true) local int *local FuncVar12; FuncVar12 = KernelArg2; // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar13", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_PRIVATE]], isLocal: true, isDefinition: true) private int *local FuncVar13; FuncVar13 = Tmp0; - // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar14", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: true, isDefinition: true) + // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar14", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_GENERIC]], isLocal: true, isDefinition: true) int *local FuncVar14; FuncVar14 = Tmp1; - // CHECK-DAG: !DILocalVariable(name: "FuncVar15", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]]) + // CHECK-DAG: !DILocalVariable(name: "FuncVar15", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_GLOBAL]]) global int *private FuncVar15 = KernelArg0; - // CHECK-DAG: !DILocalVariable(name: "FuncVar16", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]]) + // CHECK-DAG: !DILocalVariable(name: "FuncVar16", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_GLOBAL]]) constant int *private FuncVar16 = KernelArg1; // CHECK-DAG: !DILocalVariable(name: "FuncVar17", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_LOCAL]]) local int *private FuncVar17 = KernelArg2; // CHECK-DAG: !DILocalVariable(name: "FuncVar18", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_PRIVATE]]) private int *private FuncVar18 = Tmp0; - // CHECK-DAG: !DILocalVariable(name: "FuncVar19", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]]) + // CHECK-DAG: !DILocalVariable(name: "FuncVar19", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_GENERIC]]) int *private FuncVar19 = Tmp1; } struct FileStruct0 { - // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "StructMem0", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_NONE]], size: {{[0-9]+}}) + // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "StructMem0", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_GLOBAL]], size: {{[0-9]+}}) global int *StructMem0; - // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "StructMem1", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_NONE]], size: {{[0-9]+}}, offset: {{[0-9]+}}) + // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "StructMem1", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_GLOBAL]], size: {{[0-9]+}}, offset: {{[0-9]+}}) constant int *StructMem1; // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "StructMem2", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_LOCAL]], size: {{[0-9]+}}, offset: {{[0-9]+}}) local int *StructMem2; // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "StructMem3", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_PRIVATE]], size: {{[0-9]+}}, offset: {{[0-9]+}}) private int *StructMem3; - // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "StructMem4", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_NONE]], size: {{[0-9]+}}, offset: {{[0-9]+}}) + // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "StructMem4", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_GENERIC]], size: {{[0-9]+}}, offset: {{[0-9]+}}) int *StructMem4; }; struct FileStruct1 { union { - // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "UnionMem0", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_NONE]], size: {{[0-9]+}}) + // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "UnionMem0", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_GLOBAL]], size: {{[0-9]+}}) global int *UnionMem0; - // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "UnionMem1", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_NONE]], size: {{[0-9]+}}) + // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "UnionMem1", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_GLOBAL]], size: {{[0-9]+}}) constant int *UnionMem1; // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "UnionMem2", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_LOCAL]], size: {{[0-9]+}}) local int *UnionMem2; // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "UnionMem3", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_PRIVATE]], size: {{[0-9]+}}) private int *UnionMem3; - // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "UnionMem4", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_NONE]], size: {{[0-9]+}}) + // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "UnionMem4", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_GENERIC]], size: {{[0-9]+}}) int *UnionMem4; }; long StructMem0; diff --git a/clang/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl b/clang/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl index 479e893000942..4d5f1019378af 100644 --- a/clang/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl +++ b/clang/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl @@ -52,31 +52,31 @@ int *constant FileVar14 = 0; kernel void kernel1( // CHECK-DAG: ![[KERNELARG0:[0-9]+]] = !DILocalVariable(name: "KernelArg0", arg: {{[0-9]+}}, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}) - // CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[KERNELARG0]], !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}} + // CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[KERNELARG0]], !DIExpression(DW_OP_constu, 5, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}} global int *KernelArg0, // CHECK-DAG: ![[KERNELARG1:[0-9]+]] = !DILocalVariable(name: "KernelArg1", arg: {{[0-9]+}}, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}) - // CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[KERNELARG1]], !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}} + // CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[KERNELARG1]], !DIExpression(DW_OP_constu, 5, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}} constant int *KernelArg1, // CHECK-DAG: ![[KERNELARG2:[0-9]+]] = !DILocalVariable(name: "KernelArg2", arg: {{[0-9]+}}, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}) - // CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[KERNELARG2]], !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}} + // CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[KERNELARG2]], !DIExpression(DW_OP_constu, 5, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}} local int *KernelArg2) { private int *Tmp0; int *Tmp1; // CHECK-DAG: ![[FUNCVAR0:[0-9]+]] = !DILocalVariable(name: "FuncVar0", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}) - // CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR0]], !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}} + // CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR0]], !DIExpression(DW_OP_constu, 5, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}} global int *FuncVar0 = KernelArg0; // CHECK-DAG: ![[FUNCVAR1:[0-9]+]] = !DILocalVariable(name: "FuncVar1", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}) - // CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR1]], !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}} + // CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR1]], !DIExpression(DW_OP_constu, 5, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}} constant int *FuncVar1 = KernelArg1; // CHECK-DAG: ![[FUNCVAR2:[0-9]+]] = !DILocalVariable(name: "FuncVar2", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}) - // CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR2]], !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}} + // CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR2]], !DIExpression(DW_OP_constu, 5, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}} local int *FuncVar2 = KernelArg2; // CHECK-DAG: ![[FUNCVAR3:[0-9]+]] = !DILocalVariable(name: "FuncVar3", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}) - // CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR3]], !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}} + // CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR3]], !DIExpression(DW_OP_constu, 5, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}} private int *FuncVar3 = Tmp0; // CHECK-DAG: ![[FUNCVAR4:[0-9]+]] = !DILocalVariable(name: "FuncVar4", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}) - // CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR4]], !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}} + // CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR4]], !DIExpression(DW_OP_constu, 5, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}} int *FuncVar4 = Tmp1; // 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( int *constant FuncVar9 = 0; // 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) - // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR10]], expr: !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef)) + // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR10]], expr: !DIExpression(DW_OP_constu, 3, DW_OP_swap, DW_OP_xderef)) global int *local FuncVar10; FuncVar10 = KernelArg0; // 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) - // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR11]], expr: !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef)) + // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR11]], expr: !DIExpression(DW_OP_constu, 3, DW_OP_swap, DW_OP_xderef)) constant int *local FuncVar11; FuncVar11 = KernelArg1; // 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) - // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR12]], expr: !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef)) + // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR12]], expr: !DIExpression(DW_OP_constu, 3, DW_OP_swap, DW_OP_xderef)) local int *local FuncVar12; FuncVar12 = KernelArg2; // 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) - // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR13]], expr: !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef)) + // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR13]], expr: !DIExpression(DW_OP_constu, 3, DW_OP_swap, DW_OP_xderef)) private int *local FuncVar13; FuncVar13 = Tmp0; // 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) - // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR14]], expr: !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef)) + // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR14]], expr: !DIExpression(DW_OP_constu, 3, DW_OP_swap, DW_OP_xderef)) int *local FuncVar14; FuncVar14 = Tmp1; // CHECK-DAG: ![[FUNCVAR15:[0-9]+]] = !DILocalVariable(name: "FuncVar15", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}) - // CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR15]], !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}} + // CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR15]], !DIExpression(DW_OP_constu, 5, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}} global int *private FuncVar15 = KernelArg0; // CHECK-DAG: ![[FUNCVAR16:[0-9]+]] = !DILocalVariable(name: "FuncVar16", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}) - // CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR16]], !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}} + // CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR16]], !DIExpression(DW_OP_constu, 5, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}} constant int *private FuncVar16 = KernelArg1; // CHECK-DAG: ![[FUNCVAR17:[0-9]+]] = !DILocalVariable(name: "FuncVar17", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}) - // CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR17]], !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}} + // CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR17]], !DIExpression(DW_OP_constu, 5, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}} local int *private FuncVar17 = KernelArg2; // CHECK-DAG: ![[FUNCVAR18:[0-9]+]] = !DILocalVariable(name: "FuncVar18", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}) - // CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR18]], !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}} + // CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR18]], !DIExpression(DW_OP_constu, 5, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}} private int *private FuncVar18 = Tmp0; // CHECK-DAG: ![[FUNCVAR19:[0-9]+]] = !DILocalVariable(name: "FuncVar19", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}) - // CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR19]], !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}} + // CHECK-DAG: #dbg_declare(ptr addrspace(5) {{.*}}, ![[FUNCVAR19]], !DIExpression(DW_OP_constu, 5, DW_OP_swap, DW_OP_xderef), !{{[0-9]+}} int *private FuncVar19 = Tmp1; } diff --git a/llvm/include/llvm/BinaryFormat/Dwarf.def b/llvm/include/llvm/BinaryFormat/Dwarf.def index b561125fe37a4..2c9a3c0f6fb04 100644 --- a/llvm/include/llvm/BinaryFormat/Dwarf.def +++ b/llvm/include/llvm/BinaryFormat/Dwarf.def @@ -25,7 +25,8 @@ defined HANDLE_DW_APPLE_PROPERTY || defined HANDLE_DW_UT || \ defined HANDLE_DWARF_SECTION || defined HANDLE_DW_IDX || \ defined HANDLE_DW_END || defined HANDLE_DW_SECT || \ - defined HANDLE_DW_APPLE_ENUM_KIND) + defined HANDLE_DW_APPLE_ENUM_KIND || \ + ( defined HANDLE_DW_ASPACE && defined HANDLE_DW_ASPACE_PRED) ) #error "Missing macro definition of HANDLE_DW*" #endif @@ -151,6 +152,14 @@ #define HANDLE_DW_APPLE_ENUM_KIND(ID, NAME) #endif +#ifndef HANDLE_DW_ASPACE +#define HANDLE_DW_ASPACE(ID, NAME) +#endif + +#ifndef HANDLE_DW_ASPACE_PRED +#define HANDLE_DW_ASPACE_PRED(ID, NAME, PRED) +#endif + HANDLE_DW_TAG(0x0000, null, 2, DWARF, DW_KIND_NONE) HANDLE_DW_TAG(0x0001, array_type, 2, DWARF, DW_KIND_TYPE) 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) // The DWARF v6 working draft defines DW_AT_alloc_type; use this LLVM-private ID // until that is released as an official standard. HANDLE_DW_AT(0x3e0e, LLVM_alloc_type, 0, LLVM) +// Heterogeneous Debugging Extension defined at +// https://llvm.org/docs/AMDGPUDwarfProposalForHeterogeneousDebugging.html. +HANDLE_DW_AT(0x3e0f, LLVM_memory_space, 0, LLVM) +HANDLE_DW_AT(0x3e10, LLVM_address_space, 0, LLVM) +HANDLE_DW_AT(0x3e11, LLVM_lanes, 0, LLVM) +HANDLE_DW_AT(0x3e12, LLVM_lane_pc, 0, LLVM) +HANDLE_DW_AT(0x3e13, LLVM_vector_size, 0, LLVM) + +// https://llvm.org/docs/AMDGPUUsage.html#address-space-identifier +HANDLE_DW_ASPACE(0x0, none) +HANDLE_DW_ASPACE_PRED(AMDGPU::DWARFAS::GENERIC, AMDGPU_generic, SELECT_AMDGPU) +HANDLE_DW_ASPACE_PRED(AMDGPU::DWARFAS::REGION, AMDGPU_region, SELECT_AMDGPU) +HANDLE_DW_ASPACE_PRED(AMDGPU::DWARFAS::LOCAL, AMDGPU_local, SELECT_AMDGPU) +HANDLE_DW_ASPACE_PRED(AMDGPU::DWARFAS::PRIVATE_LANE, AMDGPU_private_lane, SELECT_AMDGPU) +HANDLE_DW_ASPACE_PRED(AMDGPU::DWARFAS::PRIVATE_WAVE, AMDGPU_private_wave, SELECT_AMDGPU) // Apple extensions. @@ -916,6 +940,19 @@ HANDLE_DW_OP(0xe9, LLVM_user, -1, -1, 0, LLVM) // location stack or any of its values. It is defined as a placeholder for // testing purposes. HANDLE_DW_OP_LLVM_USEROP(0x0001, nop) +// Heterogeneous Debugging Extension defined at +// https://llvm.org/docs/AMDGPUDwarfProposalForHeterogeneousDebugging.html. +HANDLE_DW_OP_LLVM_USEROP(0x0002, form_aspace_address) +HANDLE_DW_OP_LLVM_USEROP(0x0003, push_lane) +HANDLE_DW_OP_LLVM_USEROP(0x0004, offset) +HANDLE_DW_OP_LLVM_USEROP(0x0005, offset_uconst) +HANDLE_DW_OP_LLVM_USEROP(0x0006, bit_offset) +HANDLE_DW_OP_LLVM_USEROP(0x0007, call_frame_entry_reg) +HANDLE_DW_OP_LLVM_USEROP(0x0008, undefined) +HANDLE_DW_OP_LLVM_USEROP(0x0009, aspace_bregx) +HANDLE_DW_OP_LLVM_USEROP(0x000a, piece_end) +HANDLE_DW_OP_LLVM_USEROP(0x000b, extend) +HANDLE_DW_OP_LLVM_USEROP(0x000c, select_bit_piece) // DWARF languages. HANDLE_DW_LANG(0x0001, C89, 0, 2, DWARF) @@ -1385,3 +1422,5 @@ HANDLE_DW_SECT(8, RNGLISTS) #undef HANDLE_DW_END #undef HANDLE_DW_SECT #undef HANDLE_DW_APPLE_ENUM_KIND +#undef HANDLE_DW_ASPACE +#undef HANDLE_DW_ASPACE_PRED diff --git a/llvm/include/llvm/BinaryFormat/Dwarf.h b/llvm/include/llvm/BinaryFormat/Dwarf.h index 231b7ac17d75f..2c5012510a5c3 100644 --- a/llvm/include/llvm/BinaryFormat/Dwarf.h +++ b/llvm/include/llvm/BinaryFormat/Dwarf.h @@ -19,6 +19,7 @@ #ifndef LLVM_BINARYFORMAT_DWARF_H #define LLVM_BINARYFORMAT_DWARF_H +#include "llvm/Support/AMDGPUAddrSpace.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/ErrorHandling.h" @@ -757,6 +758,12 @@ enum CallingConvention { DW_CC_hi_user = 0xff }; +enum AddressSpace { +#define HANDLE_DW_ASPACE(ID, NAME) DW_ASPACE_LLVM_##NAME = ID, +#define HANDLE_DW_ASPACE_PRED(ID, NAME, PRED) DW_ASPACE_LLVM_##NAME = ID, +#include "llvm/BinaryFormat/Dwarf.def" +}; + enum InlineAttribute { // Inline codes DW_INL_not_inlined = 0x00, @@ -1011,6 +1018,7 @@ LLVM_ABI StringRef IndexString(unsigned Idx); LLVM_ABI StringRef FormatString(DwarfFormat Format); LLVM_ABI StringRef FormatString(bool IsDWARF64); LLVM_ABI StringRef RLEString(unsigned RLE); +LLVM_ABI StringRef AddressSpaceString(unsigned AS, const llvm::Triple &TT); /// @} /// \defgroup DwarfConstantsParsing Dwarf constants parsing functions diff --git a/llvm/include/llvm/Support/AMDGPUAddrSpace.h b/llvm/include/llvm/Support/AMDGPUAddrSpace.h index b1b1dd49a2c4a..0c89512310289 100644 --- a/llvm/include/llvm/Support/AMDGPUAddrSpace.h +++ b/llvm/include/llvm/Support/AMDGPUAddrSpace.h @@ -120,6 +120,51 @@ inline bool isConstantAddressSpace(unsigned AS) { return false; } } + +namespace DWARFAS { +enum : unsigned { + GLOBAL = 0, + GENERIC = 1, + REGION = 2, + LOCAL = 3, + PRIVATE_LANE = 5, + PRIVATE_WAVE = 6, + DEFAULT = GLOBAL, +}; +} // namespace DWARFAS + +namespace impl { +// TODO: Move this into mapToDWARFAddrSpace when we switch to C++23 +// (see https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2647r1.html) +static constexpr unsigned LLVMToDWARFAddrSpaceMapping[] = { + DWARFAS::GENERIC, //< AMDGPUAS::FLAT_ADDRESS + DWARFAS::GLOBAL, //< AMDGPUAS::GLOBAL_ADDRESS + DWARFAS::REGION, //< AMDGPUAS::REGION_ADDRESS + DWARFAS::LOCAL, //< AMDGPUAS::LOCAL_ADDRESS + DWARFAS::GLOBAL, //< AMDGPUAS::CONSTANT_ADDRESS + DWARFAS::PRIVATE_LANE //< AMDGPUAS::PRIVATE_ADDRESS +}; +} // end namespace impl + +/// If @p LLVMAddressSpace has a corresponding DWARF encoding, +/// return it; otherwise return the sentinel value -1 to indicate +/// no such mapping exists. +/// +/// This maps private/scratch to the focused lane view. +/// +/// These mappings must be kept in sync with llvm/docs/AMDGPUUsage.rst +/// table "AMDGPU DWARF Address Space Mapping". +/// +/// Note: This could return std::optional but that would require +/// an extra #include. +constexpr int mapToDWARFAddrSpace(unsigned LLVMAddrSpace) { + constexpr unsigned SizeOfLLVMToDWARFAddrSpaceMapping = + sizeof(impl::LLVMToDWARFAddrSpaceMapping) / + sizeof(impl::LLVMToDWARFAddrSpaceMapping[0]); + if (LLVMAddrSpace < SizeOfLLVMToDWARFAddrSpaceMapping) + return impl::LLVMToDWARFAddrSpaceMapping[LLVMAddrSpace]; + return -1; +} } // end namespace AMDGPU } // end namespace llvm diff --git a/llvm/lib/BinaryFormat/Dwarf.cpp b/llvm/lib/BinaryFormat/Dwarf.cpp index 0d17dc175fed9..8b24044e19e50 100644 --- a/llvm/lib/BinaryFormat/Dwarf.cpp +++ b/llvm/lib/BinaryFormat/Dwarf.cpp @@ -911,6 +911,27 @@ StringRef llvm::dwarf::RLEString(unsigned RLE) { } } +StringRef llvm::dwarf::AddressSpaceString(unsigned AS, const llvm::Triple &TT) { + switch (AS) { +#define HANDLE_DW_ASPACE(ID, NAME) \ + case DW_ASPACE_LLVM_##NAME: \ + return "DW_ASPACE_LLVM_" #NAME; +#define HANDLE_DW_ASPACE_PRED(ID, NAME, PRED) +#include "llvm/BinaryFormat/Dwarf.def" + default: + break; + } + + bool SELECT_AMDGPU = TT.isAMDGPU(); +#define HANDLE_DW_ASPACE(ID, NAME) +#define HANDLE_DW_ASPACE_PRED(ID, NAME, PRED) \ + if (DW_ASPACE_LLVM_##NAME == AS && PRED) \ + return "DW_ASPACE_LLVM_" #NAME; +#include "llvm/BinaryFormat/Dwarf.def" + + return ""; +} + StringRef (*const llvm::dwarf::EnumTraits::StringFn)(unsigned) = TagString; StringRef (*const llvm::dwarf::EnumTraits::StringFn)(unsigned) = AttributeString; diff --git a/llvm/lib/DebugInfo/DWARF/DWARFExpressionPrinter.cpp b/llvm/lib/DebugInfo/DWARF/DWARFExpressionPrinter.cpp index 078ebf4e7c032..fcd2316c30aef 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFExpressionPrinter.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFExpressionPrinter.cpp @@ -53,6 +53,8 @@ static bool printOp(const DWARFExpression::Operation *Op, raw_ostream &OS, return false; } + std::optional SubOpcode = Op->getSubCode(); + // In "register-only" mode, still show simple constant-valued locations. // This lets clients print annotations like "i = 0" when the location is // a constant (e.g. DW_OP_constu/consts ... DW_OP_stack_value). @@ -63,7 +65,9 @@ static bool printOp(const DWARFExpression::Operation *Op, raw_ostream &OS, if ((Op->getCode() >= DW_OP_breg0 && Op->getCode() <= DW_OP_breg31) || (Op->getCode() >= DW_OP_reg0 && Op->getCode() <= DW_OP_reg31) || Op->getCode() == DW_OP_bregx || Op->getCode() == DW_OP_regx || - Op->getCode() == DW_OP_regval_type) { + Op->getCode() == DW_OP_regval_type || + SubOpcode == DW_OP_LLVM_call_frame_entry_reg || + SubOpcode == DW_OP_LLVM_aspace_bregx) { if (prettyPrintRegisterOp(U, OS, DumpOpts, Op->getCode(), Op->getRawOperands())) return true; @@ -93,12 +97,20 @@ static bool printOp(const DWARFExpression::Operation *Op, raw_ostream &OS, StringRef Name = OperationEncodingString(Op->getCode()); assert(!Name.empty() && "DW_OP has no name!"); OS << Name; + + if (SubOpcode) { + StringRef SubName = SubOperationEncodingString(Op->getCode(), *SubOpcode); + assert(!SubName.empty() && "DW_OP SubOp has no name!"); + OS << ' ' << SubName; + } } if ((Op->getCode() >= DW_OP_breg0 && Op->getCode() <= DW_OP_breg31) || (Op->getCode() >= DW_OP_reg0 && Op->getCode() <= DW_OP_reg31) || Op->getCode() == DW_OP_bregx || Op->getCode() == DW_OP_regx || - Op->getCode() == DW_OP_regval_type) + Op->getCode() == DW_OP_regval_type || + SubOpcode == DW_OP_LLVM_call_frame_entry_reg || + SubOpcode == DW_OP_LLVM_aspace_bregx) if (prettyPrintRegisterOp(U, OS, DumpOpts, Op->getCode(), Op->getRawOperands())) return true; @@ -110,10 +122,8 @@ static bool printOp(const DWARFExpression::Operation *Op, raw_ostream &OS, unsigned Signed = Size & DWARFExpression::Operation::SignBit; if (Size == DWARFExpression::Operation::SizeSubOpLEB) { - StringRef SubName = SubOperationEncodingString( - Op->getCode(), Op->getRawOperand(Operand)); - assert(!SubName.empty() && "DW_OP SubOp has no name!"); - OS << " " << SubName; + assert(Operand == 0 && "DW_OP SubOp must be the first operand"); + assert(SubOpcode && "DW_OP SubOp description is inconsistent"); } else if (Size == DWARFExpression::Operation::BaseTypeRef && U) { // For DW_OP_convert the operand may be 0 to indicate that conversion to // the generic type should be done. The same holds for @@ -210,6 +220,19 @@ static bool printCompactDWARFExpr( nullptr) { SmallVector Stack; + auto UnknownOpcode = [](raw_ostream &OS, uint8_t Opcode, + std::optional SubOpcode) -> bool { + // If we hit an unknown operand, we don't know its effect on the stack, + // so bail out on the whole expression. + OS << ""; + return false; + }; + while (I != E) { const DWARFExpression::Operation &Op = *I; uint8_t Opcode = Op.getCode(); @@ -262,8 +285,10 @@ static bool printCompactDWARFExpr( break; } case dwarf::DW_OP_LLVM_user: { - assert(Op.getSubCode() == dwarf::DW_OP_LLVM_nop); - break; + std::optional SubOpcode = Op.getSubCode(); + if (SubOpcode == dwarf::DW_OP_LLVM_nop) + break; + return UnknownOpcode(OS, Opcode, SubOpcode); } default: if (Opcode >= dwarf::DW_OP_reg0 && Opcode <= dwarf::DW_OP_reg31) { @@ -287,11 +312,7 @@ static bool printCompactDWARFExpr( if (Offset) S << format("%+" PRId64, Offset); } else { - // If we hit an unknown operand, we don't know its effect on the stack, - // so bail out on the whole expression. - OS << ""; - return false; + return UnknownOpcode(OS, Opcode, std::nullopt); } break; } @@ -326,8 +347,13 @@ bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS, uint64_t DwarfRegNum; unsigned OpNum = 0; + std::optional SubOpcode; + if (Opcode == DW_OP_LLVM_user) + SubOpcode = Operands[OpNum++]; + if (Opcode == DW_OP_bregx || Opcode == DW_OP_regx || - Opcode == DW_OP_regval_type) + Opcode == DW_OP_regval_type || SubOpcode == DW_OP_LLVM_aspace_bregx || + SubOpcode == DW_OP_LLVM_call_frame_entry_reg) DwarfRegNum = Operands[OpNum++]; else if (Opcode >= DW_OP_breg0 && Opcode < DW_OP_bregx) DwarfRegNum = Opcode - DW_OP_breg0; @@ -337,7 +363,7 @@ bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS, auto RegName = DumpOpts.GetNameForDWARFReg(DwarfRegNum, DumpOpts.IsEH); if (!RegName.empty()) { if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) || - Opcode == DW_OP_bregx) + Opcode == DW_OP_bregx || SubOpcode == DW_OP_LLVM_aspace_bregx) OS << ' ' << RegName << format("%+" PRId64, Operands[OpNum]); else OS << ' ' << RegName.data(); diff --git a/llvm/lib/DebugInfo/DWARF/LowLevel/DWARFExpression.cpp b/llvm/lib/DebugInfo/DWARF/LowLevel/DWARFExpression.cpp index 9a7f7d1ca2a67..61bd6fcb65bfa 100644 --- a/llvm/lib/DebugInfo/DWARF/LowLevel/DWARFExpression.cpp +++ b/llvm/lib/DebugInfo/DWARF/LowLevel/DWARFExpression.cpp @@ -130,6 +130,23 @@ static std::vector getSubOpDescriptions() { std::vector Descriptions; Descriptions.resize(LlvmUserDescriptionsSize); Descriptions[DW_OP_LLVM_nop] = Desc(Op::Dwarf5, Op::SizeSubOpLEB); + Descriptions[DW_OP_LLVM_form_aspace_address] = + Desc(Op::Dwarf5, Op::SizeSubOpLEB); + Descriptions[DW_OP_LLVM_push_lane] = Desc(Op::Dwarf5, Op::SizeSubOpLEB); + Descriptions[DW_OP_LLVM_offset] = Desc(Op::Dwarf5, Op::SizeSubOpLEB); + Descriptions[DW_OP_LLVM_offset_uconst] = + Desc(Op::Dwarf5, Op::SizeSubOpLEB, Op::SizeLEB); + Descriptions[DW_OP_LLVM_bit_offset] = Desc(Op::Dwarf5, Op::SizeSubOpLEB); + Descriptions[DW_OP_LLVM_call_frame_entry_reg] = + Desc(Op::Dwarf5, Op::SizeSubOpLEB, Op::SizeLEB); + Descriptions[DW_OP_LLVM_undefined] = Desc(Op::Dwarf5, Op::SizeSubOpLEB); + Descriptions[DW_OP_LLVM_aspace_bregx] = + Desc(Op::Dwarf5, Op::SizeSubOpLEB, Op::SizeLEB, Op::SizeLEB); + Descriptions[DW_OP_LLVM_piece_end] = Desc(Op::Dwarf5, Op::SizeSubOpLEB); + Descriptions[DW_OP_LLVM_extend] = + Desc(Op::Dwarf5, Op::SizeSubOpLEB, Op::SizeLEB, Op::SizeLEB); + Descriptions[DW_OP_LLVM_select_bit_piece] = + Desc(Op::Dwarf5, Op::SizeSubOpLEB, Op::SizeLEB, Op::SizeLEB); return Descriptions; } @@ -164,6 +181,8 @@ bool DWARFExpression::Operation::extract(DataExtractor Data, return false; assert(Desc.Op[Operand] == Operation::SizeSubOpLEB && "SizeSubOpLEB Description must begin with SizeSubOpLEB operand"); + Operands.resize(Desc.Op.size()); + OperandEndOffsets.resize(Desc.Op.size()); break; case Operation::Size1: Operands[Operand] = Data.getU8(&Offset); diff --git a/llvm/test/tools/llvm-dwarfdump/X86/heterogeneous-user-ops.s b/llvm/test/tools/llvm-dwarfdump/X86/heterogeneous-user-ops.s new file mode 100644 index 0000000000000..ef90f31d92a8a --- /dev/null +++ b/llvm/test/tools/llvm-dwarfdump/X86/heterogeneous-user-ops.s @@ -0,0 +1,31 @@ +# RUN: llvm-mc %s -filetype=obj -triple=i686-pc-linux -o - | llvm-dwarfdump --debug-frame - | FileCheck %s + +# CHECK: .eh_frame contents: +# CHECK: FDE +# CHECK-NEXT: Format: DWARF32 + +foo: + .cfi_startproc + # CHECK-NEXT: DW_CFA_expression: EAX DW_OP_LLVM_user DW_OP_LLVM_form_aspace_address + .cfi_escape 0x10, 0x00, 0x02, 0xe9, 0x02 + # CHECK-NEXT: DW_CFA_expression: EAX DW_OP_LLVM_user DW_OP_LLVM_push_lane + .cfi_escape 0x10, 0x00, 0x02, 0xe9, 0x03 + # CHECK-NEXT: DW_CFA_expression: EAX DW_OP_LLVM_user DW_OP_LLVM_offset + .cfi_escape 0x10, 0x00, 0x02, 0xe9, 0x04 + # CHECK-NEXT: DW_CFA_expression: EAX DW_OP_LLVM_user DW_OP_LLVM_offset_uconst 0x0 + .cfi_escape 0x10, 0x00, 0x03, 0xe9, 0x05, 0x00 + # CHECK-NEXT: DW_CFA_expression: EAX DW_OP_LLVM_user DW_OP_LLVM_bit_offset + .cfi_escape 0x10, 0x00, 0x02, 0xe9, 0x06 + # CHECK-NEXT: DW_CFA_expression: EAX DW_OP_LLVM_user DW_OP_LLVM_call_frame_entry_reg EAX + .cfi_escape 0x10, 0x00, 0x03, 0xe9, 0x07, 0x00 + # CHECK-NEXT: DW_CFA_expression: EAX DW_OP_LLVM_user DW_OP_LLVM_undefined + .cfi_escape 0x10, 0x00, 0x02, 0xe9, 0x08 + # CHECK-NEXT: DW_CFA_expression: EAX DW_OP_LLVM_user DW_OP_LLVM_aspace_bregx EAX+2 + .cfi_escape 0x10, 0x00, 0x04, 0xe9, 0x09, 0x00, 0x02 + # CHECK-NEXT: DW_CFA_expression: EAX DW_OP_LLVM_user DW_OP_LLVM_piece_end + .cfi_escape 0x10, 0x00, 0x02, 0xe9, 0x0a + # CHECK-NEXT: DW_CFA_expression: EAX DW_OP_LLVM_user DW_OP_LLVM_extend 0x0 0x0 + .cfi_escape 0x10, 0x00, 0x04, 0xe9, 0x0b, 0x00, 0x00 + # CHECK-NEXT: DW_CFA_expression: EAX DW_OP_LLVM_user DW_OP_LLVM_select_bit_piece 0x0 0x0 + .cfi_escape 0x10, 0x00, 0x04, 0xe9, 0x0c, 0x00, 0x00 + .cfi_endproc diff --git a/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp index 41acc8240c720..306ce67f93793 100644 --- a/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp +++ b/llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp @@ -141,3 +141,9 @@ TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_nop_OP_reg) { TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_LLVM_nop_OP_reg) { TestExprPrinter({DW_OP_LLVM_user, DW_OP_LLVM_nop, DW_OP_reg0}, "R0"); } + +TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_LLVM_user_unknown_subop) { + TestExprPrinter({DW_OP_LLVM_user, DW_OP_LLVM_form_aspace_address}, + ""); +}