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