Thanks to visit codestin.com
Credit goes to llvm.org

LLVM 22.0.0git
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 "AMDGPUPTNote.h"
19#include "SIDefines.h"
21#include "llvm/IR/Constants.h"
22#include "llvm/IR/Module.h"
23#include "llvm/MC/MCExpr.h"
27
28using namespace llvm;
29using namespace llvm::AMDGPU;
30
31// Return the PAL metadata hardware shader stage name.
32static const char *getStageName(CallingConv::ID CC) {
33 switch (CC) {
35 return ".ps";
37 return ".vs";
39 return ".gs";
41 return ".es";
43 return ".hs";
45 return ".ls";
48 llvm_unreachable("Callable shader has no hardware stage");
49 default:
50 return ".cs";
51 }
52}
53
54// Read the PAL metadata from IR metadata, where it was put by the frontend.
56 auto *NamedMD = M.getNamedMetadata("amdgpu.pal.metadata.msgpack");
57 if (NamedMD && NamedMD->getNumOperands()) {
58 // This is the new msgpack format for metadata. It is a NamedMD containing
59 // an MDTuple containing an MDString containing the msgpack data.
60 BlobType = ELF::NT_AMDGPU_METADATA;
61 auto *MDN = dyn_cast<MDTuple>(NamedMD->getOperand(0));
62 if (MDN && MDN->getNumOperands()) {
63 if (auto *MDS = dyn_cast<MDString>(MDN->getOperand(0)))
64 setFromMsgPackBlob(MDS->getString());
65 }
66 return;
67 }
68 BlobType = ELF::NT_AMD_PAL_METADATA;
69 NamedMD = M.getNamedMetadata("amdgpu.pal.metadata");
70 if (!NamedMD || !NamedMD->getNumOperands()) {
71 // Emit msgpack metadata by default
72 BlobType = ELF::NT_AMDGPU_METADATA;
73 return;
74 }
75 // This is the old reg=value pair format for metadata. It is a NamedMD
76 // containing an MDTuple containing a number of MDNodes each of which is an
77 // integer value, and each two integer values forms a key=value pair that we
78 // store as Registers[key]=value in the map.
79 auto *Tuple = dyn_cast<MDTuple>(NamedMD->getOperand(0));
80 if (!Tuple)
81 return;
82 for (unsigned I = 0, E = Tuple->getNumOperands() & -2; I != E; I += 2) {
83 auto *Key = mdconst::dyn_extract<ConstantInt>(Tuple->getOperand(I));
84 auto *Val = mdconst::dyn_extract<ConstantInt>(Tuple->getOperand(I + 1));
85 if (!Key || !Val)
86 continue;
87 setRegister(Key->getZExtValue(), Val->getZExtValue());
88 }
89}
90
91// Set PAL metadata from a binary blob from the applicable .note record.
92// Returns false if bad format. Blob must remain valid for the lifetime of the
93// Metadata.
95 BlobType = Type;
97 return setFromLegacyBlob(Blob);
98 return setFromMsgPackBlob(Blob);
99}
100
101// Set PAL metadata from legacy (array of key=value pairs) blob.
102bool AMDGPUPALMetadata::setFromLegacyBlob(StringRef Blob) {
103 const auto *Data = reinterpret_cast<const uint32_t *>(Blob.data());
104 for (unsigned I = 0; I != Blob.size() / sizeof(uint32_t) / 2; ++I)
105 setRegister(Data[I * 2], Data[I * 2 + 1]);
106 return true;
107}
108
109// Set PAL metadata from msgpack blob.
110bool AMDGPUPALMetadata::setFromMsgPackBlob(StringRef Blob) {
111 return MsgPackDoc.readFromBlob(Blob, /*Multi=*/false);
112}
113
114// Given the calling convention, calculate the register number for rsrc1. In
115// principle the register number could change in future hardware, but we know
116// it is the same for gfx6-9 (except that LS and ES don't exist on gfx9), so
117// we can use fixed values.
136
137// Calculate the PAL metadata key for *S_SCRATCH_SIZE. It can be used
138// with a constant offset to access any non-register shader-specific PAL
139// metadata key.
158
159// Set the rsrc1 register in the metadata for a particular shader stage.
160// In fact this ORs the value into any previous setting of the register.
162 setRegister(getRsrc1Reg(CC), Val);
163}
164
166 MCContext &Ctx) {
167 setRegister(getRsrc1Reg(CC), Val, Ctx);
168}
169
170// Set the rsrc2 register in the metadata for a particular shader stage.
171// In fact this ORs the value into any previous setting of the register.
173 setRegister(getRsrc1Reg(CC) + 1, Val);
174}
175
177 MCContext &Ctx) {
178 setRegister(getRsrc1Reg(CC) + 1, Val, Ctx);
179}
180
181// Set the SPI_PS_INPUT_ENA register in the metadata.
182// In fact this ORs the value into any previous setting of the register.
186
187// Set the SPI_PS_INPUT_ADDR register in the metadata.
188// In fact this ORs the value into any previous setting of the register.
192
193// Get a register from the metadata, or 0 if not currently set.
194unsigned AMDGPUPALMetadata::getRegister(unsigned Reg) {
195 auto Regs = getRegisters();
196 auto It = Regs.find(MsgPackDoc.getNode(Reg));
197 if (It == Regs.end())
198 return 0;
199 auto N = It->second;
200 if (N.getKind() != msgpack::Type::UInt)
201 return 0;
202 return N.getUInt();
203}
204
205// Set a register in the metadata.
206// In fact this ORs the value into any previous setting of the register.
207void AMDGPUPALMetadata::setRegister(unsigned Reg, unsigned Val) {
208 if (!isLegacy()) {
209 // In the new MsgPack format, ignore register numbered >= 0x10000000. It
210 // is a PAL ABI pseudo-register in the old non-MsgPack format.
211 if (Reg >= 0x10000000)
212 return;
213 }
214 auto &N = getRegisters()[MsgPackDoc.getNode(Reg)];
215 if (N.getKind() == msgpack::Type::UInt)
216 Val |= N.getUInt();
217 N = N.getDocument()->getNode(Val);
218}
219
220// Set a register in the metadata.
221// In fact this ORs the value into any previous setting of the register.
222void AMDGPUPALMetadata::setRegister(unsigned Reg, const MCExpr *Val,
223 MCContext &Ctx) {
224 if (!isLegacy()) {
225 // In the new MsgPack format, ignore register numbered >= 0x10000000. It
226 // is a PAL ABI pseudo-register in the old non-MsgPack format.
227 if (Reg >= 0x10000000)
228 return;
229 }
230 auto &N = getRegisters()[MsgPackDoc.getNode(Reg)];
231 auto [ExprIt, Inserted] = REM.try_emplace(Reg);
232
233 if (!Inserted) {
234 Val = MCBinaryExpr::createOr(Val, ExprIt->getSecond(), Ctx);
235 // This conditional may be redundant most of the time, but the alternate
236 // setRegister(unsigned, unsigned) could've been called while the
237 // conditional returns true (i.e., Reg exists in REM).
238 if (N.getKind() == msgpack::Type::UInt) {
239 const MCExpr *NExpr = MCConstantExpr::create(N.getUInt(), Ctx);
240 Val = MCBinaryExpr::createOr(Val, NExpr, Ctx);
241 }
242 } else if (N.getKind() == msgpack::Type::UInt) {
243 const MCExpr *NExpr = MCConstantExpr::create(N.getUInt(), Ctx);
244 Val = MCBinaryExpr::createOr(Val, NExpr, Ctx);
245 } else {
246 // Default to uint64_t 0 so additional calls to setRegister will allow
247 // propagate ORs.
248 N = (uint64_t)0;
249 }
250 ExprIt->second = Val;
251 DelayedExprs.assignDocNode(N, msgpack::Type::UInt, Val);
252}
253
254// Set the entry point name for one shader.
256 if (isLegacy())
257 return;
258 // Msgpack format.
259 // Entry point is updated to .entry_point_symbol and is set to the function
260 // name
261 getHwStage(CC)[".entry_point_symbol"] =
262 MsgPackDoc.getNode(Name, /*Copy=*/true);
263
264 // For PAL version 3.6 and above, entry_point is no longer required.
265 if (getPALVersion() < VersionTuple(3, 6)) {
266 // Set .entry_point which is defined to be _amdgpu_<stage>_main and
267 // _amdgpu_cs_main for non-shader functions.
268 SmallString<16> EPName("_amdgpu_");
269 raw_svector_ostream EPNameOS(EPName);
270 EPNameOS << getStageName(CC) + 1 << "_main";
271 getHwStage(CC)[".entry_point"] =
272 MsgPackDoc.getNode(EPNameOS.str(), /*Copy=*/true);
273 }
274}
275
276// Set the number of used vgprs in the metadata. This is an optional
277// advisory record for logging etc; wave dispatch actually uses the rsrc1
278// register for the shader stage to determine the number of vgprs to
279// allocate.
281 if (isLegacy()) {
282 // Old non-msgpack format.
283 unsigned NumUsedVgprsKey = getScratchSizeKey(CC) +
286 setRegister(NumUsedVgprsKey, Val);
287 return;
288 }
289 // Msgpack format.
290 getHwStage(CC)[".vgpr_count"] = MsgPackDoc.getNode(Val);
291}
292
294 MCContext &Ctx) {
295 if (isLegacy()) {
296 // Old non-msgpack format.
297 unsigned NumUsedVgprsKey = getScratchSizeKey(CC) +
300 setRegister(NumUsedVgprsKey, Val, Ctx);
301 return;
302 }
303 // Msgpack format.
304 setHwStage(CC, ".vgpr_count", msgpack::Type::UInt, Val);
305}
306
307// Set the number of used agprs in the metadata.
309 getHwStage(CC)[".agpr_count"] = Val;
310}
311
312void AMDGPUPALMetadata::setNumUsedAgprs(unsigned CC, const MCExpr *Val) {
313 setHwStage(CC, ".agpr_count", msgpack::Type::UInt, Val);
314}
315
316// Set the number of used sgprs in the metadata. This is an optional advisory
317// record for logging etc; wave dispatch actually uses the rsrc1 register for
318// the shader stage to determine the number of sgprs to allocate.
320 if (isLegacy()) {
321 // Old non-msgpack format.
322 unsigned NumUsedSgprsKey = getScratchSizeKey(CC) +
325 setRegister(NumUsedSgprsKey, Val);
326 return;
327 }
328 // Msgpack format.
329 getHwStage(CC)[".sgpr_count"] = MsgPackDoc.getNode(Val);
330}
331
332void AMDGPUPALMetadata::setNumUsedSgprs(unsigned CC, const MCExpr *Val,
333 MCContext &Ctx) {
334 if (isLegacy()) {
335 // Old non-msgpack format.
336 unsigned NumUsedSgprsKey = getScratchSizeKey(CC) +
339 setRegister(NumUsedSgprsKey, Val, Ctx);
340 return;
341 }
342 // Msgpack format.
343 setHwStage(CC, ".sgpr_count", msgpack::Type::UInt, Val);
344}
345
346// Set the scratch size in the metadata.
348 if (isLegacy()) {
349 // Old non-msgpack format.
351 return;
352 }
353 // Msgpack format.
354 getHwStage(CC)[".scratch_memory_size"] = MsgPackDoc.getNode(Val);
355}
356
357void AMDGPUPALMetadata::setScratchSize(unsigned CC, const MCExpr *Val,
358 MCContext &Ctx) {
359 if (isLegacy()) {
360 // Old non-msgpack format.
361 setRegister(getScratchSizeKey(CC), Val, Ctx);
362 return;
363 }
364 // Msgpack format.
365 setHwStage(CC, ".scratch_memory_size", msgpack::Type::UInt, Val);
366}
367
368// Set the stack frame size of a function in the metadata.
370 auto Node = getShaderFunction(FnName);
371 Node[".stack_frame_size_in_bytes"] = MsgPackDoc.getNode(Val);
372 Node[".backend_stack_size"] = MsgPackDoc.getNode(Val);
373}
374
375// Set the amount of LDS used in bytes in the metadata.
377 auto Node = getShaderFunction(FnName);
378 Node[".lds_size"] = MsgPackDoc.getNode(Val);
379}
380
381// Set the number of used vgprs in the metadata.
383 unsigned Val) {
384 auto Node = getShaderFunction(FnName);
385 Node[".vgpr_count"] = MsgPackDoc.getNode(Val);
386}
387
389 const MCExpr *Val) {
390 auto Node = getShaderFunction(FnName);
391 DelayedExprs.assignDocNode(Node[".vgpr_count"], msgpack::Type::UInt, Val);
392}
393
394// Set the number of used vgprs in the metadata.
396 unsigned Val) {
397 auto Node = getShaderFunction(FnName);
398 Node[".sgpr_count"] = MsgPackDoc.getNode(Val);
399}
400
402 const MCExpr *Val) {
403 auto Node = getShaderFunction(FnName);
404 DelayedExprs.assignDocNode(Node[".sgpr_count"], msgpack::Type::UInt, Val);
405}
406
407// Set the hardware register bit in PAL metadata to enable wave32 on the
408// shader of the given calling convention.
429
430// Convert a register number to name, for display by toString().
431// Returns nullptr if none.
432static const char *getRegisterName(unsigned RegNum) {
433 // Table of registers.
434 static const struct RegInfo {
435 unsigned Num;
436 const char *Name;
437 } RegInfoTable[] = {
438 // Registers that code generation sets/modifies metadata for.
439 {PALMD::R_2C4A_SPI_SHADER_PGM_RSRC1_VS, "SPI_SHADER_PGM_RSRC1_VS"},
440 {PALMD::R_2C4A_SPI_SHADER_PGM_RSRC1_VS + 1, "SPI_SHADER_PGM_RSRC2_VS"},
441 {PALMD::R_2D4A_SPI_SHADER_PGM_RSRC1_LS, "SPI_SHADER_PGM_RSRC1_LS"},
442 {PALMD::R_2D4A_SPI_SHADER_PGM_RSRC1_LS + 1, "SPI_SHADER_PGM_RSRC2_LS"},
443 {PALMD::R_2D0A_SPI_SHADER_PGM_RSRC1_HS, "SPI_SHADER_PGM_RSRC1_HS"},
444 {PALMD::R_2D0A_SPI_SHADER_PGM_RSRC1_HS + 1, "SPI_SHADER_PGM_RSRC2_HS"},
445 {PALMD::R_2CCA_SPI_SHADER_PGM_RSRC1_ES, "SPI_SHADER_PGM_RSRC1_ES"},
446 {PALMD::R_2CCA_SPI_SHADER_PGM_RSRC1_ES + 1, "SPI_SHADER_PGM_RSRC2_ES"},
447 {PALMD::R_2C8A_SPI_SHADER_PGM_RSRC1_GS, "SPI_SHADER_PGM_RSRC1_GS"},
448 {PALMD::R_2C8A_SPI_SHADER_PGM_RSRC1_GS + 1, "SPI_SHADER_PGM_RSRC2_GS"},
449 {PALMD::R_2E00_COMPUTE_DISPATCH_INITIATOR, "COMPUTE_DISPATCH_INITIATOR"},
450 {PALMD::R_2E12_COMPUTE_PGM_RSRC1, "COMPUTE_PGM_RSRC1"},
451 {PALMD::R_2E12_COMPUTE_PGM_RSRC1 + 1, "COMPUTE_PGM_RSRC2"},
452 {PALMD::R_2C0A_SPI_SHADER_PGM_RSRC1_PS, "SPI_SHADER_PGM_RSRC1_PS"},
453 {PALMD::R_2C0A_SPI_SHADER_PGM_RSRC1_PS + 1, "SPI_SHADER_PGM_RSRC2_PS"},
454 {PALMD::R_A1B3_SPI_PS_INPUT_ENA, "SPI_PS_INPUT_ENA"},
455 {PALMD::R_A1B4_SPI_PS_INPUT_ADDR, "SPI_PS_INPUT_ADDR"},
456 {PALMD::R_A1B6_SPI_PS_IN_CONTROL, "SPI_PS_IN_CONTROL"},
457 {PALMD::R_A2D5_VGT_SHADER_STAGES_EN, "VGT_SHADER_STAGES_EN"},
458
459 // Registers not known to code generation.
460 {0x2c07, "SPI_SHADER_PGM_RSRC3_PS"},
461 {0x2c46, "SPI_SHADER_PGM_RSRC3_VS"},
462 {0x2c87, "SPI_SHADER_PGM_RSRC3_GS"},
463 {0x2cc7, "SPI_SHADER_PGM_RSRC3_ES"},
464 {0x2d07, "SPI_SHADER_PGM_RSRC3_HS"},
465 {0x2d47, "SPI_SHADER_PGM_RSRC3_LS"},
466
467 {0xa1c3, "SPI_SHADER_POS_FORMAT"},
468 {0xa1b1, "SPI_VS_OUT_CONFIG"},
469 {0xa207, "PA_CL_VS_OUT_CNTL"},
470 {0xa204, "PA_CL_CLIP_CNTL"},
471 {0xa206, "PA_CL_VTE_CNTL"},
472 {0xa2f9, "PA_SU_VTX_CNTL"},
473 {0xa293, "PA_SC_MODE_CNTL_1"},
474 {0xa2a1, "VGT_PRIMITIVEID_EN"},
475 {0x2c81, "SPI_SHADER_PGM_RSRC4_GS"},
476 {0x2e18, "COMPUTE_TMPRING_SIZE"},
477 {0xa1b5, "SPI_INTERP_CONTROL_0"},
478 {0xa1ba, "SPI_TMPRING_SIZE"},
479 {0xa1c4, "SPI_SHADER_Z_FORMAT"},
480 {0xa1c5, "SPI_SHADER_COL_FORMAT"},
481 {0xa203, "DB_SHADER_CONTROL"},
482 {0xa08f, "CB_SHADER_MASK"},
483 {0xa191, "SPI_PS_INPUT_CNTL_0"},
484 {0xa192, "SPI_PS_INPUT_CNTL_1"},
485 {0xa193, "SPI_PS_INPUT_CNTL_2"},
486 {0xa194, "SPI_PS_INPUT_CNTL_3"},
487 {0xa195, "SPI_PS_INPUT_CNTL_4"},
488 {0xa196, "SPI_PS_INPUT_CNTL_5"},
489 {0xa197, "SPI_PS_INPUT_CNTL_6"},
490 {0xa198, "SPI_PS_INPUT_CNTL_7"},
491 {0xa199, "SPI_PS_INPUT_CNTL_8"},
492 {0xa19a, "SPI_PS_INPUT_CNTL_9"},
493 {0xa19b, "SPI_PS_INPUT_CNTL_10"},
494 {0xa19c, "SPI_PS_INPUT_CNTL_11"},
495 {0xa19d, "SPI_PS_INPUT_CNTL_12"},
496 {0xa19e, "SPI_PS_INPUT_CNTL_13"},
497 {0xa19f, "SPI_PS_INPUT_CNTL_14"},
498 {0xa1a0, "SPI_PS_INPUT_CNTL_15"},
499 {0xa1a1, "SPI_PS_INPUT_CNTL_16"},
500 {0xa1a2, "SPI_PS_INPUT_CNTL_17"},
501 {0xa1a3, "SPI_PS_INPUT_CNTL_18"},
502 {0xa1a4, "SPI_PS_INPUT_CNTL_19"},
503 {0xa1a5, "SPI_PS_INPUT_CNTL_20"},
504 {0xa1a6, "SPI_PS_INPUT_CNTL_21"},
505 {0xa1a7, "SPI_PS_INPUT_CNTL_22"},
506 {0xa1a8, "SPI_PS_INPUT_CNTL_23"},
507 {0xa1a9, "SPI_PS_INPUT_CNTL_24"},
508 {0xa1aa, "SPI_PS_INPUT_CNTL_25"},
509 {0xa1ab, "SPI_PS_INPUT_CNTL_26"},
510 {0xa1ac, "SPI_PS_INPUT_CNTL_27"},
511 {0xa1ad, "SPI_PS_INPUT_CNTL_28"},
512 {0xa1ae, "SPI_PS_INPUT_CNTL_29"},
513 {0xa1af, "SPI_PS_INPUT_CNTL_30"},
514 {0xa1b0, "SPI_PS_INPUT_CNTL_31"},
515
516 {0xa2ce, "VGT_GS_MAX_VERT_OUT"},
517 {0xa2ab, "VGT_ESGS_RING_ITEMSIZE"},
518 {0xa290, "VGT_GS_MODE"},
519 {0xa291, "VGT_GS_ONCHIP_CNTL"},
520 {0xa2d7, "VGT_GS_VERT_ITEMSIZE"},
521 {0xa2d8, "VGT_GS_VERT_ITEMSIZE_1"},
522 {0xa2d9, "VGT_GS_VERT_ITEMSIZE_2"},
523 {0xa2da, "VGT_GS_VERT_ITEMSIZE_3"},
524 {0xa298, "VGT_GSVS_RING_OFFSET_1"},
525 {0xa299, "VGT_GSVS_RING_OFFSET_2"},
526 {0xa29a, "VGT_GSVS_RING_OFFSET_3"},
527
528 {0xa2e4, "VGT_GS_INSTANCE_CNT"},
529 {0xa297, "VGT_GS_PER_VS"},
530 {0xa29b, "VGT_GS_OUT_PRIM_TYPE"},
531 {0xa2ac, "VGT_GSVS_RING_ITEMSIZE"},
532
533 {0xa2ad, "VGT_REUSE_OFF"},
534 {0xa1b8, "SPI_BARYC_CNTL"},
535
536 {0x2c4c, "SPI_SHADER_USER_DATA_VS_0"},
537 {0x2c4d, "SPI_SHADER_USER_DATA_VS_1"},
538 {0x2c4e, "SPI_SHADER_USER_DATA_VS_2"},
539 {0x2c4f, "SPI_SHADER_USER_DATA_VS_3"},
540 {0x2c50, "SPI_SHADER_USER_DATA_VS_4"},
541 {0x2c51, "SPI_SHADER_USER_DATA_VS_5"},
542 {0x2c52, "SPI_SHADER_USER_DATA_VS_6"},
543 {0x2c53, "SPI_SHADER_USER_DATA_VS_7"},
544 {0x2c54, "SPI_SHADER_USER_DATA_VS_8"},
545 {0x2c55, "SPI_SHADER_USER_DATA_VS_9"},
546 {0x2c56, "SPI_SHADER_USER_DATA_VS_10"},
547 {0x2c57, "SPI_SHADER_USER_DATA_VS_11"},
548 {0x2c58, "SPI_SHADER_USER_DATA_VS_12"},
549 {0x2c59, "SPI_SHADER_USER_DATA_VS_13"},
550 {0x2c5a, "SPI_SHADER_USER_DATA_VS_14"},
551 {0x2c5b, "SPI_SHADER_USER_DATA_VS_15"},
552 {0x2c5c, "SPI_SHADER_USER_DATA_VS_16"},
553 {0x2c5d, "SPI_SHADER_USER_DATA_VS_17"},
554 {0x2c5e, "SPI_SHADER_USER_DATA_VS_18"},
555 {0x2c5f, "SPI_SHADER_USER_DATA_VS_19"},
556 {0x2c60, "SPI_SHADER_USER_DATA_VS_20"},
557 {0x2c61, "SPI_SHADER_USER_DATA_VS_21"},
558 {0x2c62, "SPI_SHADER_USER_DATA_VS_22"},
559 {0x2c63, "SPI_SHADER_USER_DATA_VS_23"},
560 {0x2c64, "SPI_SHADER_USER_DATA_VS_24"},
561 {0x2c65, "SPI_SHADER_USER_DATA_VS_25"},
562 {0x2c66, "SPI_SHADER_USER_DATA_VS_26"},
563 {0x2c67, "SPI_SHADER_USER_DATA_VS_27"},
564 {0x2c68, "SPI_SHADER_USER_DATA_VS_28"},
565 {0x2c69, "SPI_SHADER_USER_DATA_VS_29"},
566 {0x2c6a, "SPI_SHADER_USER_DATA_VS_30"},
567 {0x2c6b, "SPI_SHADER_USER_DATA_VS_31"},
568
569 {0x2c8c, "SPI_SHADER_USER_DATA_GS_0"},
570 {0x2c8d, "SPI_SHADER_USER_DATA_GS_1"},
571 {0x2c8e, "SPI_SHADER_USER_DATA_GS_2"},
572 {0x2c8f, "SPI_SHADER_USER_DATA_GS_3"},
573 {0x2c90, "SPI_SHADER_USER_DATA_GS_4"},
574 {0x2c91, "SPI_SHADER_USER_DATA_GS_5"},
575 {0x2c92, "SPI_SHADER_USER_DATA_GS_6"},
576 {0x2c93, "SPI_SHADER_USER_DATA_GS_7"},
577 {0x2c94, "SPI_SHADER_USER_DATA_GS_8"},
578 {0x2c95, "SPI_SHADER_USER_DATA_GS_9"},
579 {0x2c96, "SPI_SHADER_USER_DATA_GS_10"},
580 {0x2c97, "SPI_SHADER_USER_DATA_GS_11"},
581 {0x2c98, "SPI_SHADER_USER_DATA_GS_12"},
582 {0x2c99, "SPI_SHADER_USER_DATA_GS_13"},
583 {0x2c9a, "SPI_SHADER_USER_DATA_GS_14"},
584 {0x2c9b, "SPI_SHADER_USER_DATA_GS_15"},
585 {0x2c9c, "SPI_SHADER_USER_DATA_GS_16"},
586 {0x2c9d, "SPI_SHADER_USER_DATA_GS_17"},
587 {0x2c9e, "SPI_SHADER_USER_DATA_GS_18"},
588 {0x2c9f, "SPI_SHADER_USER_DATA_GS_19"},
589 {0x2ca0, "SPI_SHADER_USER_DATA_GS_20"},
590 {0x2ca1, "SPI_SHADER_USER_DATA_GS_21"},
591 {0x2ca2, "SPI_SHADER_USER_DATA_GS_22"},
592 {0x2ca3, "SPI_SHADER_USER_DATA_GS_23"},
593 {0x2ca4, "SPI_SHADER_USER_DATA_GS_24"},
594 {0x2ca5, "SPI_SHADER_USER_DATA_GS_25"},
595 {0x2ca6, "SPI_SHADER_USER_DATA_GS_26"},
596 {0x2ca7, "SPI_SHADER_USER_DATA_GS_27"},
597 {0x2ca8, "SPI_SHADER_USER_DATA_GS_28"},
598 {0x2ca9, "SPI_SHADER_USER_DATA_GS_29"},
599 {0x2caa, "SPI_SHADER_USER_DATA_GS_30"},
600 {0x2cab, "SPI_SHADER_USER_DATA_GS_31"},
601
602 {0x2ccc, "SPI_SHADER_USER_DATA_ES_0"},
603 {0x2ccd, "SPI_SHADER_USER_DATA_ES_1"},
604 {0x2cce, "SPI_SHADER_USER_DATA_ES_2"},
605 {0x2ccf, "SPI_SHADER_USER_DATA_ES_3"},
606 {0x2cd0, "SPI_SHADER_USER_DATA_ES_4"},
607 {0x2cd1, "SPI_SHADER_USER_DATA_ES_5"},
608 {0x2cd2, "SPI_SHADER_USER_DATA_ES_6"},
609 {0x2cd3, "SPI_SHADER_USER_DATA_ES_7"},
610 {0x2cd4, "SPI_SHADER_USER_DATA_ES_8"},
611 {0x2cd5, "SPI_SHADER_USER_DATA_ES_9"},
612 {0x2cd6, "SPI_SHADER_USER_DATA_ES_10"},
613 {0x2cd7, "SPI_SHADER_USER_DATA_ES_11"},
614 {0x2cd8, "SPI_SHADER_USER_DATA_ES_12"},
615 {0x2cd9, "SPI_SHADER_USER_DATA_ES_13"},
616 {0x2cda, "SPI_SHADER_USER_DATA_ES_14"},
617 {0x2cdb, "SPI_SHADER_USER_DATA_ES_15"},
618 {0x2cdc, "SPI_SHADER_USER_DATA_ES_16"},
619 {0x2cdd, "SPI_SHADER_USER_DATA_ES_17"},
620 {0x2cde, "SPI_SHADER_USER_DATA_ES_18"},
621 {0x2cdf, "SPI_SHADER_USER_DATA_ES_19"},
622 {0x2ce0, "SPI_SHADER_USER_DATA_ES_20"},
623 {0x2ce1, "SPI_SHADER_USER_DATA_ES_21"},
624 {0x2ce2, "SPI_SHADER_USER_DATA_ES_22"},
625 {0x2ce3, "SPI_SHADER_USER_DATA_ES_23"},
626 {0x2ce4, "SPI_SHADER_USER_DATA_ES_24"},
627 {0x2ce5, "SPI_SHADER_USER_DATA_ES_25"},
628 {0x2ce6, "SPI_SHADER_USER_DATA_ES_26"},
629 {0x2ce7, "SPI_SHADER_USER_DATA_ES_27"},
630 {0x2ce8, "SPI_SHADER_USER_DATA_ES_28"},
631 {0x2ce9, "SPI_SHADER_USER_DATA_ES_29"},
632 {0x2cea, "SPI_SHADER_USER_DATA_ES_30"},
633 {0x2ceb, "SPI_SHADER_USER_DATA_ES_31"},
634
635 {0x2c0c, "SPI_SHADER_USER_DATA_PS_0"},
636 {0x2c0d, "SPI_SHADER_USER_DATA_PS_1"},
637 {0x2c0e, "SPI_SHADER_USER_DATA_PS_2"},
638 {0x2c0f, "SPI_SHADER_USER_DATA_PS_3"},
639 {0x2c10, "SPI_SHADER_USER_DATA_PS_4"},
640 {0x2c11, "SPI_SHADER_USER_DATA_PS_5"},
641 {0x2c12, "SPI_SHADER_USER_DATA_PS_6"},
642 {0x2c13, "SPI_SHADER_USER_DATA_PS_7"},
643 {0x2c14, "SPI_SHADER_USER_DATA_PS_8"},
644 {0x2c15, "SPI_SHADER_USER_DATA_PS_9"},
645 {0x2c16, "SPI_SHADER_USER_DATA_PS_10"},
646 {0x2c17, "SPI_SHADER_USER_DATA_PS_11"},
647 {0x2c18, "SPI_SHADER_USER_DATA_PS_12"},
648 {0x2c19, "SPI_SHADER_USER_DATA_PS_13"},
649 {0x2c1a, "SPI_SHADER_USER_DATA_PS_14"},
650 {0x2c1b, "SPI_SHADER_USER_DATA_PS_15"},
651 {0x2c1c, "SPI_SHADER_USER_DATA_PS_16"},
652 {0x2c1d, "SPI_SHADER_USER_DATA_PS_17"},
653 {0x2c1e, "SPI_SHADER_USER_DATA_PS_18"},
654 {0x2c1f, "SPI_SHADER_USER_DATA_PS_19"},
655 {0x2c20, "SPI_SHADER_USER_DATA_PS_20"},
656 {0x2c21, "SPI_SHADER_USER_DATA_PS_21"},
657 {0x2c22, "SPI_SHADER_USER_DATA_PS_22"},
658 {0x2c23, "SPI_SHADER_USER_DATA_PS_23"},
659 {0x2c24, "SPI_SHADER_USER_DATA_PS_24"},
660 {0x2c25, "SPI_SHADER_USER_DATA_PS_25"},
661 {0x2c26, "SPI_SHADER_USER_DATA_PS_26"},
662 {0x2c27, "SPI_SHADER_USER_DATA_PS_27"},
663 {0x2c28, "SPI_SHADER_USER_DATA_PS_28"},
664 {0x2c29, "SPI_SHADER_USER_DATA_PS_29"},
665 {0x2c2a, "SPI_SHADER_USER_DATA_PS_30"},
666 {0x2c2b, "SPI_SHADER_USER_DATA_PS_31"},
667
668 {0x2e40, "COMPUTE_USER_DATA_0"},
669 {0x2e41, "COMPUTE_USER_DATA_1"},
670 {0x2e42, "COMPUTE_USER_DATA_2"},
671 {0x2e43, "COMPUTE_USER_DATA_3"},
672 {0x2e44, "COMPUTE_USER_DATA_4"},
673 {0x2e45, "COMPUTE_USER_DATA_5"},
674 {0x2e46, "COMPUTE_USER_DATA_6"},
675 {0x2e47, "COMPUTE_USER_DATA_7"},
676 {0x2e48, "COMPUTE_USER_DATA_8"},
677 {0x2e49, "COMPUTE_USER_DATA_9"},
678 {0x2e4a, "COMPUTE_USER_DATA_10"},
679 {0x2e4b, "COMPUTE_USER_DATA_11"},
680 {0x2e4c, "COMPUTE_USER_DATA_12"},
681 {0x2e4d, "COMPUTE_USER_DATA_13"},
682 {0x2e4e, "COMPUTE_USER_DATA_14"},
683 {0x2e4f, "COMPUTE_USER_DATA_15"},
684 {0x2e50, "COMPUTE_USER_DATA_16"},
685 {0x2e51, "COMPUTE_USER_DATA_17"},
686 {0x2e52, "COMPUTE_USER_DATA_18"},
687 {0x2e53, "COMPUTE_USER_DATA_19"},
688 {0x2e54, "COMPUTE_USER_DATA_20"},
689 {0x2e55, "COMPUTE_USER_DATA_21"},
690 {0x2e56, "COMPUTE_USER_DATA_22"},
691 {0x2e57, "COMPUTE_USER_DATA_23"},
692 {0x2e58, "COMPUTE_USER_DATA_24"},
693 {0x2e59, "COMPUTE_USER_DATA_25"},
694 {0x2e5a, "COMPUTE_USER_DATA_26"},
695 {0x2e5b, "COMPUTE_USER_DATA_27"},
696 {0x2e5c, "COMPUTE_USER_DATA_28"},
697 {0x2e5d, "COMPUTE_USER_DATA_29"},
698 {0x2e5e, "COMPUTE_USER_DATA_30"},
699 {0x2e5f, "COMPUTE_USER_DATA_31"},
700
701 {0x2e07, "COMPUTE_NUM_THREAD_X"},
702 {0x2e08, "COMPUTE_NUM_THREAD_Y"},
703 {0x2e09, "COMPUTE_NUM_THREAD_Z"},
704 {0xa2db, "VGT_TF_PARAM"},
705 {0xa2d6, "VGT_LS_HS_CONFIG"},
706 {0xa287, "VGT_HOS_MIN_TESS_LEVEL"},
707 {0xa286, "VGT_HOS_MAX_TESS_LEVEL"},
708 {0xa2f8, "PA_SC_AA_CONFIG"},
709 {0xa310, "PA_SC_SHADER_CONTROL"},
710 {0xa313, "PA_SC_CONSERVATIVE_RASTERIZATION_CNTL"},
711
712 {0x2d0c, "SPI_SHADER_USER_DATA_HS_0"},
713 {0x2d0d, "SPI_SHADER_USER_DATA_HS_1"},
714 {0x2d0e, "SPI_SHADER_USER_DATA_HS_2"},
715 {0x2d0f, "SPI_SHADER_USER_DATA_HS_3"},
716 {0x2d10, "SPI_SHADER_USER_DATA_HS_4"},
717 {0x2d11, "SPI_SHADER_USER_DATA_HS_5"},
718 {0x2d12, "SPI_SHADER_USER_DATA_HS_6"},
719 {0x2d13, "SPI_SHADER_USER_DATA_HS_7"},
720 {0x2d14, "SPI_SHADER_USER_DATA_HS_8"},
721 {0x2d15, "SPI_SHADER_USER_DATA_HS_9"},
722 {0x2d16, "SPI_SHADER_USER_DATA_HS_10"},
723 {0x2d17, "SPI_SHADER_USER_DATA_HS_11"},
724 {0x2d18, "SPI_SHADER_USER_DATA_HS_12"},
725 {0x2d19, "SPI_SHADER_USER_DATA_HS_13"},
726 {0x2d1a, "SPI_SHADER_USER_DATA_HS_14"},
727 {0x2d1b, "SPI_SHADER_USER_DATA_HS_15"},
728 {0x2d1c, "SPI_SHADER_USER_DATA_HS_16"},
729 {0x2d1d, "SPI_SHADER_USER_DATA_HS_17"},
730 {0x2d1e, "SPI_SHADER_USER_DATA_HS_18"},
731 {0x2d1f, "SPI_SHADER_USER_DATA_HS_19"},
732 {0x2d20, "SPI_SHADER_USER_DATA_HS_20"},
733 {0x2d21, "SPI_SHADER_USER_DATA_HS_21"},
734 {0x2d22, "SPI_SHADER_USER_DATA_HS_22"},
735 {0x2d23, "SPI_SHADER_USER_DATA_HS_23"},
736 {0x2d24, "SPI_SHADER_USER_DATA_HS_24"},
737 {0x2d25, "SPI_SHADER_USER_DATA_HS_25"},
738 {0x2d26, "SPI_SHADER_USER_DATA_HS_26"},
739 {0x2d27, "SPI_SHADER_USER_DATA_HS_27"},
740 {0x2d28, "SPI_SHADER_USER_DATA_HS_28"},
741 {0x2d29, "SPI_SHADER_USER_DATA_HS_29"},
742 {0x2d2a, "SPI_SHADER_USER_DATA_HS_30"},
743 {0x2d2b, "SPI_SHADER_USER_DATA_HS_31"},
744
745 {0x2d4c, "SPI_SHADER_USER_DATA_LS_0"},
746 {0x2d4d, "SPI_SHADER_USER_DATA_LS_1"},
747 {0x2d4e, "SPI_SHADER_USER_DATA_LS_2"},
748 {0x2d4f, "SPI_SHADER_USER_DATA_LS_3"},
749 {0x2d50, "SPI_SHADER_USER_DATA_LS_4"},
750 {0x2d51, "SPI_SHADER_USER_DATA_LS_5"},
751 {0x2d52, "SPI_SHADER_USER_DATA_LS_6"},
752 {0x2d53, "SPI_SHADER_USER_DATA_LS_7"},
753 {0x2d54, "SPI_SHADER_USER_DATA_LS_8"},
754 {0x2d55, "SPI_SHADER_USER_DATA_LS_9"},
755 {0x2d56, "SPI_SHADER_USER_DATA_LS_10"},
756 {0x2d57, "SPI_SHADER_USER_DATA_LS_11"},
757 {0x2d58, "SPI_SHADER_USER_DATA_LS_12"},
758 {0x2d59, "SPI_SHADER_USER_DATA_LS_13"},
759 {0x2d5a, "SPI_SHADER_USER_DATA_LS_14"},
760 {0x2d5b, "SPI_SHADER_USER_DATA_LS_15"},
761
762 {0xa2aa, "IA_MULTI_VGT_PARAM"},
763 {0xa2a5, "VGT_GS_MAX_PRIMS_PER_SUBGROUP"},
764 {0xa2e6, "VGT_STRMOUT_BUFFER_CONFIG"},
765 {0xa2e5, "VGT_STRMOUT_CONFIG"},
766 {0xa2b5, "VGT_STRMOUT_VTX_STRIDE_0"},
767 {0xa2b9, "VGT_STRMOUT_VTX_STRIDE_1"},
768 {0xa2bd, "VGT_STRMOUT_VTX_STRIDE_2"},
769 {0xa2c1, "VGT_STRMOUT_VTX_STRIDE_3"},
770 {0xa316, "VGT_VERTEX_REUSE_BLOCK_CNTL"},
771
772 {0x2e28, "COMPUTE_PGM_RSRC3"},
773 {0x2e2a, "COMPUTE_SHADER_CHKSUM"},
774 {0x2e24, "COMPUTE_USER_ACCUM_0"},
775 {0x2e25, "COMPUTE_USER_ACCUM_1"},
776 {0x2e26, "COMPUTE_USER_ACCUM_2"},
777 {0x2e27, "COMPUTE_USER_ACCUM_3"},
778 {0xa1ff, "GE_MAX_OUTPUT_PER_SUBGROUP"},
779 {0xa2d3, "GE_NGG_SUBGRP_CNTL"},
780 {0xc25f, "GE_STEREO_CNTL"},
781 {0xc262, "GE_USER_VGPR_EN"},
782 {0xc258, "IA_MULTI_VGT_PARAM_PIPED"},
783 {0xa210, "PA_STEREO_CNTL"},
784 {0xa1c2, "SPI_SHADER_IDX_FORMAT"},
785 {0x2c80, "SPI_SHADER_PGM_CHKSUM_GS"},
786 {0x2d00, "SPI_SHADER_PGM_CHKSUM_HS"},
787 {0x2c06, "SPI_SHADER_PGM_CHKSUM_PS"},
788 {0x2c45, "SPI_SHADER_PGM_CHKSUM_VS"},
789 {0x2c88, "SPI_SHADER_PGM_LO_GS"},
790 {0x2cb2, "SPI_SHADER_USER_ACCUM_ESGS_0"},
791 {0x2cb3, "SPI_SHADER_USER_ACCUM_ESGS_1"},
792 {0x2cb4, "SPI_SHADER_USER_ACCUM_ESGS_2"},
793 {0x2cb5, "SPI_SHADER_USER_ACCUM_ESGS_3"},
794 {0x2d32, "SPI_SHADER_USER_ACCUM_LSHS_0"},
795 {0x2d33, "SPI_SHADER_USER_ACCUM_LSHS_1"},
796 {0x2d34, "SPI_SHADER_USER_ACCUM_LSHS_2"},
797 {0x2d35, "SPI_SHADER_USER_ACCUM_LSHS_3"},
798 {0x2c32, "SPI_SHADER_USER_ACCUM_PS_0"},
799 {0x2c33, "SPI_SHADER_USER_ACCUM_PS_1"},
800 {0x2c34, "SPI_SHADER_USER_ACCUM_PS_2"},
801 {0x2c35, "SPI_SHADER_USER_ACCUM_PS_3"},
802 {0x2c72, "SPI_SHADER_USER_ACCUM_VS_0"},
803 {0x2c73, "SPI_SHADER_USER_ACCUM_VS_1"},
804 {0x2c74, "SPI_SHADER_USER_ACCUM_VS_2"},
805 {0x2c75, "SPI_SHADER_USER_ACCUM_VS_3"},
806
807 {0, nullptr}};
808 const auto *Entry = RegInfoTable;
809 for (; Entry->Num && Entry->Num != RegNum; ++Entry)
810 ;
811 return Entry->Name;
812}
813
814// Convert the accumulated PAL metadata into an asm directive.
816 String.clear();
817 if (!BlobType)
818 return;
819 ResolvedAll = DelayedExprs.resolveDelayedExpressions();
821 if (isLegacy()) {
822 if (MsgPackDoc.getRoot().getKind() == msgpack::Type::Nil)
823 return;
824 // Old linear reg=val format.
825 Stream << '\t' << AMDGPU::PALMD::AssemblerDirective << ' ';
826 auto Regs = getRegisters();
827 for (auto I = Regs.begin(), E = Regs.end(); I != E; ++I) {
828 if (I != Regs.begin())
829 Stream << ',';
830 unsigned Reg = I->first.getUInt();
831 unsigned Val = I->second.getUInt();
832 Stream << "0x" << Twine::utohexstr(Reg) << ",0x" << Twine::utohexstr(Val);
833 }
834 Stream << '\n';
835 return;
836 }
837
838 // New msgpack-based format -- output as YAML (with unsigned numbers in hex),
839 // but first change the registers map to use names.
840 MsgPackDoc.setHexMode();
841 auto &RegsObj = refRegisters();
842 auto OrigRegs = RegsObj.getMap();
843 RegsObj = MsgPackDoc.getMapNode();
844 for (auto I : OrigRegs) {
845 auto Key = I.first;
846 if (const char *RegName = getRegisterName(Key.getUInt())) {
847 std::string KeyName = Key.toString();
848 KeyName += " (";
849 KeyName += RegName;
850 KeyName += ')';
851 Key = MsgPackDoc.getNode(KeyName, /*Copy=*/true);
852 }
853 RegsObj.getMap()[Key] = I.second;
854 }
855
856 // Output as YAML.
857 Stream << '\t' << AMDGPU::PALMD::AssemblerDirectiveBegin << '\n';
858 MsgPackDoc.toYAML(Stream);
859 Stream << '\t' << AMDGPU::PALMD::AssemblerDirectiveEnd << '\n';
860
861 // Restore original registers map.
862 RegsObj = OrigRegs;
863}
864
865// Convert the accumulated PAL metadata into a binary blob for writing as
866// a .note record of the specified AMD type. Returns an empty blob if
867// there is no PAL metadata,
868void AMDGPUPALMetadata::toBlob(unsigned Type, std::string &Blob) {
869 ResolvedAll = DelayedExprs.resolveDelayedExpressions();
871 toLegacyBlob(Blob);
872 else if (Type)
873 toMsgPackBlob(Blob);
874}
875
876void AMDGPUPALMetadata::toLegacyBlob(std::string &Blob) {
877 Blob.clear();
878 auto Registers = getRegisters();
879 if (Registers.getMap().empty())
880 return;
881 raw_string_ostream OS(Blob);
883 for (auto I : Registers.getMap()) {
884 EW.write(uint32_t(I.first.getUInt()));
885 EW.write(uint32_t(I.second.getUInt()));
886 }
887}
888
889void AMDGPUPALMetadata::toMsgPackBlob(std::string &Blob) {
890 Blob.clear();
891 MsgPackDoc.writeToBlob(Blob);
892}
893
894// Set PAL metadata from YAML text. Returns false if failed.
896 BlobType = ELF::NT_AMDGPU_METADATA;
897 if (!MsgPackDoc.fromYAML(S))
898 return false;
899
900 // In the registers map, some keys may be of the form "0xa191
901 // (SPI_PS_INPUT_CNTL_0)", in which case the YAML input code made it a
902 // string. We need to turn it into a number.
903 auto &RegsObj = refRegisters();
904 auto OrigRegs = RegsObj;
905 RegsObj = MsgPackDoc.getMapNode();
906 Registers = RegsObj.getMap();
907 bool Ok = true;
908 for (auto I : OrigRegs.getMap()) {
909 auto Key = I.first;
910 if (Key.getKind() == msgpack::Type::String) {
911 StringRef S = Key.getString();
912 uint64_t Val;
913 if (S.consumeInteger(0, Val)) {
914 Ok = false;
915 errs() << "Unrecognized PAL metadata register key '" << S << "'\n";
916 continue;
917 }
918 Key = MsgPackDoc.getNode(Val);
919 }
920 Registers.getMap()[Key] = I.second;
921 }
922 return Ok;
923}
924
925// Reference (create if necessary) the node for the registers map.
926msgpack::DocNode &AMDGPUPALMetadata::refRegisters() {
927 auto &N =
928 MsgPackDoc.getRoot()
929 .getMap(/*Convert=*/true)[MsgPackDoc.getNode("amdpal.pipelines")]
930 .getArray(/*Convert=*/true)[0]
931 .getMap(/*Convert=*/true)[MsgPackDoc.getNode(".registers")];
932 N.getMap(/*Convert=*/true);
933 return N;
934}
935
936// Get (create if necessary) the registers map.
937msgpack::MapDocNode AMDGPUPALMetadata::getRegisters() {
938 if (Registers.isEmpty())
939 Registers = refRegisters();
940 return Registers.getMap();
941}
942
943// Reference (create if necessary) the node for the shader functions map.
944msgpack::DocNode &AMDGPUPALMetadata::refShaderFunctions() {
945 auto &N =
946 MsgPackDoc.getRoot()
947 .getMap(/*Convert=*/true)[MsgPackDoc.getNode("amdpal.pipelines")]
948 .getArray(/*Convert=*/true)[0]
949 .getMap(/*Convert=*/true)[MsgPackDoc.getNode(".shader_functions")];
950 N.getMap(/*Convert=*/true);
951 return N;
952}
953
954// Get (create if necessary) the shader functions map.
955msgpack::MapDocNode AMDGPUPALMetadata::getShaderFunctions() {
956 if (ShaderFunctions.isEmpty())
957 ShaderFunctions = refShaderFunctions();
958 return ShaderFunctions.getMap();
959}
960
961// Get (create if necessary) a function in the shader functions map.
962msgpack::MapDocNode AMDGPUPALMetadata::getShaderFunction(StringRef Name) {
963 auto Functions = getShaderFunctions();
964 return Functions[Name].getMap(/*Convert=*/true);
965}
966
967msgpack::DocNode &AMDGPUPALMetadata::refComputeRegisters() {
968 auto &N =
969 MsgPackDoc.getRoot()
970 .getMap(/*Convert=*/true)[MsgPackDoc.getNode("amdpal.pipelines")]
971 .getArray(/*Convert=*/true)[0]
972 .getMap(/*Convert=*/true)[MsgPackDoc.getNode(".compute_registers")];
973 N.getMap(/*Convert=*/true);
974 return N;
975}
976
977msgpack::MapDocNode AMDGPUPALMetadata::getComputeRegisters() {
978 if (ComputeRegisters.isEmpty())
979 ComputeRegisters = refComputeRegisters();
980 return ComputeRegisters.getMap();
981}
982
983msgpack::DocNode &AMDGPUPALMetadata::refGraphicsRegisters() {
984 auto &N =
985 MsgPackDoc.getRoot()
986 .getMap(/*Convert=*/true)[MsgPackDoc.getNode("amdpal.pipelines")]
987 .getArray(/*Convert=*/true)[0]
988 .getMap(/*Convert=*/true)[MsgPackDoc.getNode(".graphics_registers")];
989 N.getMap(/*Convert=*/true);
990 return N;
991}
992
993msgpack::MapDocNode AMDGPUPALMetadata::getGraphicsRegisters() {
994 if (GraphicsRegisters.isEmpty())
995 GraphicsRegisters = refGraphicsRegisters();
996 return GraphicsRegisters.getMap();
997}
998
999msgpack::DocNode &AMDGPUPALMetadata::refHwStage() {
1000 auto &N =
1001 MsgPackDoc.getRoot()
1002 .getMap(/*Convert=*/true)[MsgPackDoc.getNode("amdpal.pipelines")]
1003 .getArray(/*Convert=*/true)[0]
1004 .getMap(/*Convert=*/true)[MsgPackDoc.getNode(".hardware_stages")];
1005 N.getMap(/*Convert=*/true);
1006 return N;
1007}
1008
1009// Get (create if necessary) the .hardware_stages entry for the given calling
1010// convention.
1011msgpack::MapDocNode AMDGPUPALMetadata::getHwStage(unsigned CC) {
1012 if (HwStages.isEmpty())
1013 HwStages = refHwStage();
1014 return HwStages.getMap()[getStageName(CC)].getMap(/*Convert=*/true);
1015}
1016
1017// Get .note record vendor name of metadata blob to be emitted.
1018const char *AMDGPUPALMetadata::getVendor() const {
1019 return isLegacy() ? ElfNote::NoteNameV2 : ElfNote::NoteNameV3;
1020}
1021
1022// Get .note record type of metadata blob to be emitted:
1023// ELF::NT_AMD_PAL_METADATA (legacy key=val format), or
1024// ELF::NT_AMDGPU_METADATA (MsgPack format), or
1025// 0 (no PAL metadata).
1027 return BlobType;
1028}
1029
1030// Return whether the blob type is legacy PAL metadata.
1031bool AMDGPUPALMetadata::isLegacy() const {
1032 return BlobType == ELF::NT_AMD_PAL_METADATA;
1033}
1034
1035// Set legacy PAL metadata format.
1039
1040// Erase all PAL metadata.
1042 MsgPackDoc.clear();
1043 REM.clear();
1044 DelayedExprs.clear();
1045 Registers = MsgPackDoc.getEmptyNode();
1046 HwStages = MsgPackDoc.getEmptyNode();
1047 ShaderFunctions = MsgPackDoc.getEmptyNode();
1048}
1049
1051 return ResolvedAll && DelayedExprs.empty();
1052}
1053
1054unsigned AMDGPUPALMetadata::getPALVersion(unsigned idx) {
1055 assert(idx < 2 &&
1056 "illegal index to PAL version - should be 0 (major) or 1 (minor)");
1057 if (!VersionChecked) {
1058 if (Version.isEmpty()) {
1059 auto &M = MsgPackDoc.getRoot().getMap(/*Convert=*/true);
1060 auto I = M.find(MsgPackDoc.getNode("amdpal.version"));
1061 if (I != M.end())
1062 Version = I->second;
1063 }
1064 VersionChecked = true;
1065 }
1066 if (Version.isEmpty())
1067 // Default to 2.6 if there's no version info
1068 return idx ? 6 : 2;
1069 return Version.getArray()[idx].getUInt();
1070}
1071
1073
1075
1079
1080// Set the field in a given .hardware_stages entry to a maximum value
1082 unsigned Val) {
1083 msgpack::MapDocNode HwStageFieldMapNode = getHwStage(CC);
1084 auto &Node = HwStageFieldMapNode[field];
1085 if (Node.isEmpty())
1086 Node = Val;
1087 else
1088 Node = std::max<unsigned>(Node.getUInt(), Val);
1089}
1090
1091// Set the field in a given .hardware_stages entry
1092void AMDGPUPALMetadata::setHwStage(unsigned CC, StringRef field, unsigned Val) {
1093 getHwStage(CC)[field] = Val;
1094}
1095
1096void AMDGPUPALMetadata::setHwStage(unsigned CC, StringRef field, bool Val) {
1097 getHwStage(CC)[field] = Val;
1098}
1099
1101 msgpack::Type Type, const MCExpr *Val) {
1102 DelayedExprs.assignDocNode(getHwStage(CC)[field], Type, Val);
1103}
1104
1106 getComputeRegisters()[field] = Val;
1107}
1108
1110 getComputeRegisters()[field] = Val;
1111}
1112
1114 auto M = getComputeRegisters();
1115 auto I = M.find(field);
1116 return I == M.end() ? nullptr : &I->second;
1117}
1118
1120 if (auto *N = refComputeRegister(field))
1121 return N->getUInt() == Val;
1122 return false;
1123}
1124
1126 if (auto *N = refComputeRegister(field))
1127 return N->getBool() == Val;
1128 return false;
1129}
1130
1132 getGraphicsRegisters()[field] = Val;
1133}
1134
1136 getGraphicsRegisters()[field] = Val;
1137}
1138
1140 unsigned Val) {
1141 getGraphicsRegisters()[field1].getMap(true)[field2] = Val;
1142}
1143
1145 bool Val) {
1146 getGraphicsRegisters()[field1].getMap(true)[field2] = Val;
1147}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU metadata definitions and in-memory representations.
static unsigned getScratchSizeKey(CallingConv::ID CC)
static unsigned getRsrc1Reg(CallingConv::ID CC)
static const char * getStageName(CallingConv::ID CC)
PAL metadata handling.
Enums and constants for AMDGPU PT_NOTE sections.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Module.h This file contains the declarations for the Module class.
#define RegName(no)
#define I(x, y, z)
Definition MD5.cpp:58
static std::string getRegisterName(const TargetRegisterInfo *TRI, Register Reg)
#define S_0286D8_PS_W32_EN(x)
Definition SIDefines.h:1277
#define S_00B800_CS_W32_EN(x)
Definition SIDefines.h:1279
#define S_028B54_GS_W32_EN(x)
Definition SIDefines.h:1274
#define S_028B54_VS_W32_EN(x)
Definition SIDefines.h:1275
#define S_028B54_HS_W32_EN(x)
Definition SIDefines.h:1273
SI Pre allocate WWM Registers
Defines the llvm::VersionTuple class, which represents a version in the form major[....
void setSpiPsInputAddr(unsigned Val)
void setEntryPoint(unsigned CC, StringRef Name)
const char * getVendor() const
void setFunctionScratchSize(StringRef FnName, unsigned Val)
bool setFromString(StringRef S)
void setNumUsedVgprs(unsigned CC, unsigned Val)
unsigned getRegister(unsigned Reg)
msgpack::DocNode * refComputeRegister(StringRef field)
void setFunctionNumUsedVgprs(StringRef FnName, unsigned Val)
bool setFromBlob(unsigned Type, StringRef Blob)
void setFunctionNumUsedSgprs(StringRef FnName, unsigned Val)
void setScratchSize(unsigned CC, unsigned Val)
void setRegister(unsigned Reg, unsigned Val)
void setHwStage(unsigned CC, StringRef field, unsigned Val)
void setRsrc1(unsigned CC, unsigned Val)
void setSpiPsInputEna(unsigned Val)
void setNumUsedAgprs(unsigned CC, unsigned Val)
void setGraphicsRegisters(StringRef field, unsigned Val)
bool checkComputeRegisters(StringRef field, unsigned Val)
void toBlob(unsigned Type, std::string &S)
void toString(std::string &S)
void setFunctionLdsSize(StringRef FnName, unsigned Val)
void updateHwStageMaximum(unsigned CC, StringRef field, unsigned Val)
void setRsrc2(unsigned CC, unsigned Val)
void setNumUsedSgprs(unsigned CC, unsigned Val)
void setComputeRegisters(StringRef field, unsigned Val)
static const MCBinaryExpr * createOr(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition MCExpr.h:408
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition MCExpr.cpp:212
Context object for machine code objects.
Definition MCContext.h:83
Base class for the full range of assembler expressions which are needed for parsing.
Definition MCExpr.h:34
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
bool consumeInteger(unsigned Radix, T &Result)
Parse the current string as an integer of the specified radix.
Definition StringRef.h:501
constexpr size_t size() const
size - Get the string size.
Definition StringRef.h:146
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition StringRef.h:140
static Twine utohexstr(uint64_t Val)
Definition Twine.h:385
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:45
Represents a version number in the form major[.minor[.subminor[.build]]].
A node in a MsgPack Document.
MapDocNode & getMap(bool Convert=false)
Get a MapDocNode for a map node.
ArrayDocNode & getArray(bool Convert=false)
Get an ArrayDocNode for an array node.
DocNode & getRoot()
Get ref to the document's root element.
DocNode getNode()
Create a nil node associated with this Document.
LLVM_ABI bool readFromBlob(StringRef Blob, bool Multi, function_ref< int(DocNode *DestNode, DocNode SrcNode, DocNode MapKey)> Merger=[](DocNode *DestNode, DocNode SrcNode, DocNode MapKey) { return -1;})
Read a document from a binary msgpack blob, merging into anything already in the Document.
A DocNode that is a map.
A raw_ostream that writes to an std::string.
A raw_ostream that writes to an SmallVector or SmallString.
StringRef str() const
Return a StringRef for the vector contents.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const char NoteNameV2[]
const char NoteNameV3[]
constexpr char AssemblerDirective[]
PAL metadata (old linear format) assembler directive.
constexpr char AssemblerDirectiveBegin[]
PAL metadata (new MsgPack format) beginning assembler directive.
constexpr char AssemblerDirectiveEnd[]
PAL metadata (new MsgPack format) ending assembler directive.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ AMDGPU_CS
Used for Mesa/AMDPAL compute shaders.
@ AMDGPU_VS
Used for Mesa vertex shaders, or AMDPAL last shader stage before rasterization (vertex shader if tess...
@ AMDGPU_Gfx
Used for AMD graphics targets.
@ AMDGPU_HS
Used for Mesa/AMDPAL hull shaders (= tessellation control shaders).
@ AMDGPU_GS
Used for Mesa/AMDPAL geometry shaders.
@ AMDGPU_PS
Used for Mesa/AMDPAL pixel shaders.
@ AMDGPU_ES
Used for AMDPAL shader stage before geometry shader if geometry is in use.
@ AMDGPU_LS
Used for AMDPAL vertex shader if tessellation is in use.
@ NT_AMD_PAL_METADATA
Definition ELF.h:1974
@ NT_AMDGPU_METADATA
Definition ELF.h:1980
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > dyn_extract(Y &&MD)
Extract a Value from Metadata, if any.
Definition Metadata.h:694
Type
MessagePack types as defined in the standard, with the exception of Integer being divided into a sign...
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:649
FunctionAddr VTableAddr uintptr_t uintptr_t Version
Definition InstrProf.h:302
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
Definition InstrProf.h:189
#define N
Adapter to write values to a stream in a particular byte order.