Index: llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/AMDGPUCodeObjectMetadata.h =================================================================== --- llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/AMDGPUCodeObjectMetadata.h +++ llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/AMDGPUCodeObjectMetadata.h @@ -280,23 +280,23 @@ namespace CodeProps { namespace Key { -/// \brief Key for Kernel::CodeProps::mKernargSegmentSize. +/// \brief Key for Kernel::CodeProps::Metadata::mKernargSegmentSize. constexpr char KernargSegmentSize[] = "KernargSegmentSize"; -/// \brief Key for Kernel::CodeProps::mWorkgroupGroupSegmentSize. +/// \brief Key for Kernel::CodeProps::Metadata::mWorkgroupGroupSegmentSize. constexpr char WorkgroupGroupSegmentSize[] = "WorkgroupGroupSegmentSize"; -/// \brief Key for Kernel::CodeProps::mWorkitemPrivateSegmentSize. +/// \brief Key for Kernel::CodeProps::Metadata::mWorkitemPrivateSegmentSize. constexpr char WorkitemPrivateSegmentSize[] = "WorkitemPrivateSegmentSize"; -/// \brief Key for Kernel::CodeProps::mWavefrontNumSGPRs. +/// \brief Key for Kernel::CodeProps::Metadata::mWavefrontNumSGPRs. constexpr char WavefrontNumSGPRs[] = "WavefrontNumSGPRs"; -/// \brief Key for Kernel::CodeProps::mWorkitemNumVGPRs. +/// \brief Key for Kernel::CodeProps::Metadata::mWorkitemNumVGPRs. constexpr char WorkitemNumVGPRs[] = "WorkitemNumVGPRs"; -/// \brief Key for Kernel::CodeProps::mKernargSegmentAlign. +/// \brief Key for Kernel::CodeProps::Metadata::mKernargSegmentAlign. constexpr char KernargSegmentAlign[] = "KernargSegmentAlign"; -/// \brief Key for Kernel::CodeProps::mGroupSegmentAlign. +/// \brief Key for Kernel::CodeProps::Metadata::mGroupSegmentAlign. constexpr char GroupSegmentAlign[] = "GroupSegmentAlign"; -/// \brief Key for Kernel::CodeProps::mPrivateSegmentAlign. +/// \brief Key for Kernel::CodeProps::Metadata::mPrivateSegmentAlign. constexpr char PrivateSegmentAlign[] = "PrivateSegmentAlign"; -/// \brief Key for Kernel::CodeProps::mWavefrontSize. +/// \brief Key for Kernel::CodeProps::Metadata::mWavefrontSize. constexpr char WavefrontSize[] = "WavefrontSize"; } // end namespace Key @@ -349,6 +349,63 @@ } // end namespace CodeProps +//===----------------------------------------------------------------------===// +// Kernel Debug Properties Metadata. +//===----------------------------------------------------------------------===// +namespace DebugProps { + +namespace Key { +/// \brief Key for Kernel::DebugProps::Metadata::mDebuggerABIVersion. +constexpr char DebuggerABIVersion[] = "DebuggerABIVersion"; +/// \brief Key for Kernel::DebugProps::Metadata::mReservedNumVGPRs. +constexpr char ReservedNumVGPRs[] = "ReservedNumVGPRs"; +/// \brief Key for Kernel::DebugProps::Metadata::mReservedFirstVGPR. +constexpr char ReservedFirstVGPR[] = "ReservedFirstVGPR"; +/// \brief Key for Kernel::DebugProps::Metadata::mPrivateSegmentBufferSGPR. +constexpr char PrivateSegmentBufferSGPR[] = "PrivateSegmentBufferSGPR"; +/// \brief Key for +/// Kernel::DebugProps::Metadata::mWavefrontPrivateSegmentOffsetSGPR. +constexpr char WavefrontPrivateSegmentOffsetSGPR[] = + "WavefrontPrivateSegmentOffsetSGPR"; +} // end namespace Key + +/// \brief In-memory representation of kernel debug properties metadata. +struct Metadata final { + /// \brief Debugger ABI version. Optional. + std::vector mDebuggerABIVersion = std::vector(); + /// \brief Consecutive number of VGPRs reserved for debugger use. Must be 0 if + /// mDebuggerABIVersion is not set. Optional. + uint16_t mReservedNumVGPRs = 0; + /// \brief First fixed VGPR reserved. Must be uint16_t(-1) if + /// mDebuggerABIVersion is not set or mReservedFirstVGPR is 0. Optional. + uint16_t mReservedFirstVGPR = uint16_t(-1); + /// \brief Fixed SGPR of the first of 4 SGPRs used to hold the scratch V# used + /// for the entire kernel execution. Must be uint16_t(-1) if + /// mDebuggerABIVersion is not set or SGPR not used or not known. Optional. + uint16_t mPrivateSegmentBufferSGPR = uint16_t(-1); + /// \brief Fixed SGPR used to hold the wave scratch offset for the entire + /// kernel execution. Must be uint16_t(-1) if mDebuggerABIVersion is not set + /// or SGPR is not used or not known. Optional. + uint16_t mWavefrontPrivateSegmentOffsetSGPR = uint16_t(-1); + + /// \brief Default constructor. + Metadata() = default; + + /// \returns True if kernel debug properties metadata is empty, false + /// otherwise. + bool empty() const { + return !notEmpty(); + } + + /// \returns True if kernel debug properties metadata is not empty, false + /// otherwise. + bool notEmpty() const { + return !mDebuggerABIVersion.empty(); + } +}; + +} // end namespace DebugProps + namespace Key { /// \brief Key for Kernel::Metadata::mName. constexpr char Name[] = "Name"; @@ -362,6 +419,8 @@ constexpr char Args[] = "Args"; /// \brief Key for Kernel::Metadata::mCodeProps. constexpr char CodeProps[] = "CodeProps"; +/// \brief Key for Kernel::Metadata::mDebugProps. +constexpr char DebugProps[] = "DebugProps"; } // end namespace Key /// \brief In-memory representation of kernel metadata. @@ -378,6 +437,8 @@ std::vector mArgs = std::vector(); /// \brief Code properties metadata. Optional. CodeProps::Metadata mCodeProps = CodeProps::Metadata(); + /// \brief Debug properties metadata. Optional. + DebugProps::Metadata mDebugProps = DebugProps::Metadata(); /// \brief Default constructor. Metadata() = default; Index: llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/AMDGPUCodeObjectMetadataStreamer.h =================================================================== --- llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/AMDGPUCodeObjectMetadataStreamer.h +++ llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/AMDGPUCodeObjectMetadataStreamer.h @@ -76,6 +76,8 @@ void emitKernelCodeProps(const amd_kernel_code_t &KernelCode); + void emitKernelDebugProps(const amd_kernel_code_t &KernelCode); + public: MetadataStreamer() = default; ~MetadataStreamer() = default; Index: llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/AMDGPUCodeObjectMetadataStreamer.cpp =================================================================== --- llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/AMDGPUCodeObjectMetadataStreamer.cpp +++ llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/AMDGPUCodeObjectMetadataStreamer.cpp @@ -178,6 +178,22 @@ }; template <> +struct MappingTraits { + static void mapping(IO &YIO, Kernel::DebugProps::Metadata &MD) { + YIO.mapOptional(Kernel::DebugProps::Key::DebuggerABIVersion, + MD.mDebuggerABIVersion, std::vector()); + YIO.mapOptional(Kernel::DebugProps::Key::ReservedNumVGPRs, + MD.mReservedNumVGPRs, uint16_t(0)); + YIO.mapOptional(Kernel::DebugProps::Key::ReservedFirstVGPR, + MD.mReservedFirstVGPR, uint16_t(-1)); + YIO.mapOptional(Kernel::DebugProps::Key::PrivateSegmentBufferSGPR, + MD.mPrivateSegmentBufferSGPR, uint16_t(-1)); + YIO.mapOptional(Kernel::DebugProps::Key::WavefrontPrivateSegmentOffsetSGPR, + MD.mWavefrontPrivateSegmentOffsetSGPR, uint16_t(-1)); + } +}; + +template <> struct MappingTraits { static void mapping(IO &YIO, Kernel::Metadata &MD) { YIO.mapRequired(Kernel::Key::Name, MD.mName); @@ -190,6 +206,8 @@ YIO.mapOptional(Kernel::Key::Args, MD.mArgs); if (!MD.mCodeProps.empty() || !YIO.outputting()) YIO.mapOptional(Kernel::Key::CodeProps, MD.mCodeProps); + if (!MD.mDebugProps.empty() || !YIO.outputting()) + YIO.mapOptional(Kernel::Key::DebugProps, MD.mDebugProps); } }; @@ -574,6 +592,25 @@ CodeProps.mWavefrontSize = KernelCode.wavefront_size; } +void MetadataStreamer::emitKernelDebugProps( + const amd_kernel_code_t &KernelCode) { + if (!(KernelCode.code_properties & AMD_CODE_PROPERTY_IS_DEBUG_SUPPORTED)) + return; + + auto &DebugProps = CodeObjectMetadata.mKernels.back().mDebugProps; + + // FIXME: Need to pass down debugger ABI version through features. This is ok + // for now because we only have one version. + DebugProps.mDebuggerABIVersion.push_back(1); + DebugProps.mDebuggerABIVersion.push_back(0); + DebugProps.mReservedNumVGPRs = KernelCode.reserved_vgpr_count; + DebugProps.mReservedFirstVGPR = KernelCode.reserved_vgpr_first; + DebugProps.mPrivateSegmentBufferSGPR = + KernelCode.debug_private_segment_buffer_sgpr; + DebugProps.mWavefrontPrivateSegmentOffsetSGPR = + KernelCode.debug_wavefront_private_segment_offset_sgpr; +} + void MetadataStreamer::begin(const FeatureBitset &Features, const Module &Mod) { emitVersion(); emitIsa(Features); @@ -593,6 +630,7 @@ emitKernelAttrs(Func); emitKernelArgs(Func); emitKernelCodeProps(KernelCode); + emitKernelDebugProps(KernelCode); } ErrorOr MetadataStreamer::toYamlString() { Index: llvm/trunk/test/CodeGen/AMDGPU/code-object-metadata-kernel-debug-props.ll =================================================================== --- llvm/trunk/test/CodeGen/AMDGPU/code-object-metadata-kernel-debug-props.ll +++ llvm/trunk/test/CodeGen/AMDGPU/code-object-metadata-kernel-debug-props.ll @@ -0,0 +1,67 @@ +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx700 -filetype=obj -o - < %s | llvm-readobj -amdgpu-code-object-metadata -elf-output-style=GNU -notes | FileCheck --check-prefix=CHECK --check-prefix=GFX700 --check-prefix=NOTES %s +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx800 -filetype=obj -o - < %s | llvm-readobj -amdgpu-code-object-metadata -elf-output-style=GNU -notes | FileCheck --check-prefix=CHECK --check-prefix=GFX800 --check-prefix=NOTES %s +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -filetype=obj -o - < %s | llvm-readobj -amdgpu-code-object-metadata -elf-output-style=GNU -notes | FileCheck --check-prefix=CHECK --check-prefix=GFX900 --check-prefix=NOTES %s + +declare void @llvm.dbg.declare(metadata, metadata, metadata) + +; CHECK: --- +; CHECK: Version: [ 1, 0 ] + +; CHECK: Kernels: +; CHECK: - Name: test +; CHECK: DebugProps: +; CHECK: DebuggerABIVersion: [ 1, 0 ] +; CHECK: ReservedNumVGPRs: 4 +; CHECK: ReservedFirstVGPR: 11 +; CHECK: PrivateSegmentBufferSGPR: 0 +; CHECK: WavefrontPrivateSegmentOffsetSGPR: 11 +define amdgpu_kernel void @test(i32 addrspace(1)* %A) #0 !dbg !7 !kernel_arg_addr_space !12 !kernel_arg_access_qual !13 !kernel_arg_type !14 !kernel_arg_base_type !14 !kernel_arg_type_qual !15 { +entry: + %A.addr = alloca i32 addrspace(1)*, align 4 + store i32 addrspace(1)* %A, i32 addrspace(1)** %A.addr, align 4 + call void @llvm.dbg.declare(metadata i32 addrspace(1)** %A.addr, metadata !16, metadata !17), !dbg !18 + %0 = load i32 addrspace(1)*, i32 addrspace(1)** %A.addr, align 4, !dbg !19 + %arrayidx = getelementptr inbounds i32, i32 addrspace(1)* %0, i64 0, !dbg !19 + store i32 777, i32 addrspace(1)* %arrayidx, align 4, !dbg !20 + %1 = load i32 addrspace(1)*, i32 addrspace(1)** %A.addr, align 4, !dbg !21 + %arrayidx1 = getelementptr inbounds i32, i32 addrspace(1)* %1, i64 1, !dbg !21 + store i32 888, i32 addrspace(1)* %arrayidx1, align 4, !dbg !22 + %2 = load i32 addrspace(1)*, i32 addrspace(1)** %A.addr, align 4, !dbg !23 + %arrayidx2 = getelementptr inbounds i32, i32 addrspace(1)* %2, i64 2, !dbg !23 + store i32 999, i32 addrspace(1)* %arrayidx2, align 4, !dbg !24 + ret void, !dbg !25 +} + +attributes #0 = { noinline nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="gfx800" "target-features"="+16-bit-insts,+amdgpu-debugger-emit-prologue,+amdgpu-debugger-insert-nops,+amdgpu-debugger-reserve-regs,+dpp,+fp64-fp16-denormals,+s-memrealtime,-fp32-denormals" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!0} +!opencl.ocl.version = !{!3} +!llvm.module.flags = !{!4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 5.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) +!1 = !DIFile(filename: "code-object-metadata-kernel-debug-props.cl", directory: "/some/random/directory") +!2 = !{} +!3 = !{i32 1, i32 0} +!4 = !{i32 2, !"Dwarf Version", i32 2} +!5 = !{i32 2, !"Debug Info Version", i32 3} +!6 = !{!"clang version 5.0.0"} +!7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!8 = !DISubroutineType(types: !9) +!9 = !{null, !10} +!10 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !11, size: 64) +!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!12 = !{i32 1} +!13 = !{!"none"} +!14 = !{!"int*"} +!15 = !{!""} +!16 = !DILocalVariable(name: "A", arg: 1, scope: !7, file: !1, line: 1, type: !10) +!17 = !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef) +!18 = !DILocation(line: 1, column: 30, scope: !7) +!19 = !DILocation(line: 2, column: 3, scope: !7) +!20 = !DILocation(line: 2, column: 8, scope: !7) +!21 = !DILocation(line: 3, column: 3, scope: !7) +!22 = !DILocation(line: 3, column: 8, scope: !7) +!23 = !DILocation(line: 4, column: 3, scope: !7) +!24 = !DILocation(line: 4, column: 8, scope: !7) +!25 = !DILocation(line: 5, column: 1, scope: !7) Index: llvm/trunk/test/MC/AMDGPU/code-object-metadata-kernel-code-props.s =================================================================== --- llvm/trunk/test/MC/AMDGPU/code-object-metadata-kernel-code-props.s +++ llvm/trunk/test/MC/AMDGPU/code-object-metadata-kernel-code-props.s @@ -7,10 +7,10 @@ // CHECK: Kernels: // CHECK: - Name: test_kernel // CHECK: CodeProps: -// CHECK: KernargSegmentSize: 24 -// CHECK: WorkitemPrivateSegmentSize: 16 -// CHECK: WavefrontNumSGPRs: 6 -// CHECK: WorkitemNumVGPRs: 12 +// CHECK: KernargSegmentSize: 24 +// CHECK: WorkitemPrivateSegmentSize: 16 +// CHECK: WavefrontNumSGPRs: 6 +// CHECK: WorkitemNumVGPRs: 12 .amdgpu_code_object_metadata Version: [ 1, 0 ] Printf: [ '1:1:4:%d\n', '2:1:8:%g\n' ] Index: llvm/trunk/test/MC/AMDGPU/code-object-metadata-kernel-debug-props.s =================================================================== --- llvm/trunk/test/MC/AMDGPU/code-object-metadata-kernel-debug-props.s +++ llvm/trunk/test/MC/AMDGPU/code-object-metadata-kernel-debug-props.s @@ -0,0 +1,26 @@ +// RUN: llvm-mc -triple=amdgcn-amd-amdhsa -mcpu=gfx700 -show-encoding %s | FileCheck --check-prefix=CHECK --check-prefix=GFX700 %s +// RUN: llvm-mc -triple=amdgcn-amd-amdhsa -mcpu=gfx800 -show-encoding %s | FileCheck --check-prefix=CHECK --check-prefix=GFX800 %s +// RUN: llvm-mc -triple=amdgcn-amd-amdhsa -mcpu=gfx900 -show-encoding %s | FileCheck --check-prefix=CHECK --check-prefix=GFX900 %s + +// CHECK: .amdgpu_code_object_metadata +// CHECK: Version: [ 1, 0 ] +// CHECK: Kernels: +// CHECK: - Name: test_kernel +// CHECK: DebugProps: +// CHECK: DebuggerABIVersion: [ 1, 0 ] +// CHECK: ReservedNumVGPRs: 4 +// CHECK: ReservedFirstVGPR: 11 +// CHECK: PrivateSegmentBufferSGPR: 0 +// CHECK: WavefrontPrivateSegmentOffsetSGPR: 11 +.amdgpu_code_object_metadata + Version: [ 1, 0 ] + Printf: [ '1:1:4:%d\n', '2:1:8:%g\n' ] + Kernels: + - Name: test_kernel + DebugProps: + DebuggerABIVersion: [ 1, 0 ] + ReservedNumVGPRs: 4 + ReservedFirstVGPR: 11 + PrivateSegmentBufferSGPR: 0 + WavefrontPrivateSegmentOffsetSGPR: 11 +.end_amdgpu_code_object_metadata \ No newline at end of file