LLVM  9.0.0svn
AMDGPUPALMetadata.cpp
Go to the documentation of this file.
1 //===-- AMDGPUPALMetadata.cpp - Accumulate and print AMDGPU PAL metadata -===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// \file
10 ///
11 /// This class has methods called by AMDGPUAsmPrinter to accumulate and print
12 /// the PAL metadata.
13 //
14 //===----------------------------------------------------------------------===//
15 //
16 
17 #include "AMDGPUPALMetadata.h"
18 #include "AMDGPU.h"
19 #include "AMDGPUAsmPrinter.h"
21 #include "SIDefines.h"
22 #include "llvm/BinaryFormat/ELF.h"
23 #include "llvm/IR/CallingConv.h"
26 
27 using namespace llvm;
28 using namespace llvm::AMDGPU;
29 
30 // Read the PAL metadata from IR metadata, where it was put by the frontend.
32  auto NamedMD = M.getNamedMetadata("amdgpu.pal.metadata.msgpack");
33  if (NamedMD && NamedMD->getNumOperands()) {
34  // This is the new msgpack format for metadata. It is a NamedMD containing
35  // an MDTuple containing an MDString containing the msgpack data.
36  BlobType = ELF::NT_AMDGPU_METADATA;
37  auto MDN = dyn_cast<MDTuple>(NamedMD->getOperand(0));
38  if (MDN && MDN->getNumOperands()) {
39  if (auto MDS = dyn_cast<MDString>(MDN->getOperand(0)))
40  setFromMsgPackBlob(MDS->getString());
41  }
42  return;
43  }
45  NamedMD = M.getNamedMetadata("amdgpu.pal.metadata");
46  if (!NamedMD || !NamedMD->getNumOperands())
47  return;
48  // This is the old reg=value pair format for metadata. It is a NamedMD
49  // containing an MDTuple containing a number of MDNodes each of which is an
50  // integer value, and each two integer values forms a key=value pair that we
51  // store as Registers[key]=value in the map.
52  auto Tuple = dyn_cast<MDTuple>(NamedMD->getOperand(0));
53  if (!Tuple)
54  return;
55  for (unsigned I = 0, E = Tuple->getNumOperands() & -2; I != E; I += 2) {
56  auto Key = mdconst::dyn_extract<ConstantInt>(Tuple->getOperand(I));
57  auto Val = mdconst::dyn_extract<ConstantInt>(Tuple->getOperand(I + 1));
58  if (!Key || !Val)
59  continue;
60  setRegister(Key->getZExtValue(), Val->getZExtValue());
61  }
62 }
63 
64 // Set PAL metadata from a binary blob from the applicable .note record.
65 // Returns false if bad format. Blob must remain valid for the lifetime of the
66 // Metadata.
68  BlobType = Type;
70  return setFromLegacyBlob(Blob);
71  return setFromMsgPackBlob(Blob);
72 }
73 
74 // Set PAL metadata from legacy (array of key=value pairs) blob.
75 bool AMDGPUPALMetadata::setFromLegacyBlob(StringRef Blob) {
76  auto Data = reinterpret_cast<const uint32_t *>(Blob.data());
77  for (unsigned I = 0; I != Blob.size() / sizeof(uint32_t) / 2; ++I)
78  setRegister(Data[I * 2], Data[I * 2 + 1]);
79  return true;
80 }
81 
82 // Set PAL metadata from msgpack blob.
83 bool AMDGPUPALMetadata::setFromMsgPackBlob(StringRef Blob) {
84  msgpack::Reader Reader(Blob);
85  return MsgPackDoc.readFromBlob(Blob, /*Multi=*/false);
86 }
87 
88 // Given the calling convention, calculate the register number for rsrc1. In
89 // principle the register number could change in future hardware, but we know
90 // it is the same for gfx6-9 (except that LS and ES don't exist on gfx9), so
91 // we can use fixed values.
92 static unsigned getRsrc1Reg(CallingConv::ID CC) {
93  switch (CC) {
94  default:
108  }
109 }
110 
111 // Calculate the PAL metadata key for *S_SCRATCH_SIZE. It can be used
112 // with a constant offset to access any non-register shader-specific PAL
113 // metadata key.
114 static unsigned getScratchSizeKey(CallingConv::ID CC) {
115  switch (CC) {
128  default:
130  }
131 }
132 
133 // Set the rsrc1 register in the metadata for a particular shader stage.
134 // In fact this ORs the value into any previous setting of the register.
136  setRegister(getRsrc1Reg(CC), Val);
137 }
138 
139 // Set the rsrc2 register in the metadata for a particular shader stage.
140 // In fact this ORs the value into any previous setting of the register.
142  setRegister(getRsrc1Reg(CC) + 1, Val);
143 }
144 
145 // Set the SPI_PS_INPUT_ENA register in the metadata.
146 // In fact this ORs the value into any previous setting of the register.
148  setRegister(PALMD::R_A1B3_SPI_PS_INPUT_ENA, Val);
149 }
150 
151 // Set the SPI_PS_INPUT_ADDR register in the metadata.
152 // In fact this ORs the value into any previous setting of the register.
154  setRegister(PALMD::R_A1B4_SPI_PS_INPUT_ADDR, Val);
155 }
156 
157 // Get a register from the metadata, or 0 if not currently set.
159  auto Regs = getRegisters();
160  auto It = Regs.find(MsgPackDoc.getNode(Reg));
161  if (It == Regs.end())
162  return 0;
163  auto N = It->second;
164  if (N.getKind() != msgpack::Type::UInt)
165  return 0;
166  return N.getUInt();
167 }
168 
169 // Set a register in the metadata.
170 // In fact this ORs the value into any previous setting of the register.
171 void AMDGPUPALMetadata::setRegister(unsigned Reg, unsigned Val) {
172  if (!isLegacy()) {
173  // In the new MsgPack format, ignore register numbered >= 0x10000000. It
174  // is a PAL ABI pseudo-register in the old non-MsgPack format.
175  if (Reg >= 0x10000000)
176  return;
177  }
178  auto &N = getRegisters()[MsgPackDoc.getNode(Reg)];
179  if (N.getKind() == msgpack::Type::UInt)
180  Val |= N.getUInt();
181  N = N.getDocument()->getNode(Val);
182 }
183 
184 // Set the entry point name for one shader.
186  if (isLegacy())
187  return;
188  // Msgpack format.
189  getHwStage(CC)[".entry_point"] = MsgPackDoc.getNode(Name, /*Copy=*/true);
190 }
191 
192 // Set the number of used vgprs in the metadata. This is an optional
193 // advisory record for logging etc; wave dispatch actually uses the rsrc1
194 // register for the shader stage to determine the number of vgprs to
195 // allocate.
197  if (isLegacy()) {
198  // Old non-msgpack format.
199  unsigned NumUsedVgprsKey = getScratchSizeKey(CC) +
202  setRegister(NumUsedVgprsKey, Val);
203  return;
204  }
205  // Msgpack format.
206  getHwStage(CC)[".vgpr_count"] = MsgPackDoc.getNode(Val);
207 }
208 
209 // Set the number of used sgprs in the metadata. This is an optional advisory
210 // record for logging etc; wave dispatch actually uses the rsrc1 register for
211 // the shader stage to determine the number of sgprs to allocate.
213  if (isLegacy()) {
214  // Old non-msgpack format.
215  unsigned NumUsedSgprsKey = getScratchSizeKey(CC) +
218  setRegister(NumUsedSgprsKey, Val);
219  return;
220  }
221  // Msgpack format.
222  getHwStage(CC)[".sgpr_count"] = MsgPackDoc.getNode(Val);
223 }
224 
225 // Set the scratch size in the metadata.
227  if (isLegacy()) {
228  // Old non-msgpack format.
229  setRegister(getScratchSizeKey(CC), Val);
230  return;
231  }
232  // Msgpack format.
233  getHwStage(CC)[".scratch_memory_size"] = MsgPackDoc.getNode(Val);
234 }
235 
236 // Set the hardware register bit in PAL metadata to enable wave32 on the
237 // shader of the given calling convention.
238 void AMDGPUPALMetadata::setWave32(unsigned CC) {
239  switch (CC) {
242  break;
245  break;
248  break;
251  break;
254  S_00B800_CS_W32_EN(1));
255  break;
256  }
257 }
258 
259 // Convert a register number to name, for display by toString().
260 // Returns nullptr if none.
261 static const char *getRegisterName(unsigned RegNum) {
262  // Table of registers.
263  static const struct RegInfo {
264  unsigned Num;
265  const char *Name;
266  } RegInfoTable[] = {
267  // Registers that code generation sets/modifies metadata for.
268  {PALMD::R_2C4A_SPI_SHADER_PGM_RSRC1_VS, "SPI_SHADER_PGM_RSRC1_VS"},
269  {PALMD::R_2C4A_SPI_SHADER_PGM_RSRC1_VS + 1, "SPI_SHADER_PGM_RSRC2_VS"},
270  {PALMD::R_2D4A_SPI_SHADER_PGM_RSRC1_LS, "SPI_SHADER_PGM_RSRC1_LS"},
271  {PALMD::R_2D4A_SPI_SHADER_PGM_RSRC1_LS + 1, "SPI_SHADER_PGM_RSRC2_LS"},
272  {PALMD::R_2D0A_SPI_SHADER_PGM_RSRC1_HS, "SPI_SHADER_PGM_RSRC1_HS"},
273  {PALMD::R_2D0A_SPI_SHADER_PGM_RSRC1_HS + 1, "SPI_SHADER_PGM_RSRC2_HS"},
274  {PALMD::R_2CCA_SPI_SHADER_PGM_RSRC1_ES, "SPI_SHADER_PGM_RSRC1_ES"},
275  {PALMD::R_2CCA_SPI_SHADER_PGM_RSRC1_ES + 1, "SPI_SHADER_PGM_RSRC2_ES"},
276  {PALMD::R_2C8A_SPI_SHADER_PGM_RSRC1_GS, "SPI_SHADER_PGM_RSRC1_GS"},
277  {PALMD::R_2C8A_SPI_SHADER_PGM_RSRC1_GS + 1, "SPI_SHADER_PGM_RSRC2_GS"},
278  {PALMD::R_2E00_COMPUTE_DISPATCH_INITIATOR, "COMPUTE_DISPATCH_INITIATOR"},
279  {PALMD::R_2E12_COMPUTE_PGM_RSRC1, "COMPUTE_PGM_RSRC1"},
280  {PALMD::R_2E12_COMPUTE_PGM_RSRC1 + 1, "COMPUTE_PGM_RSRC2"},
281  {PALMD::R_2C0A_SPI_SHADER_PGM_RSRC1_PS, "SPI_SHADER_PGM_RSRC1_PS"},
282  {PALMD::R_2C0A_SPI_SHADER_PGM_RSRC1_PS + 1, "SPI_SHADER_PGM_RSRC2_PS"},
283  {PALMD::R_A1B3_SPI_PS_INPUT_ENA, "SPI_PS_INPUT_ENA"},
284  {PALMD::R_A1B4_SPI_PS_INPUT_ADDR, "SPI_PS_INPUT_ADDR"},
285  {PALMD::R_A1B6_SPI_PS_IN_CONTROL, "SPI_PS_IN_CONTROL"},
286  {PALMD::R_A2D5_VGT_SHADER_STAGES_EN, "VGT_SHADER_STAGES_EN"},
287 
288  // Registers not known to code generation.
289  {0x2c07, "SPI_SHADER_PGM_RSRC3_PS"},
290  {0x2c46, "SPI_SHADER_PGM_RSRC3_VS"},
291  {0x2c87, "SPI_SHADER_PGM_RSRC3_GS"},
292  {0x2cc7, "SPI_SHADER_PGM_RSRC3_ES"},
293  {0x2d07, "SPI_SHADER_PGM_RSRC3_HS"},
294  {0x2d47, "SPI_SHADER_PGM_RSRC3_LS"},
295 
296  {0xa1c3, "SPI_SHADER_POS_FORMAT"},
297  {0xa1b1, "SPI_VS_OUT_CONFIG"},
298  {0xa207, "PA_CL_VS_OUT_CNTL"},
299  {0xa204, "PA_CL_CLIP_CNTL"},
300  {0xa206, "PA_CL_VTE_CNTL"},
301  {0xa2f9, "PA_SU_VTX_CNTL"},
302  {0xa293, "PA_SC_MODE_CNTL_1"},
303  {0xa2a1, "VGT_PRIMITIVEID_EN"},
304  {0x2c81, "SPI_SHADER_PGM_RSRC4_GS"},
305  {0x2e18, "COMPUTE_TMPRING_SIZE"},
306  {0xa1b5, "SPI_INTERP_CONTROL_0"},
307  {0xa1ba, "SPI_TMPRING_SIZE"},
308  {0xa1c4, "SPI_SHADER_Z_FORMAT"},
309  {0xa1c5, "SPI_SHADER_COL_FORMAT"},
310  {0xa203, "DB_SHADER_CONTROL"},
311  {0xa08f, "CB_SHADER_MASK"},
312  {0xa191, "SPI_PS_INPUT_CNTL_0"},
313  {0xa192, "SPI_PS_INPUT_CNTL_1"},
314  {0xa193, "SPI_PS_INPUT_CNTL_2"},
315  {0xa194, "SPI_PS_INPUT_CNTL_3"},
316  {0xa195, "SPI_PS_INPUT_CNTL_4"},
317  {0xa196, "SPI_PS_INPUT_CNTL_5"},
318  {0xa197, "SPI_PS_INPUT_CNTL_6"},
319  {0xa198, "SPI_PS_INPUT_CNTL_7"},
320  {0xa199, "SPI_PS_INPUT_CNTL_8"},
321  {0xa19a, "SPI_PS_INPUT_CNTL_9"},
322  {0xa19b, "SPI_PS_INPUT_CNTL_10"},
323  {0xa19c, "SPI_PS_INPUT_CNTL_11"},
324  {0xa19d, "SPI_PS_INPUT_CNTL_12"},
325  {0xa19e, "SPI_PS_INPUT_CNTL_13"},
326  {0xa19f, "SPI_PS_INPUT_CNTL_14"},
327  {0xa1a0, "SPI_PS_INPUT_CNTL_15"},
328  {0xa1a1, "SPI_PS_INPUT_CNTL_16"},
329  {0xa1a2, "SPI_PS_INPUT_CNTL_17"},
330  {0xa1a3, "SPI_PS_INPUT_CNTL_18"},
331  {0xa1a4, "SPI_PS_INPUT_CNTL_19"},
332  {0xa1a5, "SPI_PS_INPUT_CNTL_20"},
333  {0xa1a6, "SPI_PS_INPUT_CNTL_21"},
334  {0xa1a7, "SPI_PS_INPUT_CNTL_22"},
335  {0xa1a8, "SPI_PS_INPUT_CNTL_23"},
336  {0xa1a9, "SPI_PS_INPUT_CNTL_24"},
337  {0xa1aa, "SPI_PS_INPUT_CNTL_25"},
338  {0xa1ab, "SPI_PS_INPUT_CNTL_26"},
339  {0xa1ac, "SPI_PS_INPUT_CNTL_27"},
340  {0xa1ad, "SPI_PS_INPUT_CNTL_28"},
341  {0xa1ae, "SPI_PS_INPUT_CNTL_29"},
342  {0xa1af, "SPI_PS_INPUT_CNTL_30"},
343  {0xa1b0, "SPI_PS_INPUT_CNTL_31"},
344 
345  {0xa2ce, "VGT_GS_MAX_VERT_OUT"},
346  {0xa2ab, "VGT_ESGS_RING_ITEMSIZE"},
347  {0xa290, "VGT_GS_MODE"},
348  {0xa291, "VGT_GS_ONCHIP_CNTL"},
349  {0xa2d7, "VGT_GS_VERT_ITEMSIZE"},
350  {0xa2d8, "VGT_GS_VERT_ITEMSIZE_1"},
351  {0xa2d9, "VGT_GS_VERT_ITEMSIZE_2"},
352  {0xa2da, "VGT_GS_VERT_ITEMSIZE_3"},
353  {0xa298, "VGT_GSVS_RING_OFFSET_1"},
354  {0xa299, "VGT_GSVS_RING_OFFSET_2"},
355  {0xa29a, "VGT_GSVS_RING_OFFSET_3"},
356 
357  {0xa2e4, "VGT_GS_INSTANCE_CNT"},
358  {0xa297, "VGT_GS_PER_VS"},
359  {0xa29b, "VGT_GS_OUT_PRIM_TYPE"},
360  {0xa2ac, "VGT_GSVS_RING_ITEMSIZE"},
361 
362  {0xa2ad, "VGT_REUSE_OFF"},
363  {0xa1b8, "SPI_BARYC_CNTL"},
364 
365  {0x2c4c, "SPI_SHADER_USER_DATA_VS_0"},
366  {0x2c4d, "SPI_SHADER_USER_DATA_VS_1"},
367  {0x2c4e, "SPI_SHADER_USER_DATA_VS_2"},
368  {0x2c4f, "SPI_SHADER_USER_DATA_VS_3"},
369  {0x2c50, "SPI_SHADER_USER_DATA_VS_4"},
370  {0x2c51, "SPI_SHADER_USER_DATA_VS_5"},
371  {0x2c52, "SPI_SHADER_USER_DATA_VS_6"},
372  {0x2c53, "SPI_SHADER_USER_DATA_VS_7"},
373  {0x2c54, "SPI_SHADER_USER_DATA_VS_8"},
374  {0x2c55, "SPI_SHADER_USER_DATA_VS_9"},
375  {0x2c56, "SPI_SHADER_USER_DATA_VS_10"},
376  {0x2c57, "SPI_SHADER_USER_DATA_VS_11"},
377  {0x2c58, "SPI_SHADER_USER_DATA_VS_12"},
378  {0x2c59, "SPI_SHADER_USER_DATA_VS_13"},
379  {0x2c5a, "SPI_SHADER_USER_DATA_VS_14"},
380  {0x2c5b, "SPI_SHADER_USER_DATA_VS_15"},
381  {0x2c5c, "SPI_SHADER_USER_DATA_VS_16"},
382  {0x2c5d, "SPI_SHADER_USER_DATA_VS_17"},
383  {0x2c5e, "SPI_SHADER_USER_DATA_VS_18"},
384  {0x2c5f, "SPI_SHADER_USER_DATA_VS_19"},
385  {0x2c60, "SPI_SHADER_USER_DATA_VS_20"},
386  {0x2c61, "SPI_SHADER_USER_DATA_VS_21"},
387  {0x2c62, "SPI_SHADER_USER_DATA_VS_22"},
388  {0x2c63, "SPI_SHADER_USER_DATA_VS_23"},
389  {0x2c64, "SPI_SHADER_USER_DATA_VS_24"},
390  {0x2c65, "SPI_SHADER_USER_DATA_VS_25"},
391  {0x2c66, "SPI_SHADER_USER_DATA_VS_26"},
392  {0x2c67, "SPI_SHADER_USER_DATA_VS_27"},
393  {0x2c68, "SPI_SHADER_USER_DATA_VS_28"},
394  {0x2c69, "SPI_SHADER_USER_DATA_VS_29"},
395  {0x2c6a, "SPI_SHADER_USER_DATA_VS_30"},
396  {0x2c6b, "SPI_SHADER_USER_DATA_VS_31"},
397 
398  {0x2ccc, "SPI_SHADER_USER_DATA_ES_0"},
399  {0x2ccd, "SPI_SHADER_USER_DATA_ES_1"},
400  {0x2cce, "SPI_SHADER_USER_DATA_ES_2"},
401  {0x2ccf, "SPI_SHADER_USER_DATA_ES_3"},
402  {0x2cd0, "SPI_SHADER_USER_DATA_ES_4"},
403  {0x2cd1, "SPI_SHADER_USER_DATA_ES_5"},
404  {0x2cd2, "SPI_SHADER_USER_DATA_ES_6"},
405  {0x2cd3, "SPI_SHADER_USER_DATA_ES_7"},
406  {0x2cd4, "SPI_SHADER_USER_DATA_ES_8"},
407  {0x2cd5, "SPI_SHADER_USER_DATA_ES_9"},
408  {0x2cd6, "SPI_SHADER_USER_DATA_ES_10"},
409  {0x2cd7, "SPI_SHADER_USER_DATA_ES_11"},
410  {0x2cd8, "SPI_SHADER_USER_DATA_ES_12"},
411  {0x2cd9, "SPI_SHADER_USER_DATA_ES_13"},
412  {0x2cda, "SPI_SHADER_USER_DATA_ES_14"},
413  {0x2cdb, "SPI_SHADER_USER_DATA_ES_15"},
414  {0x2cdc, "SPI_SHADER_USER_DATA_ES_16"},
415  {0x2cdd, "SPI_SHADER_USER_DATA_ES_17"},
416  {0x2cde, "SPI_SHADER_USER_DATA_ES_18"},
417  {0x2cdf, "SPI_SHADER_USER_DATA_ES_19"},
418  {0x2ce0, "SPI_SHADER_USER_DATA_ES_20"},
419  {0x2ce1, "SPI_SHADER_USER_DATA_ES_21"},
420  {0x2ce2, "SPI_SHADER_USER_DATA_ES_22"},
421  {0x2ce3, "SPI_SHADER_USER_DATA_ES_23"},
422  {0x2ce4, "SPI_SHADER_USER_DATA_ES_24"},
423  {0x2ce5, "SPI_SHADER_USER_DATA_ES_25"},
424  {0x2ce6, "SPI_SHADER_USER_DATA_ES_26"},
425  {0x2ce7, "SPI_SHADER_USER_DATA_ES_27"},
426  {0x2ce8, "SPI_SHADER_USER_DATA_ES_28"},
427  {0x2ce9, "SPI_SHADER_USER_DATA_ES_29"},
428  {0x2cea, "SPI_SHADER_USER_DATA_ES_30"},
429  {0x2ceb, "SPI_SHADER_USER_DATA_ES_31"},
430 
431  {0x2c0c, "SPI_SHADER_USER_DATA_PS_0"},
432  {0x2c0d, "SPI_SHADER_USER_DATA_PS_1"},
433  {0x2c0e, "SPI_SHADER_USER_DATA_PS_2"},
434  {0x2c0f, "SPI_SHADER_USER_DATA_PS_3"},
435  {0x2c10, "SPI_SHADER_USER_DATA_PS_4"},
436  {0x2c11, "SPI_SHADER_USER_DATA_PS_5"},
437  {0x2c12, "SPI_SHADER_USER_DATA_PS_6"},
438  {0x2c13, "SPI_SHADER_USER_DATA_PS_7"},
439  {0x2c14, "SPI_SHADER_USER_DATA_PS_8"},
440  {0x2c15, "SPI_SHADER_USER_DATA_PS_9"},
441  {0x2c16, "SPI_SHADER_USER_DATA_PS_10"},
442  {0x2c17, "SPI_SHADER_USER_DATA_PS_11"},
443  {0x2c18, "SPI_SHADER_USER_DATA_PS_12"},
444  {0x2c19, "SPI_SHADER_USER_DATA_PS_13"},
445  {0x2c1a, "SPI_SHADER_USER_DATA_PS_14"},
446  {0x2c1b, "SPI_SHADER_USER_DATA_PS_15"},
447  {0x2c1c, "SPI_SHADER_USER_DATA_PS_16"},
448  {0x2c1d, "SPI_SHADER_USER_DATA_PS_17"},
449  {0x2c1e, "SPI_SHADER_USER_DATA_PS_18"},
450  {0x2c1f, "SPI_SHADER_USER_DATA_PS_19"},
451  {0x2c20, "SPI_SHADER_USER_DATA_PS_20"},
452  {0x2c21, "SPI_SHADER_USER_DATA_PS_21"},
453  {0x2c22, "SPI_SHADER_USER_DATA_PS_22"},
454  {0x2c23, "SPI_SHADER_USER_DATA_PS_23"},
455  {0x2c24, "SPI_SHADER_USER_DATA_PS_24"},
456  {0x2c25, "SPI_SHADER_USER_DATA_PS_25"},
457  {0x2c26, "SPI_SHADER_USER_DATA_PS_26"},
458  {0x2c27, "SPI_SHADER_USER_DATA_PS_27"},
459  {0x2c28, "SPI_SHADER_USER_DATA_PS_28"},
460  {0x2c29, "SPI_SHADER_USER_DATA_PS_29"},
461  {0x2c2a, "SPI_SHADER_USER_DATA_PS_30"},
462  {0x2c2b, "SPI_SHADER_USER_DATA_PS_31"},
463 
464  {0x2e40, "COMPUTE_USER_DATA_0"},
465  {0x2e41, "COMPUTE_USER_DATA_1"},
466  {0x2e42, "COMPUTE_USER_DATA_2"},
467  {0x2e43, "COMPUTE_USER_DATA_3"},
468  {0x2e44, "COMPUTE_USER_DATA_4"},
469  {0x2e45, "COMPUTE_USER_DATA_5"},
470  {0x2e46, "COMPUTE_USER_DATA_6"},
471  {0x2e47, "COMPUTE_USER_DATA_7"},
472  {0x2e48, "COMPUTE_USER_DATA_8"},
473  {0x2e49, "COMPUTE_USER_DATA_9"},
474  {0x2e4a, "COMPUTE_USER_DATA_10"},
475  {0x2e4b, "COMPUTE_USER_DATA_11"},
476  {0x2e4c, "COMPUTE_USER_DATA_12"},
477  {0x2e4d, "COMPUTE_USER_DATA_13"},
478  {0x2e4e, "COMPUTE_USER_DATA_14"},
479  {0x2e4f, "COMPUTE_USER_DATA_15"},
480 
481  {0x2e07, "COMPUTE_NUM_THREAD_X"},
482  {0x2e08, "COMPUTE_NUM_THREAD_Y"},
483  {0x2e09, "COMPUTE_NUM_THREAD_Z"},
484  {0xa2db, "VGT_TF_PARAM"},
485  {0xa2d6, "VGT_LS_HS_CONFIG"},
486  {0xa287, "VGT_HOS_MIN_TESS_LEVEL"},
487  {0xa286, "VGT_HOS_MAX_TESS_LEVEL"},
488  {0xa2f8, "PA_SC_AA_CONFIG"},
489  {0xa310, "PA_SC_SHADER_CONTROL"},
490  {0xa313, "PA_SC_CONSERVATIVE_RASTERIZATION_CNTL"},
491 
492  {0x2d0c, "SPI_SHADER_USER_DATA_LS_0"},
493  {0x2d0d, "SPI_SHADER_USER_DATA_LS_1"},
494  {0x2d0e, "SPI_SHADER_USER_DATA_LS_2"},
495  {0x2d0f, "SPI_SHADER_USER_DATA_LS_3"},
496  {0x2d10, "SPI_SHADER_USER_DATA_LS_4"},
497  {0x2d11, "SPI_SHADER_USER_DATA_LS_5"},
498  {0x2d12, "SPI_SHADER_USER_DATA_LS_6"},
499  {0x2d13, "SPI_SHADER_USER_DATA_LS_7"},
500  {0x2d14, "SPI_SHADER_USER_DATA_LS_8"},
501  {0x2d15, "SPI_SHADER_USER_DATA_LS_9"},
502  {0x2d16, "SPI_SHADER_USER_DATA_LS_10"},
503  {0x2d17, "SPI_SHADER_USER_DATA_LS_11"},
504  {0x2d18, "SPI_SHADER_USER_DATA_LS_12"},
505  {0x2d19, "SPI_SHADER_USER_DATA_LS_13"},
506  {0x2d1a, "SPI_SHADER_USER_DATA_LS_14"},
507  {0x2d1b, "SPI_SHADER_USER_DATA_LS_15"},
508  {0x2d1c, "SPI_SHADER_USER_DATA_LS_16"},
509  {0x2d1d, "SPI_SHADER_USER_DATA_LS_17"},
510  {0x2d1e, "SPI_SHADER_USER_DATA_LS_18"},
511  {0x2d1f, "SPI_SHADER_USER_DATA_LS_19"},
512  {0x2d20, "SPI_SHADER_USER_DATA_LS_20"},
513  {0x2d21, "SPI_SHADER_USER_DATA_LS_21"},
514  {0x2d22, "SPI_SHADER_USER_DATA_LS_22"},
515  {0x2d23, "SPI_SHADER_USER_DATA_LS_23"},
516  {0x2d24, "SPI_SHADER_USER_DATA_LS_24"},
517  {0x2d25, "SPI_SHADER_USER_DATA_LS_25"},
518  {0x2d26, "SPI_SHADER_USER_DATA_LS_26"},
519  {0x2d27, "SPI_SHADER_USER_DATA_LS_27"},
520  {0x2d28, "SPI_SHADER_USER_DATA_LS_28"},
521  {0x2d29, "SPI_SHADER_USER_DATA_LS_29"},
522  {0x2d2a, "SPI_SHADER_USER_DATA_LS_30"},
523  {0x2d2b, "SPI_SHADER_USER_DATA_LS_31"},
524 
525  {0xa2aa, "IA_MULTI_VGT_PARAM"},
526  {0xa2a5, "VGT_GS_MAX_PRIMS_PER_SUBGROUP"},
527  {0xa2e6, "VGT_STRMOUT_BUFFER_CONFIG"},
528  {0xa2e5, "VGT_STRMOUT_CONFIG"},
529  {0xa2b5, "VGT_STRMOUT_VTX_STRIDE_0"},
530  {0xa2b9, "VGT_STRMOUT_VTX_STRIDE_1"},
531  {0xa2bd, "VGT_STRMOUT_VTX_STRIDE_2"},
532  {0xa2c1, "VGT_STRMOUT_VTX_STRIDE_3"},
533  {0xa316, "VGT_VERTEX_REUSE_BLOCK_CNTL"},
534 
535  {0, nullptr}};
536  auto Entry = RegInfoTable;
537  for (; Entry->Num && Entry->Num != RegNum; ++Entry)
538  ;
539  return Entry->Name;
540 }
541 
542 // Convert the accumulated PAL metadata into an asm directive.
543 void AMDGPUPALMetadata::toString(std::string &String) {
544  String.clear();
545  if (!BlobType)
546  return;
547  raw_string_ostream Stream(String);
548  if (isLegacy()) {
549  if (MsgPackDoc.getRoot().getKind() == msgpack::Type::Nil)
550  return;
551  // Old linear reg=val format.
552  Stream << '\t' << AMDGPU::PALMD::AssemblerDirective << ' ';
553  auto Regs = getRegisters();
554  for (auto I = Regs.begin(), E = Regs.end(); I != E; ++I) {
555  if (I != Regs.begin())
556  Stream << ',';
557  unsigned Reg = I->first.getUInt();
558  unsigned Val = I->second.getUInt();
559  Stream << "0x" << Twine::utohexstr(Reg) << ",0x" << Twine::utohexstr(Val);
560  }
561  Stream << '\n';
562  return;
563  }
564 
565  // New msgpack-based format -- output as YAML (with unsigned numbers in hex),
566  // but first change the registers map to use names.
567  MsgPackDoc.setHexMode();
568  auto &RegsObj = refRegisters();
569  auto OrigRegs = RegsObj.getMap();
570  RegsObj = MsgPackDoc.getMapNode();
571  for (auto I : OrigRegs) {
572  auto Key = I.first;
573  if (const char *RegName = getRegisterName(Key.getUInt())) {
574  std::string KeyName = Key.toString();
575  KeyName += " (";
576  KeyName += RegName;
577  KeyName += ')';
578  Key = MsgPackDoc.getNode(KeyName, /*Copy=*/true);
579  }
580  RegsObj.getMap()[Key] = I.second;
581  }
582 
583  // Output as YAML.
584  Stream << '\t' << AMDGPU::PALMD::AssemblerDirectiveBegin << '\n';
585  MsgPackDoc.toYAML(Stream);
586  Stream << '\t' << AMDGPU::PALMD::AssemblerDirectiveEnd << '\n';
587 
588  // Restore original registers map.
589  RegsObj = OrigRegs;
590 }
591 
592 // Convert the accumulated PAL metadata into a binary blob for writing as
593 // a .note record of the specified AMD type. Returns an empty blob if
594 // there is no PAL metadata,
595 void AMDGPUPALMetadata::toBlob(unsigned Type, std::string &Blob) {
597  toLegacyBlob(Blob);
598  else if (Type)
599  toMsgPackBlob(Blob);
600 }
601 
602 void AMDGPUPALMetadata::toLegacyBlob(std::string &Blob) {
603  Blob.clear();
604  auto Registers = getRegisters();
605  if (Registers.getMap().empty())
606  return;
607  raw_string_ostream OS(Blob);
609  for (auto I : Registers.getMap()) {
610  EW.write(uint32_t(I.first.getUInt()));
611  EW.write(uint32_t(I.second.getUInt()));
612  }
613 }
614 
615 void AMDGPUPALMetadata::toMsgPackBlob(std::string &Blob) {
616  Blob.clear();
617  MsgPackDoc.writeToBlob(Blob);
618 }
619 
620 // Set PAL metadata from YAML text. Returns false if failed.
622  BlobType = ELF::NT_AMDGPU_METADATA;
623  if (!MsgPackDoc.fromYAML(S))
624  return false;
625 
626  // In the registers map, some keys may be of the form "0xa191
627  // (SPI_PS_INPUT_CNTL_0)", in which case the YAML input code made it a
628  // string. We need to turn it into a number.
629  auto &RegsObj = refRegisters();
630  auto OrigRegs = RegsObj;
631  RegsObj = MsgPackDoc.getMapNode();
632  Registers = RegsObj.getMap();
633  bool Ok = true;
634  for (auto I : OrigRegs.getMap()) {
635  auto Key = I.first;
636  if (Key.getKind() == msgpack::Type::String) {
637  StringRef S = Key.getString();
638  uint64_t Val;
639  if (S.consumeInteger(0, Val)) {
640  Ok = false;
641  errs() << "Unrecognized PAL metadata register key '" << S << "'\n";
642  continue;
643  }
644  Key = MsgPackDoc.getNode(uint64_t(Val));
645  }
646  Registers.getMap()[Key] = I.second;
647  }
648  return Ok;
649 }
650 
651 // Reference (create if necessary) the node for the registers map.
652 msgpack::DocNode &AMDGPUPALMetadata::refRegisters() {
653  auto &N =
654  MsgPackDoc.getRoot()
655  .getMap(/*Convert=*/true)[MsgPackDoc.getNode("amdpal.pipelines")]
656  .getArray(/*Convert=*/true)[0]
657  .getMap(/*Convert=*/true)[MsgPackDoc.getNode(".registers")];
658  N.getMap(/*Convert=*/true);
659  return N;
660 }
661 
662 // Get (create if necessary) the registers map.
663 msgpack::MapDocNode AMDGPUPALMetadata::getRegisters() {
664  if (Registers.isEmpty())
665  Registers = refRegisters();
666  return Registers.getMap();
667 }
668 
669 // Return the PAL metadata hardware shader stage name.
670 static const char *getStageName(CallingConv::ID CC) {
671  switch (CC) {
673  return ".ps";
675  return ".vs";
677  return ".gs";
679  return ".es";
681  return ".hs";
683  return ".ls";
684  default:
685  return ".cs";
686  }
687 }
688 
689 // Get (create if necessary) the .hardware_stages entry for the given calling
690 // convention.
691 msgpack::MapDocNode AMDGPUPALMetadata::getHwStage(unsigned CC) {
692  if (HwStages.isEmpty())
693  HwStages = MsgPackDoc.getRoot()
694  .getMap(/*Convert=*/true)["amdpal.pipelines"]
695  .getArray(/*Convert=*/true)[0]
696  .getMap(/*Convert=*/true)[".hardware_stages"]
697  .getMap(/*Convert=*/true);
698  return HwStages.getMap()[getStageName(CC)].getMap(/*Convert=*/true);
699 }
700 
701 // Get .note record vendor name of metadata blob to be emitted.
702 const char *AMDGPUPALMetadata::getVendor() const {
703  return isLegacy() ? ElfNote::NoteNameV2 : ElfNote::NoteNameV3;
704 }
705 
706 // Get .note record type of metadata blob to be emitted:
707 // ELF::NT_AMD_AMDGPU_PAL_METADATA (legacy key=val format), or
708 // ELF::NT_AMDGPU_METADATA (MsgPack format), or
709 // 0 (no PAL metadata).
710 unsigned AMDGPUPALMetadata::getType() const {
711  return BlobType;
712 }
713 
714 // Return whether the blob type is legacy PAL metadata.
715 bool AMDGPUPALMetadata::isLegacy() const {
716  return BlobType == ELF::NT_AMD_AMDGPU_PAL_METADATA;
717 }
718 
719 // Set legacy PAL metadata format.
722 }
723 
void toBlob(unsigned Type, std::string &S)
static unsigned getScratchSizeKey(CallingConv::ID CC)
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
#define S_00B800_CS_W32_EN(x)
Definition: SIDefines.h:597
void setRegister(unsigned Reg, unsigned Val)
static const char * getStageName(CallingConv::ID CC)
This class represents lattice values for constants.
Definition: AllocatorList.h:23
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:65
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
void setRsrc2(unsigned CC, unsigned Val)
unsigned Reg
#define S_0286D8_PS_W32_EN(x)
Definition: SIDefines.h:595
std::string Name
Calling convention used for Mesa/AMDPAL pixel shaders.
Definition: CallingConv.h:194
Tuple of metadata.
Definition: Metadata.h:1105
void setEntryPoint(unsigned CC, StringRef Name)
Calling convention used for Mesa/AMDPAL compute shaders.
Definition: CallingConv.h:197
MapDocNode & getMap(bool Convert=false)
Get a MapDocNode for a map node.
const char * getVendor() const
void toString(std::string &S)
Key
PAL metadata keys.
std::enable_if< std::numeric_limits< T >::is_signed, bool >::type consumeInteger(unsigned Radix, T &Result)
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:512
NamedMDNode * getNamedMetadata(const Twine &Name) const
Return the first NamedMDNode in the module with the specified name.
Definition: Module.cpp:250
#define S_028B54_VS_W32_EN(x)
Definition: SIDefines.h:593
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:130
#define S_028B54_HS_W32_EN(x)
Definition: SIDefines.h:591
SI Pre allocate WWM Registers
const char NoteNameV3[]
Definition: AMDGPUPTNote.h:26
void setSpiPsInputAddr(unsigned Val)
Reads MessagePack objects from memory, one at a time.
Definition: MsgPackReader.h:98
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
void setScratchSize(unsigned CC, unsigned Val)
Calling convention used for Mesa/AMDPAL hull shaders (= tessellation control shaders).
Definition: CallingConv.h:207
unsigned getRegister(unsigned Reg)
ArrayDocNode & getArray(bool Convert=false)
Get an ArrayDocNode for an array node.
void setRsrc1(unsigned CC, unsigned Val)
PAL metadata handling.
bool setFromString(StringRef S)
constexpr char AssemblerDirective[]
PAL metadata (old linear format) assembler directive.
constexpr char AssemblerDirectiveEnd[]
PAL metadata (new MsgPack format) ending assembler directive.
void setSpiPsInputEna(unsigned Val)
void setNumUsedVgprs(unsigned CC, unsigned Val)
Calling convention used for Mesa vertex shaders, or AMDPAL last shader stage before rasterization (ve...
Definition: CallingConv.h:188
void setNumUsedSgprs(unsigned CC, unsigned Val)
void write(ArrayRef< value_type > Val)
Definition: EndianStream.h:55
static Twine utohexstr(const uint64_t &Val)
Definition: Twine.h:387
constexpr char AssemblerDirectiveBegin[]
PAL metadata (new MsgPack format) beginning assembler directive.
Calling convention used for Mesa/AMDPAL geometry shaders.
Definition: CallingConv.h:191
static unsigned getRsrc1Reg(CallingConv::ID CC)
const char NoteNameV2[]
Definition: AMDGPUPTNote.h:25
A DocNode that is a map.
Calling convention used for AMDPAL vertex shader if tessellation is in use.
Definition: CallingConv.h:215
Adapter to write values to a stream in a particular byte order.
Definition: EndianStream.h:51
#define S_028B54_GS_W32_EN(x)
Definition: SIDefines.h:592
#define I(x, y, z)
Definition: MD5.cpp:58
#define N
AMDGPU Assembly printer class.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:332
static const char * getRegisterName(unsigned RegNum)
LLVM_NODISCARD const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:122
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:482
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
AMDGPU metadata definitions and in-memory representations.
A node in a MsgPack Document.
bool setFromBlob(unsigned Type, StringRef Blob)
Calling convention used for AMDPAL shader stage before geometry shader if geometry is in use...
Definition: CallingConv.h:220