summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/AMDGPU/MCTargetDesc
diff options
context:
space:
mode:
authorYaxun Liu <Yaxun.Liu@amd.com>2016-11-10 21:18:49 +0000
committerYaxun Liu <Yaxun.Liu@amd.com>2016-11-10 21:18:49 +0000
commitd6fbe65040a91483035d7de8f7accd07449abfd4 (patch)
treeb829582cb75aed3cf96b6666b71dd09327eae98d /llvm/lib/Target/AMDGPU/MCTargetDesc
parent949f9b9f641720804832e460b5e04df47ec6b8a5 (diff)
downloadbcm5719-llvm-d6fbe65040a91483035d7de8f7accd07449abfd4.tar.gz
bcm5719-llvm-d6fbe65040a91483035d7de8f7accd07449abfd4.zip
AMDGPU: Emit runtime metadata as a note element in .note section
Currently runtime metadata is emitted as an ELF section with name .AMDGPU.runtime_metadata. However there is a standard way to convey vendor specific information about how to run an ELF binary, which is called vendor-specific note element (http://www.netbsd.org/docs/kernel/elf-notes.html). This patch lets AMDGPU backend emits runtime metadata as a note element in .note section. Differential Revision: https://reviews.llvm.org/D25781 llvm-svn: 286502
Diffstat (limited to 'llvm/lib/Target/AMDGPU/MCTargetDesc')
-rw-r--r--llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp378
-rw-r--r--llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.h49
2 files changed, 400 insertions, 27 deletions
diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp
index fe0d10ab797..de76328b52c 100644
--- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp
+++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp
@@ -11,11 +11,16 @@
//
//===----------------------------------------------------------------------===//
+#include "AMDGPU.h"
#include "AMDGPUTargetStreamer.h"
#include "SIDefines.h"
#include "Utils/AMDGPUBaseInfo.h"
#include "Utils/AMDKernelCodeTUtils.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCELFStreamer.h"
#include "llvm/MC/MCObjectFileInfo.h"
@@ -23,10 +28,15 @@
#include "llvm/Support/ELF.h"
#include "llvm/Support/FormattedStream.h"
+namespace llvm {
+#include "AMDGPUPTNote.h"
+}
+
using namespace llvm;
+using namespace llvm::AMDGPU;
AMDGPUTargetStreamer::AMDGPUTargetStreamer(MCStreamer &S)
- : MCTargetStreamer(S) { }
+ : MCTargetStreamer(S) {}
//===----------------------------------------------------------------------===//
// AMDGPUTargetAsmStreamer
@@ -86,10 +96,8 @@ void AMDGPUTargetAsmStreamer::EmitAMDGPUHsaProgramScopeGlobal(
// AMDGPUTargetELFStreamer
//===----------------------------------------------------------------------===//
-const char *AMDGPUTargetELFStreamer::NoteName = "AMD";
-
AMDGPUTargetELFStreamer::AMDGPUTargetELFStreamer(MCStreamer &S)
- : AMDGPUTargetStreamer(S), Streamer(S) { }
+ : AMDGPUTargetStreamer(S), Streamer(S) {}
MCELFStreamer &AMDGPUTargetELFStreamer::getStreamer() {
return static_cast<MCELFStreamer &>(Streamer);
@@ -100,16 +108,18 @@ AMDGPUTargetELFStreamer::EmitDirectiveHSACodeObjectVersion(uint32_t Major,
uint32_t Minor) {
MCStreamer &OS = getStreamer();
MCSectionELF *Note =
- OS.getContext().getELFSection(".note", ELF::SHT_NOTE, ELF::SHF_ALLOC);
+ OS.getContext().getELFSection(PT_NOTE::NoteName, ELF::SHT_NOTE,
+ ELF::SHF_ALLOC);
+ auto NameSZ = sizeof(PT_NOTE::NoteName);
OS.PushSection();
OS.SwitchSection(Note);
- OS.EmitIntValue(strlen(NoteName) + 1, 4); // namesz
- OS.EmitIntValue(8, 4); // descz
- OS.EmitIntValue(NT_AMDGPU_HSA_CODE_OBJECT_VERSION, 4); // type
- OS.EmitBytes(StringRef(NoteName, strlen(NoteName) + 1)); // name
+ OS.EmitIntValue(NameSZ, 4); // namesz
+ OS.EmitIntValue(8, 4); // descz
+ OS.EmitIntValue(PT_NOTE::NT_AMDGPU_HSA_CODE_OBJECT_VERSION, 4); // type
+ OS.EmitBytes(StringRef(PT_NOTE::NoteName, NameSZ)); // name
OS.EmitValueToAlignment(4);
- OS.EmitIntValue(Major, 4); // desc
+ OS.EmitIntValue(Major, 4); // desc
OS.EmitIntValue(Minor, 4);
OS.EmitValueToAlignment(4);
OS.PopSection();
@@ -123,7 +133,8 @@ AMDGPUTargetELFStreamer::EmitDirectiveHSACodeObjectISA(uint32_t Major,
StringRef ArchName) {
MCStreamer &OS = getStreamer();
MCSectionELF *Note =
- OS.getContext().getELFSection(".note", ELF::SHT_NOTE, ELF::SHF_ALLOC);
+ OS.getContext().getELFSection(PT_NOTE::NoteName, ELF::SHT_NOTE,
+ ELF::SHF_ALLOC);
uint16_t VendorNameSize = VendorName.size() + 1;
uint16_t ArchNameSize = ArchName.size() + 1;
@@ -133,10 +144,11 @@ AMDGPUTargetELFStreamer::EmitDirectiveHSACodeObjectISA(uint32_t Major,
OS.PushSection();
OS.SwitchSection(Note);
- OS.EmitIntValue(strlen(NoteName) + 1, 4); // namesz
+ auto NameSZ = sizeof(PT_NOTE::NoteName);
+ OS.EmitIntValue(NameSZ, 4); // namesz
OS.EmitIntValue(DescSZ, 4); // descsz
- OS.EmitIntValue(NT_AMDGPU_HSA_ISA, 4); // type
- OS.EmitBytes(StringRef(NoteName, strlen(NoteName) + 1)); // name
+ OS.EmitIntValue(PT_NOTE::NT_AMDGPU_HSA_ISA, 4); // type
+ OS.EmitBytes(StringRef(PT_NOTE::NoteName, NameSZ)); // name
OS.EmitValueToAlignment(4);
OS.EmitIntValue(VendorNameSize, 2); // desc
OS.EmitIntValue(ArchNameSize, 2);
@@ -184,3 +196,341 @@ void AMDGPUTargetELFStreamer::EmitAMDGPUHsaProgramScopeGlobal(
Symbol->setType(ELF::STT_OBJECT);
Symbol->setBinding(ELF::STB_GLOBAL);
}
+
+void AMDGPUTargetStreamer::emitRuntimeMDIntValue(RuntimeMD::Key K, uint64_t V,
+ unsigned Size) {
+ auto &S = getStreamer();
+ S.EmitIntValue(K, 1);
+ S.EmitIntValue(V, Size);
+}
+
+void AMDGPUTargetStreamer::emitRuntimeMDStringValue(RuntimeMD::Key K,
+ StringRef R) {
+ auto &S = getStreamer();
+ S.EmitIntValue(K, 1);
+ S.EmitIntValue(R.size(), 4);
+ S.EmitBytes(R);
+}
+
+void AMDGPUTargetStreamer::emitRuntimeMDThreeIntValues(RuntimeMD::Key K,
+ MDNode *Node,
+ unsigned Size) {
+ assert(Node->getNumOperands() == 3);
+
+ auto &S = getStreamer();
+ S.EmitIntValue(K, 1);
+ for (const MDOperand &Op : Node->operands()) {
+ const ConstantInt *CI = mdconst::extract<ConstantInt>(Op);
+ S.EmitIntValue(CI->getZExtValue(), Size);
+ }
+}
+
+void AMDGPUTargetStreamer::emitStartOfRuntimeMetadata(const Module &M) {
+ emitRuntimeMDIntValue(RuntimeMD::KeyMDVersion,
+ RuntimeMD::MDVersion << 8 | RuntimeMD::MDRevision, 2);
+ if (auto MD = M.getNamedMetadata("opencl.ocl.version")) {
+ if (MD->getNumOperands() != 0) {
+ auto Node = MD->getOperand(0);
+ if (Node->getNumOperands() > 1) {
+ emitRuntimeMDIntValue(RuntimeMD::KeyLanguage,
+ RuntimeMD::OpenCL_C, 1);
+ uint16_t Major = mdconst::extract<ConstantInt>(Node->getOperand(0))
+ ->getZExtValue();
+ uint16_t Minor = mdconst::extract<ConstantInt>(Node->getOperand(1))
+ ->getZExtValue();
+ emitRuntimeMDIntValue(RuntimeMD::KeyLanguageVersion,
+ Major * 100 + Minor * 10, 2);
+ }
+ }
+ }
+
+ if (auto MD = M.getNamedMetadata("llvm.printf.fmts")) {
+ for (unsigned I = 0; I < MD->getNumOperands(); ++I) {
+ auto Node = MD->getOperand(I);
+ if (Node->getNumOperands() > 0)
+ emitRuntimeMDStringValue(RuntimeMD::KeyPrintfInfo,
+ cast<MDString>(Node->getOperand(0))->getString());
+ }
+ }
+}
+
+static std::string getOCLTypeName(Type *Ty, bool Signed) {
+ switch (Ty->getTypeID()) {
+ case Type::HalfTyID:
+ return "half";
+ case Type::FloatTyID:
+ return "float";
+ case Type::DoubleTyID:
+ return "double";
+ case Type::IntegerTyID: {
+ if (!Signed)
+ return (Twine('u') + getOCLTypeName(Ty, true)).str();
+ unsigned BW = Ty->getIntegerBitWidth();
+ switch (BW) {
+ case 8:
+ return "char";
+ case 16:
+ return "short";
+ case 32:
+ return "int";
+ case 64:
+ return "long";
+ default:
+ return (Twine('i') + Twine(BW)).str();
+ }
+ }
+ case Type::VectorTyID: {
+ VectorType *VecTy = cast<VectorType>(Ty);
+ Type *EleTy = VecTy->getElementType();
+ unsigned Size = VecTy->getVectorNumElements();
+ return (Twine(getOCLTypeName(EleTy, Signed)) + Twine(Size)).str();
+ }
+ default:
+ return "unknown";
+ }
+}
+
+static RuntimeMD::KernelArg::ValueType getRuntimeMDValueType(
+ Type *Ty, StringRef TypeName) {
+ switch (Ty->getTypeID()) {
+ case Type::HalfTyID:
+ return RuntimeMD::KernelArg::F16;
+ case Type::FloatTyID:
+ return RuntimeMD::KernelArg::F32;
+ case Type::DoubleTyID:
+ return RuntimeMD::KernelArg::F64;
+ case Type::IntegerTyID: {
+ bool Signed = !TypeName.startswith("u");
+ switch (Ty->getIntegerBitWidth()) {
+ case 8:
+ return Signed ? RuntimeMD::KernelArg::I8 : RuntimeMD::KernelArg::U8;
+ case 16:
+ return Signed ? RuntimeMD::KernelArg::I16 : RuntimeMD::KernelArg::U16;
+ case 32:
+ return Signed ? RuntimeMD::KernelArg::I32 : RuntimeMD::KernelArg::U32;
+ case 64:
+ return Signed ? RuntimeMD::KernelArg::I64 : RuntimeMD::KernelArg::U64;
+ default:
+ // Runtime does not recognize other integer types. Report as struct type.
+ return RuntimeMD::KernelArg::Struct;
+ }
+ }
+ case Type::VectorTyID:
+ return getRuntimeMDValueType(Ty->getVectorElementType(), TypeName);
+ case Type::PointerTyID:
+ return getRuntimeMDValueType(Ty->getPointerElementType(), TypeName);
+ default:
+ return RuntimeMD::KernelArg::Struct;
+ }
+}
+
+static RuntimeMD::KernelArg::AddressSpaceQualifer getRuntimeAddrSpace(
+ AMDGPUAS::AddressSpaces A) {
+ switch (A) {
+ case AMDGPUAS::GLOBAL_ADDRESS:
+ return RuntimeMD::KernelArg::Global;
+ case AMDGPUAS::CONSTANT_ADDRESS:
+ return RuntimeMD::KernelArg::Constant;
+ case AMDGPUAS::LOCAL_ADDRESS:
+ return RuntimeMD::KernelArg::Local;
+ case AMDGPUAS::FLAT_ADDRESS:
+ return RuntimeMD::KernelArg::Generic;
+ case AMDGPUAS::REGION_ADDRESS:
+ return RuntimeMD::KernelArg::Region;
+ default:
+ return RuntimeMD::KernelArg::Private;
+ }
+}
+
+void AMDGPUTargetStreamer::emitRuntimeMetadataForKernelArg(const DataLayout &DL,
+ Type *T, RuntimeMD::KernelArg::Kind Kind,
+ StringRef BaseTypeName, StringRef TypeName,
+ StringRef ArgName, StringRef TypeQual, StringRef AccQual) {
+ auto &S = getStreamer();
+
+ // Emit KeyArgBegin.
+ S.EmitIntValue(RuntimeMD::KeyArgBegin, 1);
+
+ // Emit KeyArgSize and KeyArgAlign.
+ emitRuntimeMDIntValue(RuntimeMD::KeyArgSize,
+ DL.getTypeAllocSize(T), 4);
+ emitRuntimeMDIntValue(RuntimeMD::KeyArgAlign,
+ DL.getABITypeAlignment(T), 4);
+ if (auto PT = dyn_cast<PointerType>(T)) {
+ auto ET = PT->getElementType();
+ if (PT->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS && ET->isSized())
+ emitRuntimeMDIntValue(RuntimeMD::KeyArgPointeeAlign,
+ DL.getABITypeAlignment(ET), 4);
+ }
+
+ // Emit KeyArgTypeName.
+ if (!TypeName.empty())
+ emitRuntimeMDStringValue(RuntimeMD::KeyArgTypeName, TypeName);
+
+ // Emit KeyArgName.
+ if (!ArgName.empty())
+ emitRuntimeMDStringValue(RuntimeMD::KeyArgName, ArgName);
+
+ // Emit KeyArgIsVolatile, KeyArgIsRestrict, KeyArgIsConst and KeyArgIsPipe.
+ SmallVector<StringRef, 1> SplitQ;
+ TypeQual.split(SplitQ, " ", -1, false /* Drop empty entry */);
+
+ for (StringRef KeyName : SplitQ) {
+ auto Key = StringSwitch<RuntimeMD::Key>(KeyName)
+ .Case("volatile", RuntimeMD::KeyArgIsVolatile)
+ .Case("restrict", RuntimeMD::KeyArgIsRestrict)
+ .Case("const", RuntimeMD::KeyArgIsConst)
+ .Case("pipe", RuntimeMD::KeyArgIsPipe)
+ .Default(RuntimeMD::KeyNull);
+ S.EmitIntValue(Key, 1);
+ }
+
+ // Emit KeyArgKind.
+ emitRuntimeMDIntValue(RuntimeMD::KeyArgKind, Kind, 1);
+
+ // Emit KeyArgValueType.
+ emitRuntimeMDIntValue(RuntimeMD::KeyArgValueType,
+ getRuntimeMDValueType(T, BaseTypeName), 2);
+
+ // Emit KeyArgAccQual.
+ if (!AccQual.empty()) {
+ auto AQ = StringSwitch<RuntimeMD::KernelArg::AccessQualifer>(AccQual)
+ .Case("read_only", RuntimeMD::KernelArg::ReadOnly)
+ .Case("write_only", RuntimeMD::KernelArg::WriteOnly)
+ .Case("read_write", RuntimeMD::KernelArg::ReadWrite)
+ .Default(RuntimeMD::KernelArg::None);
+ emitRuntimeMDIntValue(RuntimeMD::KeyArgAccQual, AQ, 1);
+ }
+
+ // Emit KeyArgAddrQual.
+ if (auto *PT = dyn_cast<PointerType>(T))
+ emitRuntimeMDIntValue(RuntimeMD::KeyArgAddrQual,
+ getRuntimeAddrSpace(static_cast<AMDGPUAS::AddressSpaces>(
+ PT->getAddressSpace())), 1);
+
+ // Emit KeyArgEnd
+ S.EmitIntValue(RuntimeMD::KeyArgEnd, 1);
+}
+
+void AMDGPUTargetStreamer::emitRuntimeMetadata(const Function &F) {
+ if (!F.getMetadata("kernel_arg_type"))
+ return;
+ auto &S = getStreamer();
+ S.EmitIntValue(RuntimeMD::KeyKernelBegin, 1);
+ emitRuntimeMDStringValue(RuntimeMD::KeyKernelName, F.getName());
+
+ const DataLayout &DL = F.getParent()->getDataLayout();
+ for (auto &Arg : F.args()) {
+ unsigned I = Arg.getArgNo();
+ Type *T = Arg.getType();
+ auto TypeName = dyn_cast<MDString>(F.getMetadata(
+ "kernel_arg_type")->getOperand(I))->getString();
+ auto BaseTypeName = cast<MDString>(F.getMetadata(
+ "kernel_arg_base_type")->getOperand(I))->getString();
+ StringRef ArgName;
+ if (auto ArgNameMD = F.getMetadata("kernel_arg_name"))
+ ArgName = cast<MDString>(ArgNameMD->getOperand(I))->getString();
+ auto TypeQual = cast<MDString>(F.getMetadata(
+ "kernel_arg_type_qual")->getOperand(I))->getString();
+ auto AccQual = cast<MDString>(F.getMetadata(
+ "kernel_arg_access_qual")->getOperand(I))->getString();
+ RuntimeMD::KernelArg::Kind Kind;
+ if (TypeQual.find("pipe") != StringRef::npos)
+ Kind = RuntimeMD::KernelArg::Pipe;
+ else Kind = StringSwitch<RuntimeMD::KernelArg::Kind>(BaseTypeName)
+ .Case("sampler_t", RuntimeMD::KernelArg::Sampler)
+ .Case("queue_t", RuntimeMD::KernelArg::Queue)
+ .Cases("image1d_t", "image1d_array_t", "image1d_buffer_t",
+ "image2d_t" , "image2d_array_t", RuntimeMD::KernelArg::Image)
+ .Cases("image2d_depth_t", "image2d_array_depth_t",
+ "image2d_msaa_t", "image2d_array_msaa_t",
+ "image2d_msaa_depth_t", RuntimeMD::KernelArg::Image)
+ .Cases("image2d_array_msaa_depth_t", "image3d_t",
+ RuntimeMD::KernelArg::Image)
+ .Default(isa<PointerType>(T) ?
+ (T->getPointerAddressSpace() == AMDGPUAS::LOCAL_ADDRESS ?
+ RuntimeMD::KernelArg::DynamicSharedPointer :
+ RuntimeMD::KernelArg::GlobalBuffer) :
+ RuntimeMD::KernelArg::ByValue);
+ emitRuntimeMetadataForKernelArg(DL, T,
+ Kind, BaseTypeName, TypeName, ArgName, TypeQual, AccQual);
+ }
+
+ // Emit hidden kernel arguments for OpenCL kernels.
+ if (F.getParent()->getNamedMetadata("opencl.ocl.version")) {
+ auto Int64T = Type::getInt64Ty(F.getContext());
+ emitRuntimeMetadataForKernelArg(DL, Int64T,
+ RuntimeMD::KernelArg::HiddenGlobalOffsetX);
+ emitRuntimeMetadataForKernelArg(DL, Int64T,
+ RuntimeMD::KernelArg::HiddenGlobalOffsetY);
+ emitRuntimeMetadataForKernelArg(DL, Int64T,
+ RuntimeMD::KernelArg::HiddenGlobalOffsetZ);
+ if (F.getParent()->getNamedMetadata("llvm.printf.fmts")) {
+ auto Int8PtrT = Type::getInt8PtrTy(F.getContext(),
+ RuntimeMD::KernelArg::Global);
+ emitRuntimeMetadataForKernelArg(DL, Int8PtrT,
+ RuntimeMD::KernelArg::HiddenPrintfBuffer);
+ }
+ }
+
+ // Emit KeyReqdWorkGroupSize, KeyWorkGroupSizeHint, and KeyVecTypeHint.
+ if (auto RWGS = F.getMetadata("reqd_work_group_size")) {
+ emitRuntimeMDThreeIntValues(RuntimeMD::KeyReqdWorkGroupSize,
+ RWGS, 4);
+ }
+
+ if (auto WGSH = F.getMetadata("work_group_size_hint")) {
+ emitRuntimeMDThreeIntValues(RuntimeMD::KeyWorkGroupSizeHint,
+ WGSH, 4);
+ }
+
+ if (auto VTH = F.getMetadata("vec_type_hint")) {
+ auto TypeName = getOCLTypeName(cast<ValueAsMetadata>(
+ VTH->getOperand(0))->getType(), mdconst::extract<ConstantInt>(
+ VTH->getOperand(1))->getZExtValue());
+ emitRuntimeMDStringValue(RuntimeMD::KeyVecTypeHint, TypeName);
+ }
+
+ // Emit KeyKernelEnd
+ S.EmitIntValue(RuntimeMD::KeyKernelEnd, 1);
+}
+
+void AMDGPUTargetStreamer::emitRuntimeMetadataAsNoteElement(Module &M) {
+ auto &S = getStreamer();
+ auto &Context = S.getContext();
+
+ auto NameSZ = sizeof(PT_NOTE::NoteName); // Size of note name including trailing null.
+
+ S.PushSection();
+ S.SwitchSection(Context.getELFSection(
+ PT_NOTE::SectionName, ELF::SHT_NOTE, ELF::SHF_ALLOC));
+
+ // Create two labels to mark the beginning and end of the desc field
+ // and a MCExpr to calculate the size of the desc field.
+ auto *DescBegin = Context.createTempSymbol();
+ auto *DescEnd = Context.createTempSymbol();
+ auto *DescSZ = MCBinaryExpr::createSub(
+ MCSymbolRefExpr::create(DescEnd, Context),
+ MCSymbolRefExpr::create(DescBegin, Context), Context);
+
+ // Emit the note element for runtime metadata.
+ // Name and desc should be padded to 4 byte boundary but size of name and
+ // desc should not include padding 0's.
+ S.EmitIntValue(NameSZ, 4); // namesz
+ S.EmitValue(DescSZ, 4); // descz
+ S.EmitIntValue(PT_NOTE::NT_AMDGPU_HSA_RUNTIME_METADATA, 4); // type
+ S.EmitBytes(StringRef(PT_NOTE::NoteName, NameSZ)); // name
+ S.EmitValueToAlignment(4); // padding 0
+ S.EmitLabel(DescBegin);
+ emitRuntimeMetadata(M); // desc
+ S.EmitLabel(DescEnd);
+ S.EmitValueToAlignment(4); // padding 0
+ S.PopSection();
+}
+
+void AMDGPUTargetStreamer::emitRuntimeMetadata(Module &M) {
+ emitStartOfRuntimeMetadata(M);
+ for (auto &F : M.functions())
+ emitRuntimeMetadata(F);
+}
+
diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.h b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.h
index 809400d2fe7..1dd54dd8286 100644
--- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.h
+++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.h
@@ -14,9 +14,15 @@
#include "llvm/MC/MCStreamer.h"
namespace llvm {
+#include "AMDGPURuntimeMetadata.h"
+class DataLayout;
+class Function;
class MCELFStreamer;
class MCSymbol;
+class MDNode;
+class Module;
+class Type;
class AMDGPUTargetStreamer : public MCTargetStreamer {
public:
@@ -36,6 +42,36 @@ public:
virtual void EmitAMDGPUHsaModuleScopeGlobal(StringRef GlobalName) = 0;
virtual void EmitAMDGPUHsaProgramScopeGlobal(StringRef GlobalName) = 0;
+
+ /// Emit runtime metadata as a note element.
+ void emitRuntimeMetadataAsNoteElement(Module &M);
+
+private:
+ void emitRuntimeMetadata(Module &M);
+ void emitStartOfRuntimeMetadata(const Module &M);
+
+ /// Emit runtime metadata for a kernel function.
+ void emitRuntimeMetadata(const Function &F);
+
+ // Emit runtime metadata for a kernel argument.
+ void emitRuntimeMetadataForKernelArg(const DataLayout &DL,
+ Type *T, AMDGPU::RuntimeMD::KernelArg::Kind Kind,
+ StringRef BaseTypeName = "", StringRef TypeName = "",
+ StringRef ArgName = "", StringRef TypeQual = "",
+ StringRef AccQual = "");
+
+ /// Emit a key and an integer value for runtime metadata.
+ void emitRuntimeMDIntValue(AMDGPU::RuntimeMD::Key K,
+ uint64_t V, unsigned Size);
+
+ /// Emit a key and a string value for runtime metadata.
+ void emitRuntimeMDStringValue(AMDGPU::RuntimeMD::Key K,
+ StringRef S);
+
+ /// Emit a key and three integer values for runtime metadata.
+ /// The three integer values are obtained from MDNode \p Node;
+ void emitRuntimeMDThreeIntValues(AMDGPU::RuntimeMD::Key K, MDNode *Node,
+ unsigned Size);
};
class AMDGPUTargetAsmStreamer : public AMDGPUTargetStreamer {
@@ -59,19 +95,6 @@ public:
};
class AMDGPUTargetELFStreamer : public AMDGPUTargetStreamer {
-
- enum NoteType {
- NT_AMDGPU_HSA_CODE_OBJECT_VERSION = 1,
- NT_AMDGPU_HSA_HSAIL = 2,
- NT_AMDGPU_HSA_ISA = 3,
- NT_AMDGPU_HSA_PRODUCER = 4,
- NT_AMDGPU_HSA_PRODUCER_OPTIONS = 5,
- NT_AMDGPU_HSA_EXTENSION = 6,
- NT_AMDGPU_HSA_HLDEBUG_DEBUG = 101,
- NT_AMDGPU_HSA_HLDEBUG_TARGET = 102
- };
-
- static const char *NoteName;
MCStreamer &Streamer;
public:
OpenPOWER on IntegriCloud