10b57cec5SDimitry Andric //===-- AMDGPUPALMetadata.h - PAL metadata handling -------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric /// \file 100b57cec5SDimitry Andric /// PAL metadata handling 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUPALMETADATA_H 150b57cec5SDimitry Andric #define LLVM_LIB_TARGET_AMDGPU_AMDGPUPALMETADATA_H 160b57cec5SDimitry Andric #include "llvm/BinaryFormat/MsgPackDocument.h" 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric namespace llvm { 190b57cec5SDimitry Andric 200b57cec5SDimitry Andric class Module; 215ffd83dbSDimitry Andric class StringRef; 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric class AMDGPUPALMetadata { 240b57cec5SDimitry Andric unsigned BlobType = 0; 250b57cec5SDimitry Andric msgpack::Document MsgPackDoc; 260b57cec5SDimitry Andric msgpack::DocNode Registers; 270b57cec5SDimitry Andric msgpack::DocNode HwStages; 28e8d8bef9SDimitry Andric msgpack::DocNode ShaderFunctions; 2906c3fb27SDimitry Andric bool VersionChecked = false; 3006c3fb27SDimitry Andric msgpack::DocNode Version; 3106c3fb27SDimitry Andric // From PAL version >= 3.0 3206c3fb27SDimitry Andric msgpack::DocNode ComputeRegisters; 3306c3fb27SDimitry Andric msgpack::DocNode GraphicsRegisters; 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric public: 360b57cec5SDimitry Andric // Read the amdgpu.pal.metadata supplied by the frontend, ready for 370b57cec5SDimitry Andric // per-function modification. 380b57cec5SDimitry Andric void readFromIR(Module &M); 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric // Set PAL metadata from a binary blob from the applicable .note record. 410b57cec5SDimitry Andric // Returns false if bad format. Blob must remain valid for the lifetime of 420b57cec5SDimitry Andric // the Metadata. 430b57cec5SDimitry Andric bool setFromBlob(unsigned Type, StringRef Blob); 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric // Set the rsrc1 register in the metadata for a particular shader stage. 460b57cec5SDimitry Andric // In fact this ORs the value into any previous setting of the register. 470b57cec5SDimitry Andric void setRsrc1(unsigned CC, unsigned Val); 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric // Set the rsrc2 register in the metadata for a particular shader stage. 500b57cec5SDimitry Andric // In fact this ORs the value into any previous setting of the register. 510b57cec5SDimitry Andric void setRsrc2(unsigned CC, unsigned Val); 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric // Set the SPI_PS_INPUT_ENA register in the metadata. 540b57cec5SDimitry Andric // In fact this ORs the value into any previous setting of the register. 550b57cec5SDimitry Andric void setSpiPsInputEna(unsigned Val); 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric // Set the SPI_PS_INPUT_ADDR register in the metadata. 580b57cec5SDimitry Andric // In fact this ORs the value into any previous setting of the register. 590b57cec5SDimitry Andric void setSpiPsInputAddr(unsigned Val); 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric // Get a register from the metadata, or 0 if not currently set. 620b57cec5SDimitry Andric unsigned getRegister(unsigned Reg); 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric // Set a register in the metadata. 650b57cec5SDimitry Andric // In fact this ORs the value into any previous setting of the register. 660b57cec5SDimitry Andric void setRegister(unsigned Reg, unsigned Val); 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric // Set the entry point name for one shader. 690b57cec5SDimitry Andric void setEntryPoint(unsigned CC, StringRef Name); 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric // Set the number of used vgprs in the metadata. This is an optional advisory 720b57cec5SDimitry Andric // record for logging etc; wave dispatch actually uses the rsrc1 register for 730b57cec5SDimitry Andric // the shader stage to determine the number of vgprs to allocate. 740b57cec5SDimitry Andric void setNumUsedVgprs(unsigned CC, unsigned Val); 750b57cec5SDimitry Andric 7681ad6265SDimitry Andric // Set the number of used agprs in the metadata. This is an optional advisory 7781ad6265SDimitry Andric // record for logging etc; 7881ad6265SDimitry Andric void setNumUsedAgprs(unsigned CC, unsigned Val); 7981ad6265SDimitry Andric 800b57cec5SDimitry Andric // Set the number of used sgprs in the metadata. This is an optional advisory 810b57cec5SDimitry Andric // record for logging etc; wave dispatch actually uses the rsrc1 register for 820b57cec5SDimitry Andric // the shader stage to determine the number of sgprs to allocate. 830b57cec5SDimitry Andric void setNumUsedSgprs(unsigned CC, unsigned Val); 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric // Set the scratch size in the metadata. 860b57cec5SDimitry Andric void setScratchSize(unsigned CC, unsigned Val); 870b57cec5SDimitry Andric 88e8d8bef9SDimitry Andric // Set the stack frame size of a function in the metadata. 895f757f3fSDimitry Andric void setFunctionScratchSize(StringRef FnName, unsigned Val); 90e8d8bef9SDimitry Andric 91fe6060f1SDimitry Andric // Set the amount of LDS used in bytes in the metadata. This is an optional 92fe6060f1SDimitry Andric // advisory record for logging etc; wave dispatch actually uses the rsrc1 93fe6060f1SDimitry Andric // register for the shader stage to determine the amount of LDS to allocate. 945f757f3fSDimitry Andric void setFunctionLdsSize(StringRef FnName, unsigned Val); 95fe6060f1SDimitry Andric 96fe6060f1SDimitry Andric // Set the number of used vgprs in the metadata. This is an optional advisory 97fe6060f1SDimitry Andric // record for logging etc; wave dispatch actually uses the rsrc1 register for 98fe6060f1SDimitry Andric // the shader stage to determine the number of vgprs to allocate. 995f757f3fSDimitry Andric void setFunctionNumUsedVgprs(StringRef FnName, unsigned Val); 100fe6060f1SDimitry Andric 101fe6060f1SDimitry Andric // Set the number of used sgprs in the metadata. This is an optional advisory 102fe6060f1SDimitry Andric // record for logging etc; wave dispatch actually uses the rsrc1 register for 103fe6060f1SDimitry Andric // the shader stage to determine the number of sgprs to allocate. 1045f757f3fSDimitry Andric void setFunctionNumUsedSgprs(StringRef FnName, unsigned Val); 105fe6060f1SDimitry Andric 1060b57cec5SDimitry Andric // Set the hardware register bit in PAL metadata to enable wave32 on the 1070b57cec5SDimitry Andric // shader of the given calling convention. 1080b57cec5SDimitry Andric void setWave32(unsigned CC); 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric // Emit the accumulated PAL metadata as asm directives. 1110b57cec5SDimitry Andric // This is called from AMDGPUTargetAsmStreamer::Finish(). 1120b57cec5SDimitry Andric void toString(std::string &S); 1130b57cec5SDimitry Andric 1140b57cec5SDimitry Andric // Set PAL metadata from YAML text. 1150b57cec5SDimitry Andric bool setFromString(StringRef S); 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric // Get .note record vendor name of metadata blob to be emitted. 1180b57cec5SDimitry Andric const char *getVendor() const; 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric // Get .note record type of metadata blob to be emitted: 121fe6060f1SDimitry Andric // ELF::NT_AMD_PAL_METADATA (legacy key=val format), or 1220b57cec5SDimitry Andric // ELF::NT_AMDGPU_METADATA (MsgPack format), or 1230b57cec5SDimitry Andric // 0 (no PAL metadata). 1240b57cec5SDimitry Andric unsigned getType() const; 1250b57cec5SDimitry Andric 1260b57cec5SDimitry Andric // Emit the accumulated PAL metadata as a binary blob. 1270b57cec5SDimitry Andric // This is called from AMDGPUTargetELFStreamer::Finish(). 1280b57cec5SDimitry Andric void toBlob(unsigned Type, std::string &S); 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric // Get the msgpack::Document for the PAL metadata. getMsgPackDoc()1310b57cec5SDimitry Andric msgpack::Document *getMsgPackDoc() { return &MsgPackDoc; } 1320b57cec5SDimitry Andric 1330b57cec5SDimitry Andric // Set legacy PAL metadata format. 1340b57cec5SDimitry Andric void setLegacy(); 1350b57cec5SDimitry Andric 13606c3fb27SDimitry Andric unsigned getPALMajorVersion(); 13706c3fb27SDimitry Andric unsigned getPALMinorVersion(); 13806c3fb27SDimitry Andric 13906c3fb27SDimitry Andric void setHwStage(unsigned CC, StringRef field, unsigned Val); 14006c3fb27SDimitry Andric void setHwStage(unsigned CC, StringRef field, bool Val); 14106c3fb27SDimitry Andric 14206c3fb27SDimitry Andric void setComputeRegisters(StringRef field, unsigned Val); 14306c3fb27SDimitry Andric void setComputeRegisters(StringRef field, bool Val); 14406c3fb27SDimitry Andric 14506c3fb27SDimitry Andric // If the field does not exist will return nullptr rather than creating a new 14606c3fb27SDimitry Andric // entry (which is the behaviour of the other functions). 14706c3fb27SDimitry Andric msgpack::DocNode *refComputeRegister(StringRef field); 14806c3fb27SDimitry Andric bool checkComputeRegisters(StringRef field, unsigned Val); 14906c3fb27SDimitry Andric bool checkComputeRegisters(StringRef field, bool Val); 15006c3fb27SDimitry Andric 15106c3fb27SDimitry Andric void setGraphicsRegisters(StringRef field, unsigned Val); 15206c3fb27SDimitry Andric void setGraphicsRegisters(StringRef field, bool Val); 15306c3fb27SDimitry Andric void setGraphicsRegisters(StringRef field1, StringRef field2, unsigned Val); 15406c3fb27SDimitry Andric void setGraphicsRegisters(StringRef field1, StringRef field2, bool Val); 15506c3fb27SDimitry Andric 156e8d8bef9SDimitry Andric // Erase all PAL metadata. 157e8d8bef9SDimitry Andric void reset(); 158e8d8bef9SDimitry Andric 1590b57cec5SDimitry Andric private: 1600b57cec5SDimitry Andric // Return whether the blob type is legacy PAL metadata. 1610b57cec5SDimitry Andric bool isLegacy() const; 1620b57cec5SDimitry Andric 1630b57cec5SDimitry Andric // Reference (create if necessary) the node for the registers map. 1640b57cec5SDimitry Andric msgpack::DocNode &refRegisters(); 1650b57cec5SDimitry Andric 1660b57cec5SDimitry Andric // Get (create if necessary) the registers map. 1670b57cec5SDimitry Andric msgpack::MapDocNode getRegisters(); 1680b57cec5SDimitry Andric 169e8d8bef9SDimitry Andric // Reference (create if necessary) the node for the shader functions map. 170e8d8bef9SDimitry Andric msgpack::DocNode &refShaderFunctions(); 171e8d8bef9SDimitry Andric 172e8d8bef9SDimitry Andric // Get (create if necessary) the shader functions map. 173e8d8bef9SDimitry Andric msgpack::MapDocNode getShaderFunctions(); 174e8d8bef9SDimitry Andric 175e8d8bef9SDimitry Andric // Get (create if necessary) a function in the shader functions map. 176e8d8bef9SDimitry Andric msgpack::MapDocNode getShaderFunction(StringRef Name); 177e8d8bef9SDimitry Andric 17806c3fb27SDimitry Andric // Reference (create if necessary) the node for the compute_registers map. 17906c3fb27SDimitry Andric msgpack::DocNode &refComputeRegisters(); 18006c3fb27SDimitry Andric 18106c3fb27SDimitry Andric // Get (create if necessary) the .compute_registers entry. 18206c3fb27SDimitry Andric msgpack::MapDocNode getComputeRegisters(); 18306c3fb27SDimitry Andric 18406c3fb27SDimitry Andric // Reference (create if necessary) the node for the graphics registers map. 18506c3fb27SDimitry Andric msgpack::DocNode &refGraphicsRegisters(); 18606c3fb27SDimitry Andric 18706c3fb27SDimitry Andric // Get (create if necessary) the .graphics_registers entry. 18806c3fb27SDimitry Andric msgpack::MapDocNode getGraphicsRegisters(); 18906c3fb27SDimitry Andric 19006c3fb27SDimitry Andric // Reference (create if necessary) the node for the hardware_stages map. 19106c3fb27SDimitry Andric msgpack::DocNode &refHwStage(); 19206c3fb27SDimitry Andric 1930b57cec5SDimitry Andric // Get (create if necessary) the .hardware_stages entry for the given calling 1940b57cec5SDimitry Andric // convention. 1950b57cec5SDimitry Andric msgpack::MapDocNode getHwStage(unsigned CC); 1960b57cec5SDimitry Andric 19706c3fb27SDimitry Andric // Get the PAL version major (idx 0) or minor (idx 1). This is an internal 19806c3fb27SDimitry Andric // helper for the public wrapper functions that request Major or Minor 19906c3fb27SDimitry Andric unsigned getPALVersion(unsigned idx); 20006c3fb27SDimitry Andric 2010b57cec5SDimitry Andric bool setFromLegacyBlob(StringRef Blob); 2020b57cec5SDimitry Andric bool setFromMsgPackBlob(StringRef Blob); 2030b57cec5SDimitry Andric void toLegacyBlob(std::string &Blob); 2040b57cec5SDimitry Andric void toMsgPackBlob(std::string &Blob); 2050b57cec5SDimitry Andric }; 2060b57cec5SDimitry Andric 2070b57cec5SDimitry Andric } // end namespace llvm 2080b57cec5SDimitry Andric 2090b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_AMDGPU_AMDGPUPALMETADATA_H 210