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 // Convert a register number to name, for display by toString().
237 // Returns nullptr if none.
238 static const char *getRegisterName(unsigned RegNum) {
239  // Table of registers.
240  static const struct RegInfo {
241  unsigned Num;
242  const char *Name;
243  } RegInfoTable[] = {
244  // Registers that code generation sets/modifies metadata for.
245  {PALMD::R_2C4A_SPI_SHADER_PGM_RSRC1_VS, "SPI_SHADER_PGM_RSRC1_VS"},
246  {PALMD::R_2C4A_SPI_SHADER_PGM_RSRC1_VS + 1, "SPI_SHADER_PGM_RSRC2_VS"},
247  {PALMD::R_2D4A_SPI_SHADER_PGM_RSRC1_LS, "SPI_SHADER_PGM_RSRC1_LS"},
248  {PALMD::R_2D4A_SPI_SHADER_PGM_RSRC1_LS + 1, "SPI_SHADER_PGM_RSRC2_LS"},
249  {PALMD::R_2D0A_SPI_SHADER_PGM_RSRC1_HS, "SPI_SHADER_PGM_RSRC1_HS"},
250  {PALMD::R_2D0A_SPI_SHADER_PGM_RSRC1_HS + 1, "SPI_SHADER_PGM_RSRC2_HS"},
251  {PALMD::R_2CCA_SPI_SHADER_PGM_RSRC1_ES, "SPI_SHADER_PGM_RSRC1_ES"},
252  {PALMD::R_2CCA_SPI_SHADER_PGM_RSRC1_ES + 1, "SPI_SHADER_PGM_RSRC2_ES"},
253  {PALMD::R_2C8A_SPI_SHADER_PGM_RSRC1_GS, "SPI_SHADER_PGM_RSRC1_GS"},
254  {PALMD::R_2C8A_SPI_SHADER_PGM_RSRC1_GS + 1, "SPI_SHADER_PGM_RSRC2_GS"},
255  {PALMD::R_2E12_COMPUTE_PGM_RSRC1, "COMPUTE_PGM_RSRC1"},
256  {PALMD::R_2E12_COMPUTE_PGM_RSRC1 + 1, "COMPUTE_PGM_RSRC2"},
257  {PALMD::R_2C0A_SPI_SHADER_PGM_RSRC1_PS, "SPI_SHADER_PGM_RSRC1_PS"},
258  {PALMD::R_2C0A_SPI_SHADER_PGM_RSRC1_PS + 1, "SPI_SHADER_PGM_RSRC2_PS"},
259  {PALMD::R_A1B3_SPI_PS_INPUT_ENA, "SPI_PS_INPUT_ENA"},
260  {PALMD::R_A1B4_SPI_PS_INPUT_ADDR, "SPI_PS_INPUT_ADDR"},
261 
262  // Registers not known to code generation.
263  {0x2c07, "SPI_SHADER_PGM_RSRC3_PS"},
264  {0x2c46, "SPI_SHADER_PGM_RSRC3_VS"},
265  {0x2c87, "SPI_SHADER_PGM_RSRC3_GS"},
266  {0x2cc7, "SPI_SHADER_PGM_RSRC3_ES"},
267  {0x2d07, "SPI_SHADER_PGM_RSRC3_HS"},
268  {0x2d47, "SPI_SHADER_PGM_RSRC3_LS"},
269 
270  {0xa1c3, "SPI_SHADER_POS_FORMAT"},
271  {0xa1b1, "SPI_VS_OUT_CONFIG"},
272  {0xa207, "PA_CL_VS_OUT_CNTL"},
273  {0xa204, "PA_CL_CLIP_CNTL"},
274  {0xa206, "PA_CL_VTE_CNTL"},
275  {0xa2f9, "PA_SU_VTX_CNTL"},
276  {0xa293, "PA_SC_MODE_CNTL_1"},
277  {0xa2a1, "VGT_PRIMITIVEID_EN"},
278  {0x2c81, "SPI_SHADER_PGM_RSRC4_GS"},
279  {0x2e18, "COMPUTE_TMPRING_SIZE"},
280  {0xa1b5, "SPI_INTERP_CONTROL_0"},
281  {0xa1ba, "SPI_TMPRING_SIZE"},
282  {0xa1c4, "SPI_SHADER_Z_FORMAT"},
283  {0xa1c5, "SPI_SHADER_COL_FORMAT"},
284  {0xa203, "DB_SHADER_CONTROL"},
285  {0xa08f, "CB_SHADER_MASK"},
286  {0xa1b6, "SPI_PS_IN_CONTROL"},
287  {0xa191, "SPI_PS_INPUT_CNTL_0"},
288  {0xa192, "SPI_PS_INPUT_CNTL_1"},
289  {0xa193, "SPI_PS_INPUT_CNTL_2"},
290  {0xa194, "SPI_PS_INPUT_CNTL_3"},
291  {0xa195, "SPI_PS_INPUT_CNTL_4"},
292  {0xa196, "SPI_PS_INPUT_CNTL_5"},
293  {0xa197, "SPI_PS_INPUT_CNTL_6"},
294  {0xa198, "SPI_PS_INPUT_CNTL_7"},
295  {0xa199, "SPI_PS_INPUT_CNTL_8"},
296  {0xa19a, "SPI_PS_INPUT_CNTL_9"},
297  {0xa19b, "SPI_PS_INPUT_CNTL_10"},
298  {0xa19c, "SPI_PS_INPUT_CNTL_11"},
299  {0xa19d, "SPI_PS_INPUT_CNTL_12"},
300  {0xa19e, "SPI_PS_INPUT_CNTL_13"},
301  {0xa19f, "SPI_PS_INPUT_CNTL_14"},
302  {0xa1a0, "SPI_PS_INPUT_CNTL_15"},
303  {0xa1a1, "SPI_PS_INPUT_CNTL_16"},
304  {0xa1a2, "SPI_PS_INPUT_CNTL_17"},
305  {0xa1a3, "SPI_PS_INPUT_CNTL_18"},
306  {0xa1a4, "SPI_PS_INPUT_CNTL_19"},
307  {0xa1a5, "SPI_PS_INPUT_CNTL_20"},
308  {0xa1a6, "SPI_PS_INPUT_CNTL_21"},
309  {0xa1a7, "SPI_PS_INPUT_CNTL_22"},
310  {0xa1a8, "SPI_PS_INPUT_CNTL_23"},
311  {0xa1a9, "SPI_PS_INPUT_CNTL_24"},
312  {0xa1aa, "SPI_PS_INPUT_CNTL_25"},
313  {0xa1ab, "SPI_PS_INPUT_CNTL_26"},
314  {0xa1ac, "SPI_PS_INPUT_CNTL_27"},
315  {0xa1ad, "SPI_PS_INPUT_CNTL_28"},
316  {0xa1ae, "SPI_PS_INPUT_CNTL_29"},
317  {0xa1af, "SPI_PS_INPUT_CNTL_30"},
318  {0xa1b0, "SPI_PS_INPUT_CNTL_31"},
319 
320  {0xa2ce, "VGT_GS_MAX_VERT_OUT"},
321  {0xa2ab, "VGT_ESGS_RING_ITEMSIZE"},
322  {0xa290, "VGT_GS_MODE"},
323  {0xa291, "VGT_GS_ONCHIP_CNTL"},
324  {0xa2d7, "VGT_GS_VERT_ITEMSIZE"},
325  {0xa2d8, "VGT_GS_VERT_ITEMSIZE_1"},
326  {0xa2d9, "VGT_GS_VERT_ITEMSIZE_2"},
327  {0xa2da, "VGT_GS_VERT_ITEMSIZE_3"},
328  {0xa298, "VGT_GSVS_RING_OFFSET_1"},
329  {0xa299, "VGT_GSVS_RING_OFFSET_2"},
330  {0xa29a, "VGT_GSVS_RING_OFFSET_3"},
331 
332  {0xa2e4, "VGT_GS_INSTANCE_CNT"},
333  {0xa297, "VGT_GS_PER_VS"},
334  {0xa29b, "VGT_GS_OUT_PRIM_TYPE"},
335  {0xa2ac, "VGT_GSVS_RING_ITEMSIZE"},
336 
337  {0xa2d5, "VGT_SHADER_STAGES_EN"},
338  {0xa2ad, "VGT_REUSE_OFF"},
339  {0xa1b8, "SPI_BARYC_CNTL"},
340 
341  {0x2c4c, "SPI_SHADER_USER_DATA_VS_0"},
342  {0x2c4d, "SPI_SHADER_USER_DATA_VS_1"},
343  {0x2c4e, "SPI_SHADER_USER_DATA_VS_2"},
344  {0x2c4f, "SPI_SHADER_USER_DATA_VS_3"},
345  {0x2c50, "SPI_SHADER_USER_DATA_VS_4"},
346  {0x2c51, "SPI_SHADER_USER_DATA_VS_5"},
347  {0x2c52, "SPI_SHADER_USER_DATA_VS_6"},
348  {0x2c53, "SPI_SHADER_USER_DATA_VS_7"},
349  {0x2c54, "SPI_SHADER_USER_DATA_VS_8"},
350  {0x2c55, "SPI_SHADER_USER_DATA_VS_9"},
351  {0x2c56, "SPI_SHADER_USER_DATA_VS_10"},
352  {0x2c57, "SPI_SHADER_USER_DATA_VS_11"},
353  {0x2c58, "SPI_SHADER_USER_DATA_VS_12"},
354  {0x2c59, "SPI_SHADER_USER_DATA_VS_13"},
355  {0x2c5a, "SPI_SHADER_USER_DATA_VS_14"},
356  {0x2c5b, "SPI_SHADER_USER_DATA_VS_15"},
357  {0x2c5c, "SPI_SHADER_USER_DATA_VS_16"},
358  {0x2c5d, "SPI_SHADER_USER_DATA_VS_17"},
359  {0x2c5e, "SPI_SHADER_USER_DATA_VS_18"},
360  {0x2c5f, "SPI_SHADER_USER_DATA_VS_19"},
361  {0x2c60, "SPI_SHADER_USER_DATA_VS_20"},
362  {0x2c61, "SPI_SHADER_USER_DATA_VS_21"},
363  {0x2c62, "SPI_SHADER_USER_DATA_VS_22"},
364  {0x2c63, "SPI_SHADER_USER_DATA_VS_23"},
365  {0x2c64, "SPI_SHADER_USER_DATA_VS_24"},
366  {0x2c65, "SPI_SHADER_USER_DATA_VS_25"},
367  {0x2c66, "SPI_SHADER_USER_DATA_VS_26"},
368  {0x2c67, "SPI_SHADER_USER_DATA_VS_27"},
369  {0x2c68, "SPI_SHADER_USER_DATA_VS_28"},
370  {0x2c69, "SPI_SHADER_USER_DATA_VS_29"},
371  {0x2c6a, "SPI_SHADER_USER_DATA_VS_30"},
372  {0x2c6b, "SPI_SHADER_USER_DATA_VS_31"},
373 
374  {0x2ccc, "SPI_SHADER_USER_DATA_ES_0"},
375  {0x2ccd, "SPI_SHADER_USER_DATA_ES_1"},
376  {0x2cce, "SPI_SHADER_USER_DATA_ES_2"},
377  {0x2ccf, "SPI_SHADER_USER_DATA_ES_3"},
378  {0x2cd0, "SPI_SHADER_USER_DATA_ES_4"},
379  {0x2cd1, "SPI_SHADER_USER_DATA_ES_5"},
380  {0x2cd2, "SPI_SHADER_USER_DATA_ES_6"},
381  {0x2cd3, "SPI_SHADER_USER_DATA_ES_7"},
382  {0x2cd4, "SPI_SHADER_USER_DATA_ES_8"},
383  {0x2cd5, "SPI_SHADER_USER_DATA_ES_9"},
384  {0x2cd6, "SPI_SHADER_USER_DATA_ES_10"},
385  {0x2cd7, "SPI_SHADER_USER_DATA_ES_11"},
386  {0x2cd8, "SPI_SHADER_USER_DATA_ES_12"},
387  {0x2cd9, "SPI_SHADER_USER_DATA_ES_13"},
388  {0x2cda, "SPI_SHADER_USER_DATA_ES_14"},
389  {0x2cdb, "SPI_SHADER_USER_DATA_ES_15"},
390  {0x2cdc, "SPI_SHADER_USER_DATA_ES_16"},
391  {0x2cdd, "SPI_SHADER_USER_DATA_ES_17"},
392  {0x2cde, "SPI_SHADER_USER_DATA_ES_18"},
393  {0x2cdf, "SPI_SHADER_USER_DATA_ES_19"},
394  {0x2ce0, "SPI_SHADER_USER_DATA_ES_20"},
395  {0x2ce1, "SPI_SHADER_USER_DATA_ES_21"},
396  {0x2ce2, "SPI_SHADER_USER_DATA_ES_22"},
397  {0x2ce3, "SPI_SHADER_USER_DATA_ES_23"},
398  {0x2ce4, "SPI_SHADER_USER_DATA_ES_24"},
399  {0x2ce5, "SPI_SHADER_USER_DATA_ES_25"},
400  {0x2ce6, "SPI_SHADER_USER_DATA_ES_26"},
401  {0x2ce7, "SPI_SHADER_USER_DATA_ES_27"},
402  {0x2ce8, "SPI_SHADER_USER_DATA_ES_28"},
403  {0x2ce9, "SPI_SHADER_USER_DATA_ES_29"},
404  {0x2cea, "SPI_SHADER_USER_DATA_ES_30"},
405  {0x2ceb, "SPI_SHADER_USER_DATA_ES_31"},
406 
407  {0x2c0c, "SPI_SHADER_USER_DATA_PS_0"},
408  {0x2c0d, "SPI_SHADER_USER_DATA_PS_1"},
409  {0x2c0e, "SPI_SHADER_USER_DATA_PS_2"},
410  {0x2c0f, "SPI_SHADER_USER_DATA_PS_3"},
411  {0x2c10, "SPI_SHADER_USER_DATA_PS_4"},
412  {0x2c11, "SPI_SHADER_USER_DATA_PS_5"},
413  {0x2c12, "SPI_SHADER_USER_DATA_PS_6"},
414  {0x2c13, "SPI_SHADER_USER_DATA_PS_7"},
415  {0x2c14, "SPI_SHADER_USER_DATA_PS_8"},
416  {0x2c15, "SPI_SHADER_USER_DATA_PS_9"},
417  {0x2c16, "SPI_SHADER_USER_DATA_PS_10"},
418  {0x2c17, "SPI_SHADER_USER_DATA_PS_11"},
419  {0x2c18, "SPI_SHADER_USER_DATA_PS_12"},
420  {0x2c19, "SPI_SHADER_USER_DATA_PS_13"},
421  {0x2c1a, "SPI_SHADER_USER_DATA_PS_14"},
422  {0x2c1b, "SPI_SHADER_USER_DATA_PS_15"},
423  {0x2c1c, "SPI_SHADER_USER_DATA_PS_16"},
424  {0x2c1d, "SPI_SHADER_USER_DATA_PS_17"},
425  {0x2c1e, "SPI_SHADER_USER_DATA_PS_18"},
426  {0x2c1f, "SPI_SHADER_USER_DATA_PS_19"},
427  {0x2c20, "SPI_SHADER_USER_DATA_PS_20"},
428  {0x2c21, "SPI_SHADER_USER_DATA_PS_21"},
429  {0x2c22, "SPI_SHADER_USER_DATA_PS_22"},
430  {0x2c23, "SPI_SHADER_USER_DATA_PS_23"},
431  {0x2c24, "SPI_SHADER_USER_DATA_PS_24"},
432  {0x2c25, "SPI_SHADER_USER_DATA_PS_25"},
433  {0x2c26, "SPI_SHADER_USER_DATA_PS_26"},
434  {0x2c27, "SPI_SHADER_USER_DATA_PS_27"},
435  {0x2c28, "SPI_SHADER_USER_DATA_PS_28"},
436  {0x2c29, "SPI_SHADER_USER_DATA_PS_29"},
437  {0x2c2a, "SPI_SHADER_USER_DATA_PS_30"},
438  {0x2c2b, "SPI_SHADER_USER_DATA_PS_31"},
439 
440  {0x2e40, "COMPUTE_USER_DATA_0"},
441  {0x2e41, "COMPUTE_USER_DATA_1"},
442  {0x2e42, "COMPUTE_USER_DATA_2"},
443  {0x2e43, "COMPUTE_USER_DATA_3"},
444  {0x2e44, "COMPUTE_USER_DATA_4"},
445  {0x2e45, "COMPUTE_USER_DATA_5"},
446  {0x2e46, "COMPUTE_USER_DATA_6"},
447  {0x2e47, "COMPUTE_USER_DATA_7"},
448  {0x2e48, "COMPUTE_USER_DATA_8"},
449  {0x2e49, "COMPUTE_USER_DATA_9"},
450  {0x2e4a, "COMPUTE_USER_DATA_10"},
451  {0x2e4b, "COMPUTE_USER_DATA_11"},
452  {0x2e4c, "COMPUTE_USER_DATA_12"},
453  {0x2e4d, "COMPUTE_USER_DATA_13"},
454  {0x2e4e, "COMPUTE_USER_DATA_14"},
455  {0x2e4f, "COMPUTE_USER_DATA_15"},
456 
457  {0x2e07, "COMPUTE_NUM_THREAD_X"},
458  {0x2e08, "COMPUTE_NUM_THREAD_Y"},
459  {0x2e09, "COMPUTE_NUM_THREAD_Z"},
460  {0xa2db, "VGT_TF_PARAM"},
461  {0xa2d6, "VGT_LS_HS_CONFIG"},
462  {0xa287, "VGT_HOS_MIN_TESS_LEVEL"},
463  {0xa286, "VGT_HOS_MAX_TESS_LEVEL"},
464  {0xa2f8, "PA_SC_AA_CONFIG"},
465  {0xa310, "PA_SC_SHADER_CONTROL"},
466  {0xa313, "PA_SC_CONSERVATIVE_RASTERIZATION_CNTL"},
467 
468  {0x2d0c, "SPI_SHADER_USER_DATA_LS_0"},
469  {0x2d0d, "SPI_SHADER_USER_DATA_LS_1"},
470  {0x2d0e, "SPI_SHADER_USER_DATA_LS_2"},
471  {0x2d0f, "SPI_SHADER_USER_DATA_LS_3"},
472  {0x2d10, "SPI_SHADER_USER_DATA_LS_4"},
473  {0x2d11, "SPI_SHADER_USER_DATA_LS_5"},
474  {0x2d12, "SPI_SHADER_USER_DATA_LS_6"},
475  {0x2d13, "SPI_SHADER_USER_DATA_LS_7"},
476  {0x2d14, "SPI_SHADER_USER_DATA_LS_8"},
477  {0x2d15, "SPI_SHADER_USER_DATA_LS_9"},
478  {0x2d16, "SPI_SHADER_USER_DATA_LS_10"},
479  {0x2d17, "SPI_SHADER_USER_DATA_LS_11"},
480  {0x2d18, "SPI_SHADER_USER_DATA_LS_12"},
481  {0x2d19, "SPI_SHADER_USER_DATA_LS_13"},
482  {0x2d1a, "SPI_SHADER_USER_DATA_LS_14"},
483  {0x2d1b, "SPI_SHADER_USER_DATA_LS_15"},
484  {0x2d1c, "SPI_SHADER_USER_DATA_LS_16"},
485  {0x2d1d, "SPI_SHADER_USER_DATA_LS_17"},
486  {0x2d1e, "SPI_SHADER_USER_DATA_LS_18"},
487  {0x2d1f, "SPI_SHADER_USER_DATA_LS_19"},
488  {0x2d20, "SPI_SHADER_USER_DATA_LS_20"},
489  {0x2d21, "SPI_SHADER_USER_DATA_LS_21"},
490  {0x2d22, "SPI_SHADER_USER_DATA_LS_22"},
491  {0x2d23, "SPI_SHADER_USER_DATA_LS_23"},
492  {0x2d24, "SPI_SHADER_USER_DATA_LS_24"},
493  {0x2d25, "SPI_SHADER_USER_DATA_LS_25"},
494  {0x2d26, "SPI_SHADER_USER_DATA_LS_26"},
495  {0x2d27, "SPI_SHADER_USER_DATA_LS_27"},
496  {0x2d28, "SPI_SHADER_USER_DATA_LS_28"},
497  {0x2d29, "SPI_SHADER_USER_DATA_LS_29"},
498  {0x2d2a, "SPI_SHADER_USER_DATA_LS_30"},
499  {0x2d2b, "SPI_SHADER_USER_DATA_LS_31"},
500 
501  {0xa2aa, "IA_MULTI_VGT_PARAM"},
502  {0xa2a5, "VGT_GS_MAX_PRIMS_PER_SUBGROUP"},
503  {0xa2e6, "VGT_STRMOUT_BUFFER_CONFIG"},
504  {0xa2e5, "VGT_STRMOUT_CONFIG"},
505  {0xa2b5, "VGT_STRMOUT_VTX_STRIDE_0"},
506  {0xa2b9, "VGT_STRMOUT_VTX_STRIDE_1"},
507  {0xa2bd, "VGT_STRMOUT_VTX_STRIDE_2"},
508  {0xa2c1, "VGT_STRMOUT_VTX_STRIDE_3"},
509  {0xa316, "VGT_VERTEX_REUSE_BLOCK_CNTL"},
510 
511  {0, nullptr}};
512  auto Entry = RegInfoTable;
513  for (; Entry->Num && Entry->Num != RegNum; ++Entry)
514  ;
515  return Entry->Name;
516 }
517 
518 // Convert the accumulated PAL metadata into an asm directive.
519 void AMDGPUPALMetadata::toString(std::string &String) {
520  String.clear();
521  if (!BlobType)
522  return;
523  raw_string_ostream Stream(String);
524  if (isLegacy()) {
525  if (MsgPackDoc.getRoot().getKind() == msgpack::Type::Nil)
526  return;
527  // Old linear reg=val format.
528  Stream << '\t' << AMDGPU::PALMD::AssemblerDirective << ' ';
529  auto Regs = getRegisters();
530  for (auto I = Regs.begin(), E = Regs.end(); I != E; ++I) {
531  if (I != Regs.begin())
532  Stream << ',';
533  unsigned Reg = I->first.getUInt();
534  unsigned Val = I->second.getUInt();
535  Stream << "0x" << Twine::utohexstr(Reg) << ",0x" << Twine::utohexstr(Val);
536  }
537  Stream << '\n';
538  return;
539  }
540 
541  // New msgpack-based format -- output as YAML (with unsigned numbers in hex),
542  // but first change the registers map to use names.
543  MsgPackDoc.setHexMode();
544  auto &RegsObj = refRegisters();
545  auto OrigRegs = RegsObj.getMap();
546  RegsObj = MsgPackDoc.getMapNode();
547  for (auto I : OrigRegs) {
548  auto Key = I.first;
549  if (const char *RegName = getRegisterName(Key.getUInt())) {
550  std::string KeyName = Key.toString();
551  KeyName += " (";
552  KeyName += RegName;
553  KeyName += ')';
554  Key = MsgPackDoc.getNode(KeyName, /*Copy=*/true);
555  }
556  RegsObj.getMap()[Key] = I.second;
557  }
558 
559  // Output as YAML.
560  Stream << '\t' << AMDGPU::PALMD::AssemblerDirectiveBegin << '\n';
561  MsgPackDoc.toYAML(Stream);
562  Stream << '\t' << AMDGPU::PALMD::AssemblerDirectiveEnd << '\n';
563 
564  // Restore original registers map.
565  RegsObj = OrigRegs;
566 }
567 
568 // Convert the accumulated PAL metadata into a binary blob for writing as
569 // a .note record of the specified AMD type. Returns an empty blob if
570 // there is no PAL metadata,
571 void AMDGPUPALMetadata::toBlob(unsigned Type, std::string &Blob) {
573  toLegacyBlob(Blob);
574  else if (Type)
575  toMsgPackBlob(Blob);
576 }
577 
578 void AMDGPUPALMetadata::toLegacyBlob(std::string &Blob) {
579  Blob.clear();
580  auto Registers = getRegisters();
581  if (Registers.getMap().empty())
582  return;
583  raw_string_ostream OS(Blob);
585  for (auto I : Registers.getMap()) {
586  EW.write(uint32_t(I.first.getUInt()));
587  EW.write(uint32_t(I.second.getUInt()));
588  }
589 }
590 
591 void AMDGPUPALMetadata::toMsgPackBlob(std::string &Blob) {
592  Blob.clear();
593  MsgPackDoc.writeToBlob(Blob);
594 }
595 
596 // Set PAL metadata from YAML text. Returns false if failed.
598  BlobType = ELF::NT_AMDGPU_METADATA;
599  if (!MsgPackDoc.fromYAML(S))
600  return false;
601 
602  // In the registers map, some keys may be of the form "0xa191
603  // (SPI_PS_INPUT_CNTL_0)", in which case the YAML input code made it a
604  // string. We need to turn it into a number.
605  auto &RegsObj = refRegisters();
606  auto OrigRegs = RegsObj;
607  RegsObj = MsgPackDoc.getMapNode();
608  Registers = RegsObj.getMap();
609  bool Ok = true;
610  for (auto I : OrigRegs.getMap()) {
611  auto Key = I.first;
612  if (Key.getKind() == msgpack::Type::String) {
613  StringRef S = Key.getString();
614  uint64_t Val;
615  if (S.consumeInteger(0, Val)) {
616  Ok = false;
617  errs() << "Unrecognized PAL metadata register key '" << S << "'\n";
618  continue;
619  }
620  Key = MsgPackDoc.getNode(uint64_t(Val));
621  }
622  Registers.getMap()[Key] = I.second;
623  }
624  return Ok;
625 }
626 
627 // Reference (create if necessary) the node for the registers map.
628 msgpack::DocNode &AMDGPUPALMetadata::refRegisters() {
629  auto &N =
630  MsgPackDoc.getRoot()
631  .getMap(/*Convert=*/true)[MsgPackDoc.getNode("amdpal.pipelines")]
632  .getArray(/*Convert=*/true)[0]
633  .getMap(/*Convert=*/true)[MsgPackDoc.getNode(".registers")];
634  N.getMap(/*Convert=*/true);
635  return N;
636 }
637 
638 // Get (create if necessary) the registers map.
639 msgpack::MapDocNode AMDGPUPALMetadata::getRegisters() {
640  if (Registers.isEmpty())
641  Registers = refRegisters();
642  return Registers.getMap();
643 }
644 
645 // Return the PAL metadata hardware shader stage name.
646 static const char *getStageName(CallingConv::ID CC) {
647  switch (CC) {
649  return ".ps";
651  return ".vs";
653  return ".gs";
655  return ".es";
657  return ".hs";
659  return ".ls";
660  default:
661  return ".cs";
662  }
663 }
664 
665 // Get (create if necessary) the .hardware_stages entry for the given calling
666 // convention.
667 msgpack::MapDocNode AMDGPUPALMetadata::getHwStage(unsigned CC) {
668  if (HwStages.isEmpty())
669  HwStages = MsgPackDoc.getRoot()
670  .getMap(/*Convert=*/true)["amdpal.pipelines"]
671  .getArray(/*Convert=*/true)[0]
672  .getMap(/*Convert=*/true)[".hardware_stages"]
673  .getMap(/*Convert=*/true);
674  return HwStages.getMap()[getStageName(CC)].getMap(/*Convert=*/true);
675 }
676 
677 // Get .note record vendor name of metadata blob to be emitted.
678 const char *AMDGPUPALMetadata::getVendor() const {
679  return isLegacy() ? ElfNote::NoteNameV2 : ElfNote::NoteNameV3;
680 }
681 
682 // Get .note record type of metadata blob to be emitted:
683 // ELF::NT_AMD_AMDGPU_PAL_METADATA (legacy key=val format), or
684 // ELF::NT_AMDGPU_METADATA (MsgPack format), or
685 // 0 (no PAL metadata).
686 unsigned AMDGPUPALMetadata::getType() const {
687  return BlobType;
688 }
689 
690 // Return whether the blob type is legacy PAL metadata.
691 bool AMDGPUPALMetadata::isLegacy() const {
692  return BlobType == ELF::NT_AMD_AMDGPU_PAL_METADATA;
693 }
694 
695 // Set legacy PAL metadata format.
698 }
699 
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.
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
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)
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
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:130
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 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