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 16*0fca6ea1SDimitry Andric #include "AMDGPUDelayedMCExpr.h" 17*0fca6ea1SDimitry Andric #include "llvm/ADT/DenseMap.h" 180b57cec5SDimitry Andric #include "llvm/BinaryFormat/MsgPackDocument.h" 19*0fca6ea1SDimitry Andric #include "llvm/MC/MCContext.h" 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric namespace llvm { 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric class Module; 245ffd83dbSDimitry Andric class StringRef; 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric class AMDGPUPALMetadata { 27*0fca6ea1SDimitry Andric public: 28*0fca6ea1SDimitry Andric using RegisterExprMap = DenseMap<unsigned, const MCExpr *>; 29*0fca6ea1SDimitry Andric 30*0fca6ea1SDimitry Andric private: 310b57cec5SDimitry Andric unsigned BlobType = 0; 320b57cec5SDimitry Andric msgpack::Document MsgPackDoc; 330b57cec5SDimitry Andric msgpack::DocNode Registers; 340b57cec5SDimitry Andric msgpack::DocNode HwStages; 35e8d8bef9SDimitry Andric msgpack::DocNode ShaderFunctions; 3606c3fb27SDimitry Andric bool VersionChecked = false; 3706c3fb27SDimitry Andric msgpack::DocNode Version; 3806c3fb27SDimitry Andric // From PAL version >= 3.0 3906c3fb27SDimitry Andric msgpack::DocNode ComputeRegisters; 4006c3fb27SDimitry Andric msgpack::DocNode GraphicsRegisters; 410b57cec5SDimitry Andric 42*0fca6ea1SDimitry Andric DelayedMCExprs DelayedExprs; 43*0fca6ea1SDimitry Andric RegisterExprMap REM; 44*0fca6ea1SDimitry Andric bool ResolvedAll = true; 45*0fca6ea1SDimitry Andric 460b57cec5SDimitry Andric public: 470b57cec5SDimitry Andric // Read the amdgpu.pal.metadata supplied by the frontend, ready for 480b57cec5SDimitry Andric // per-function modification. 490b57cec5SDimitry Andric void readFromIR(Module &M); 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric // Set PAL metadata from a binary blob from the applicable .note record. 520b57cec5SDimitry Andric // Returns false if bad format. Blob must remain valid for the lifetime of 530b57cec5SDimitry Andric // the Metadata. 540b57cec5SDimitry Andric bool setFromBlob(unsigned Type, StringRef Blob); 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric // Set the rsrc1 register in the metadata for a particular shader stage. 570b57cec5SDimitry Andric // In fact this ORs the value into any previous setting of the register. 580b57cec5SDimitry Andric void setRsrc1(unsigned CC, unsigned Val); 59*0fca6ea1SDimitry Andric void setRsrc1(unsigned CC, const MCExpr *Val, MCContext &Ctx); 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric // Set the rsrc2 register in the metadata for a particular shader stage. 620b57cec5SDimitry Andric // In fact this ORs the value into any previous setting of the register. 630b57cec5SDimitry Andric void setRsrc2(unsigned CC, unsigned Val); 64*0fca6ea1SDimitry Andric void setRsrc2(unsigned CC, const MCExpr *Val, MCContext &Ctx); 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric // Set the SPI_PS_INPUT_ENA register in the metadata. 670b57cec5SDimitry Andric // In fact this ORs the value into any previous setting of the register. 680b57cec5SDimitry Andric void setSpiPsInputEna(unsigned Val); 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric // Set the SPI_PS_INPUT_ADDR register in the metadata. 710b57cec5SDimitry Andric // In fact this ORs the value into any previous setting of the register. 720b57cec5SDimitry Andric void setSpiPsInputAddr(unsigned Val); 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric // Get a register from the metadata, or 0 if not currently set. 750b57cec5SDimitry Andric unsigned getRegister(unsigned Reg); 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric // Set a register in the metadata. 780b57cec5SDimitry Andric // In fact this ORs the value into any previous setting of the register. 790b57cec5SDimitry Andric void setRegister(unsigned Reg, unsigned Val); 80*0fca6ea1SDimitry Andric void setRegister(unsigned Reg, const MCExpr *Val, MCContext &Ctx); 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric // Set the entry point name for one shader. 830b57cec5SDimitry Andric void setEntryPoint(unsigned CC, StringRef Name); 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric // Set the number of used vgprs in the metadata. This is an optional advisory 860b57cec5SDimitry Andric // record for logging etc; wave dispatch actually uses the rsrc1 register for 870b57cec5SDimitry Andric // the shader stage to determine the number of vgprs to allocate. 880b57cec5SDimitry Andric void setNumUsedVgprs(unsigned CC, unsigned Val); 89*0fca6ea1SDimitry Andric void setNumUsedVgprs(unsigned CC, const MCExpr *Val, MCContext &Ctx); 900b57cec5SDimitry Andric 9181ad6265SDimitry Andric // Set the number of used agprs in the metadata. This is an optional advisory 9281ad6265SDimitry Andric // record for logging etc; 9381ad6265SDimitry Andric void setNumUsedAgprs(unsigned CC, unsigned Val); 94*0fca6ea1SDimitry Andric void setNumUsedAgprs(unsigned CC, const MCExpr *Val); 9581ad6265SDimitry Andric 960b57cec5SDimitry Andric // Set the number of used sgprs in the metadata. This is an optional advisory 970b57cec5SDimitry Andric // record for logging etc; wave dispatch actually uses the rsrc1 register for 980b57cec5SDimitry Andric // the shader stage to determine the number of sgprs to allocate. 990b57cec5SDimitry Andric void setNumUsedSgprs(unsigned CC, unsigned Val); 100*0fca6ea1SDimitry Andric void setNumUsedSgprs(unsigned CC, const MCExpr *Val, MCContext &Ctx); 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric // Set the scratch size in the metadata. 1030b57cec5SDimitry Andric void setScratchSize(unsigned CC, unsigned Val); 104*0fca6ea1SDimitry Andric void setScratchSize(unsigned CC, const MCExpr *Val, MCContext &Ctx); 1050b57cec5SDimitry Andric 106e8d8bef9SDimitry Andric // Set the stack frame size of a function in the metadata. 1075f757f3fSDimitry Andric void setFunctionScratchSize(StringRef FnName, unsigned Val); 108e8d8bef9SDimitry Andric 109fe6060f1SDimitry Andric // Set the amount of LDS used in bytes in the metadata. This is an optional 110fe6060f1SDimitry Andric // advisory record for logging etc; wave dispatch actually uses the rsrc1 111fe6060f1SDimitry Andric // register for the shader stage to determine the amount of LDS to allocate. 1125f757f3fSDimitry Andric void setFunctionLdsSize(StringRef FnName, unsigned Val); 113fe6060f1SDimitry Andric 114fe6060f1SDimitry Andric // Set the number of used vgprs in the metadata. This is an optional advisory 115fe6060f1SDimitry Andric // record for logging etc; wave dispatch actually uses the rsrc1 register for 116fe6060f1SDimitry Andric // the shader stage to determine the number of vgprs to allocate. 1175f757f3fSDimitry Andric void setFunctionNumUsedVgprs(StringRef FnName, unsigned Val); 118*0fca6ea1SDimitry Andric void setFunctionNumUsedVgprs(StringRef FnName, const MCExpr *Val); 119fe6060f1SDimitry Andric 120fe6060f1SDimitry Andric // Set the number of used sgprs in the metadata. This is an optional advisory 121fe6060f1SDimitry Andric // record for logging etc; wave dispatch actually uses the rsrc1 register for 122fe6060f1SDimitry Andric // the shader stage to determine the number of sgprs to allocate. 1235f757f3fSDimitry Andric void setFunctionNumUsedSgprs(StringRef FnName, unsigned Val); 124*0fca6ea1SDimitry Andric void setFunctionNumUsedSgprs(StringRef FnName, const MCExpr *Val); 125fe6060f1SDimitry Andric 1260b57cec5SDimitry Andric // Set the hardware register bit in PAL metadata to enable wave32 on the 1270b57cec5SDimitry Andric // shader of the given calling convention. 1280b57cec5SDimitry Andric void setWave32(unsigned CC); 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric // Emit the accumulated PAL metadata as asm directives. 1310b57cec5SDimitry Andric // This is called from AMDGPUTargetAsmStreamer::Finish(). 1320b57cec5SDimitry Andric void toString(std::string &S); 1330b57cec5SDimitry Andric 1340b57cec5SDimitry Andric // Set PAL metadata from YAML text. 1350b57cec5SDimitry Andric bool setFromString(StringRef S); 1360b57cec5SDimitry Andric 1370b57cec5SDimitry Andric // Get .note record vendor name of metadata blob to be emitted. 1380b57cec5SDimitry Andric const char *getVendor() const; 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andric // Get .note record type of metadata blob to be emitted: 141fe6060f1SDimitry Andric // ELF::NT_AMD_PAL_METADATA (legacy key=val format), or 1420b57cec5SDimitry Andric // ELF::NT_AMDGPU_METADATA (MsgPack format), or 1430b57cec5SDimitry Andric // 0 (no PAL metadata). 1440b57cec5SDimitry Andric unsigned getType() const; 1450b57cec5SDimitry Andric 1460b57cec5SDimitry Andric // Emit the accumulated PAL metadata as a binary blob. 1470b57cec5SDimitry Andric // This is called from AMDGPUTargetELFStreamer::Finish(). 1480b57cec5SDimitry Andric void toBlob(unsigned Type, std::string &S); 1490b57cec5SDimitry Andric 1500b57cec5SDimitry Andric // Get the msgpack::Document for the PAL metadata. 1510b57cec5SDimitry Andric msgpack::Document *getMsgPackDoc() { return &MsgPackDoc; } 1520b57cec5SDimitry Andric 1530b57cec5SDimitry Andric // Set legacy PAL metadata format. 1540b57cec5SDimitry Andric void setLegacy(); 1550b57cec5SDimitry Andric 15606c3fb27SDimitry Andric unsigned getPALMajorVersion(); 15706c3fb27SDimitry Andric unsigned getPALMinorVersion(); 15806c3fb27SDimitry Andric 15906c3fb27SDimitry Andric void setHwStage(unsigned CC, StringRef field, unsigned Val); 16006c3fb27SDimitry Andric void setHwStage(unsigned CC, StringRef field, bool Val); 161*0fca6ea1SDimitry Andric void setHwStage(unsigned CC, StringRef field, msgpack::Type Type, 162*0fca6ea1SDimitry Andric const MCExpr *Val); 16306c3fb27SDimitry Andric 16406c3fb27SDimitry Andric void setComputeRegisters(StringRef field, unsigned Val); 16506c3fb27SDimitry Andric void setComputeRegisters(StringRef field, bool Val); 16606c3fb27SDimitry Andric 16706c3fb27SDimitry Andric // If the field does not exist will return nullptr rather than creating a new 16806c3fb27SDimitry Andric // entry (which is the behaviour of the other functions). 16906c3fb27SDimitry Andric msgpack::DocNode *refComputeRegister(StringRef field); 17006c3fb27SDimitry Andric bool checkComputeRegisters(StringRef field, unsigned Val); 17106c3fb27SDimitry Andric bool checkComputeRegisters(StringRef field, bool Val); 17206c3fb27SDimitry Andric 17306c3fb27SDimitry Andric void setGraphicsRegisters(StringRef field, unsigned Val); 17406c3fb27SDimitry Andric void setGraphicsRegisters(StringRef field, bool Val); 17506c3fb27SDimitry Andric void setGraphicsRegisters(StringRef field1, StringRef field2, unsigned Val); 17606c3fb27SDimitry Andric void setGraphicsRegisters(StringRef field1, StringRef field2, bool Val); 17706c3fb27SDimitry Andric 178e8d8bef9SDimitry Andric // Erase all PAL metadata. 179e8d8bef9SDimitry Andric void reset(); 180e8d8bef9SDimitry Andric 181*0fca6ea1SDimitry Andric bool resolvedAllMCExpr(); 182*0fca6ea1SDimitry Andric 1830b57cec5SDimitry Andric private: 1840b57cec5SDimitry Andric // Return whether the blob type is legacy PAL metadata. 1850b57cec5SDimitry Andric bool isLegacy() const; 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric // Reference (create if necessary) the node for the registers map. 1880b57cec5SDimitry Andric msgpack::DocNode &refRegisters(); 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andric // Get (create if necessary) the registers map. 1910b57cec5SDimitry Andric msgpack::MapDocNode getRegisters(); 1920b57cec5SDimitry Andric 193e8d8bef9SDimitry Andric // Reference (create if necessary) the node for the shader functions map. 194e8d8bef9SDimitry Andric msgpack::DocNode &refShaderFunctions(); 195e8d8bef9SDimitry Andric 196e8d8bef9SDimitry Andric // Get (create if necessary) the shader functions map. 197e8d8bef9SDimitry Andric msgpack::MapDocNode getShaderFunctions(); 198e8d8bef9SDimitry Andric 199e8d8bef9SDimitry Andric // Get (create if necessary) a function in the shader functions map. 200e8d8bef9SDimitry Andric msgpack::MapDocNode getShaderFunction(StringRef Name); 201e8d8bef9SDimitry Andric 20206c3fb27SDimitry Andric // Reference (create if necessary) the node for the compute_registers map. 20306c3fb27SDimitry Andric msgpack::DocNode &refComputeRegisters(); 20406c3fb27SDimitry Andric 20506c3fb27SDimitry Andric // Get (create if necessary) the .compute_registers entry. 20606c3fb27SDimitry Andric msgpack::MapDocNode getComputeRegisters(); 20706c3fb27SDimitry Andric 20806c3fb27SDimitry Andric // Reference (create if necessary) the node for the graphics registers map. 20906c3fb27SDimitry Andric msgpack::DocNode &refGraphicsRegisters(); 21006c3fb27SDimitry Andric 21106c3fb27SDimitry Andric // Get (create if necessary) the .graphics_registers entry. 21206c3fb27SDimitry Andric msgpack::MapDocNode getGraphicsRegisters(); 21306c3fb27SDimitry Andric 21406c3fb27SDimitry Andric // Reference (create if necessary) the node for the hardware_stages map. 21506c3fb27SDimitry Andric msgpack::DocNode &refHwStage(); 21606c3fb27SDimitry Andric 2170b57cec5SDimitry Andric // Get (create if necessary) the .hardware_stages entry for the given calling 2180b57cec5SDimitry Andric // convention. 2190b57cec5SDimitry Andric msgpack::MapDocNode getHwStage(unsigned CC); 2200b57cec5SDimitry Andric 22106c3fb27SDimitry Andric // Get the PAL version major (idx 0) or minor (idx 1). This is an internal 22206c3fb27SDimitry Andric // helper for the public wrapper functions that request Major or Minor 22306c3fb27SDimitry Andric unsigned getPALVersion(unsigned idx); 22406c3fb27SDimitry Andric 2250b57cec5SDimitry Andric bool setFromLegacyBlob(StringRef Blob); 2260b57cec5SDimitry Andric bool setFromMsgPackBlob(StringRef Blob); 2270b57cec5SDimitry Andric void toLegacyBlob(std::string &Blob); 2280b57cec5SDimitry Andric void toMsgPackBlob(std::string &Blob); 2290b57cec5SDimitry Andric }; 2300b57cec5SDimitry Andric 2310b57cec5SDimitry Andric } // end namespace llvm 2320b57cec5SDimitry Andric 2330b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_AMDGPU_AMDGPUPALMETADATA_H 234