[AMDGPU] Emit kernel debug properties as code object metadata
Differential Revision: https://reviews.llvm.org/D30969
llvm-svn: 298558
diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUCodeObjectMetadata.h b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUCodeObjectMetadata.h
index da89316..78c8754 100644
--- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUCodeObjectMetadata.h
+++ b/llvm/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<uint32_t> mDebuggerABIVersion = std::vector<uint32_t>();
+ /// \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<Arg::Metadata> mArgs = std::vector<Arg::Metadata>();
/// \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;
diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUCodeObjectMetadataStreamer.cpp b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUCodeObjectMetadataStreamer.cpp
index 4a24767..29f3602 100644
--- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUCodeObjectMetadataStreamer.cpp
+++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUCodeObjectMetadataStreamer.cpp
@@ -178,6 +178,22 @@
};
template <>
+struct MappingTraits<Kernel::DebugProps::Metadata> {
+ static void mapping(IO &YIO, Kernel::DebugProps::Metadata &MD) {
+ YIO.mapOptional(Kernel::DebugProps::Key::DebuggerABIVersion,
+ MD.mDebuggerABIVersion, std::vector<uint32_t>());
+ 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<Kernel::Metadata> {
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<std::string> MetadataStreamer::toYamlString() {
diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUCodeObjectMetadataStreamer.h b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUCodeObjectMetadataStreamer.h
index 5d51d6f..4d86d01 100644
--- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUCodeObjectMetadataStreamer.h
+++ b/llvm/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;