xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/AMDGPU/Utils/AMDGPUPALMetadata.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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