LLVM 24.0.0git
AMDGPUMIRFormatter.cpp
Go to the documentation of this file.
1//===- AMDGPUMIRFormatter.cpp ---------------------------------------------===//
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/// Implementation of AMDGPU overrides of MIRFormatter.
11//
12//===----------------------------------------------------------------------===//
13
14#include "AMDGPUMIRFormatter.h"
17#include "llvm/Support/Format.h"
19
20using namespace llvm;
21
22const char SWaitAluImmPrefix = '.';
24
32
34
38
41
42const char AsyncStageImmPrefix = '.';
45constexpr StringLiteral AllStages("AllStages");
46
47void AMDGPUMIRFormatter::printSWaitAluImm(uint64_t Imm, raw_ostream &OS) const {
48 bool NonePrinted = true;
50 auto PrintFieldIfNotMax = [&](StringRef Descr, uint64_t Num, unsigned Max) {
51 if (Num != Max) {
52 OS << Delim << Descr << SWaitAluDelim << Num;
53 NonePrinted = false;
54 }
55 };
63 PrintFieldIfNotMax(
66 AMDGPU::getIsaVersion(STI.getCPU())),
74 if (NonePrinted)
75 OS << AllOff;
76}
77
78void AMDGPUMIRFormatter::printSWaitcntImm(uint64_t Imm, raw_ostream &OS) const {
79 const AMDGPU::IsaVersion &Version = AMDGPU::getIsaVersion(STI.getCPU());
80 bool NonePrinted = true;
81 ListSeparator Delim(SWaitAluDelim);
82 auto PrintFieldIfNotMax = [&](StringRef Descr, uint64_t Num, unsigned Max) {
83 if (Num != Max) {
84 OS << Delim << Descr << SWaitAluDelim << Num;
85 NonePrinted = false;
86 }
87 };
89 PrintFieldIfNotMax(VmcntName, AMDGPU::decodeVmcnt(Version, Imm),
91 PrintFieldIfNotMax(ExpcntName, AMDGPU::decodeExpcnt(Version, Imm),
93 PrintFieldIfNotMax(LgkmcntName, AMDGPU::decodeLgkmcnt(Version, Imm),
95 if (NonePrinted)
96 OS << AllOff;
97}
98
99void AMDGPUMIRFormatter::printSWaitLoadcntDscntImm(uint64_t Imm,
100 raw_ostream &OS) const {
101 const AMDGPU::IsaVersion &Version = AMDGPU::getIsaVersion(STI.getCPU());
102 bool NonePrinted = true;
103 ListSeparator Delim(SWaitAluDelim);
104 auto PrintFieldIfNotMax = [&](StringRef Descr, uint64_t Num, unsigned Max) {
105 if (Num != Max) {
106 OS << Delim << Descr << SWaitAluDelim << Num;
107 NonePrinted = false;
108 }
109 };
110 OS << SWaitAluImmPrefix;
111 PrintFieldIfNotMax(LoadcntName, AMDGPU::decodeLoadcnt(Version, Imm),
113 PrintFieldIfNotMax(DscntName, AMDGPU::decodeDscnt(Version, Imm),
115 if (NonePrinted)
116 OS << AllOff;
117}
118
119void AMDGPUMIRFormatter::printAsyncStageMaskImm(int64_t Imm,
120 raw_ostream &OS) const {
122 OS << Imm;
123 return;
124 }
125
127 auto Mask = static_cast<AMDGPU::AsyncStages>(Imm);
128 // The zero mask names every stage. Spell that out rather than printing an
129 // empty list. The saturated mask means the same thing but is a different
130 // immediate, so it keeps its spelled-out list to stay round-trippable.
131 if (Mask == AMDGPU::AsyncStages::NONE) {
132 OS << AllStages;
133 return;
134 }
135
136 // Reserved stages have no meaningful name, collect them into a single
137 // hex bitmask instead.
138 ListSeparator Delim(AsyncStageDelim);
139 for (AMDGPU::AsyncStages S :
141 OS << Delim << AMDGPU::getAsyncStageName(S);
143 if (any(Reserved))
144 OS << Delim << ReservedStagePrefix
146}
147
149 std::optional<unsigned int> OpIdx, int64_t Imm) const {
150
151 switch (MI.getOpcode()) {
152 case AMDGPU::ASYNCMARK:
153 case AMDGPU::WAIT_ASYNCMARK:
154 if (OpIdx == MI.getNumExplicitOperands() - 1u)
155 printAsyncStageMaskImm(Imm, OS);
156 else
157 MIRFormatter::printImm(OS, MI, OpIdx, Imm);
158 break;
159 case AMDGPU::S_WAITCNT:
160 case AMDGPU::S_WAITCNT_soft:
161 printSWaitcntImm(Imm, OS);
162 break;
163 case AMDGPU::S_WAIT_LOADCNT_DSCNT:
164 printSWaitLoadcntDscntImm(Imm, OS);
165 break;
166 case AMDGPU::S_WAITCNT_DEPCTR:
167 printSWaitAluImm(Imm, OS);
168 break;
169 case AMDGPU::S_DELAY_ALU:
170 assert(OpIdx == 0);
171 printSDelayAluImm(Imm, OS);
172 break;
173 default:
174 MIRFormatter::printImm(OS, MI, OpIdx, Imm);
175 break;
176 }
177}
178
179/// Implement target specific parsing of immediate mnemonics. The mnemonic is
180/// a string with a leading dot.
181bool AMDGPUMIRFormatter::parseImmMnemonic(const unsigned OpCode,
182 const unsigned OpIdx,
183 StringRef Src, int64_t &Imm,
184 ErrorCallbackType ErrorCallback) const
185{
186
187 switch (OpCode) {
188 case AMDGPU::S_WAITCNT:
189 case AMDGPU::S_WAITCNT_soft:
190 return parseSWaitcntImmMnemonic(OpIdx, Imm, Src, ErrorCallback);
191 case AMDGPU::S_WAIT_LOADCNT_DSCNT:
192 return parseSWaitLoadcntDscntImmMnemonic(OpIdx, Imm, Src, ErrorCallback);
193 case AMDGPU::S_WAITCNT_DEPCTR:
194 return parseSWaitAluImmMnemonic(OpIdx, Imm, Src, ErrorCallback);
195 case AMDGPU::S_DELAY_ALU:
196 return parseSDelayAluImmMnemonic(OpIdx, Imm, Src, ErrorCallback);
197 case AMDGPU::ASYNCMARK:
198 if (OpIdx == 0)
199 return parseAsyncStageMaskImmMnemonic(OpIdx, Imm, Src, ErrorCallback);
200 break;
201 case AMDGPU::WAIT_ASYNCMARK:
202 if (OpIdx == 1)
203 return parseAsyncStageMaskImmMnemonic(OpIdx, Imm, Src, ErrorCallback);
204 break;
205 default:
206 break;
207 }
208 return true; // Don't know what this is
209}
210
211void AMDGPUMIRFormatter::printSDelayAluImm(int64_t Imm,
212 llvm::raw_ostream &OS) const {
213 // Construct an immediate string to represent the information encoded in the
214 // s_delay_alu immediate.
215 // .id0_<dep>[_skip_<count>_id1<dep>]
216 constexpr int64_t None = 0;
217 constexpr int64_t Same = 0;
218
219 uint64_t Id0 = (Imm & 0xF);
220 uint64_t Skip = ((Imm >> 4) & 0x7);
221 uint64_t Id1 = ((Imm >> 7) & 0xF);
222 auto Outdep = [&](uint64_t Id) {
223 if (Id == None)
224 OS << "NONE";
225 else if (Id < 5)
226 OS << "VALU_DEP_" << Id;
227 else if (Id < 8)
228 OS << "TRANS32_DEP_" << Id - 4;
229 else
230 OS << "SALU_CYCLE_" << Id - 8;
231 };
232
233 OS << ".id0_";
234 Outdep(Id0);
235
236 // If the second inst is "same" and "none", no need to print the rest of the
237 // string.
238 if (Skip == Same && Id1 == None)
239 return;
240
241 // Encode the second delay specification.
242 OS << "_skip_";
243 if (Skip == 0)
244 OS << "SAME";
245 else if (Skip == 1)
246 OS << "NEXT";
247 else
248 OS << "SKIP_" << Skip - 1;
249
250 OS << "_id1_";
251 Outdep(Id1);
252}
253
254bool AMDGPUMIRFormatter::parseSWaitcntImmMnemonic(
255 const unsigned int OpIdx, int64_t &Imm, StringRef &Src,
256 MIRFormatter::ErrorCallbackType &ErrorCallback) const {
257 const AMDGPU::IsaVersion &Version = AMDGPU::getIsaVersion(STI.getCPU());
258
259 // Accept integer masks for compatibility with old MIR.
260 if (!Src.consumeInteger(10, Imm))
261 return false;
262
263 // Initialize with all counters at max (no wait).
264 unsigned Vmcnt = AMDGPU::getVmcntBitMask(Version);
265 unsigned Expcnt = AMDGPU::getExpcntBitMask(Version);
266 unsigned Lgkmcnt = AMDGPU::getLgkmcntBitMask(Version);
267
268 // The input is in the form: .Name1_Num1_Name2_Num2
269 // Drop the '.' prefix.
270 if (!Src.consume_front(SWaitAluImmPrefix))
271 return ErrorCallback(Src.begin(), "expected prefix");
272 if (Src.empty())
273 return ErrorCallback(Src.begin(), "expected <CounterName>_<CounterNum>");
274
275 // Special case for all off (all counters at max).
276 if (Src == AllOff) {
277 Imm = AMDGPU::encodeWaitcnt(Version, Vmcnt, Expcnt, Lgkmcnt);
278 return false;
279 }
280
281 // Parse counter name, number pairs.
282 while (!Src.empty()) {
283 size_t DelimIdx = Src.find(SWaitAluDelim);
284 if (DelimIdx == StringRef::npos)
285 return ErrorCallback(Src.begin(), "expected <CounterName>_<CounterNum>");
286 StringRef Name = Src.substr(0, DelimIdx);
287 StringRef::iterator NamePos = Src.begin();
288 Src.consume_front(Name);
289 Src.consume_front(SWaitAluDelim);
290
291 int64_t Num;
292 StringRef::iterator NumPos = Src.begin();
293 if (Src.consumeInteger(10, Num) || Num < 0)
294 return ErrorCallback(NumPos,
295 "expected non-negative integer counter number");
296
297 unsigned Max;
298 if (Name == VmcntName) {
300 Vmcnt = Num;
301 } else if (Name == ExpcntName) {
303 Expcnt = Num;
304 } else if (Name == LgkmcntName) {
306 Lgkmcnt = Num;
307 } else {
308 return ErrorCallback(NamePos, "invalid counter name");
309 }
310 if (Num >= Max)
311 return ErrorCallback(NumPos, "counter value too large");
312
313 Src.consume_front(SWaitAluDelim);
314 }
315
316 Imm = AMDGPU::encodeWaitcnt(Version, Vmcnt, Expcnt, Lgkmcnt);
317 return false;
318}
319
320bool AMDGPUMIRFormatter::parseSWaitLoadcntDscntImmMnemonic(
321 const unsigned int OpIdx, int64_t &Imm, StringRef &Src,
322 MIRFormatter::ErrorCallbackType &ErrorCallback) const {
323 const AMDGPU::IsaVersion &Version = AMDGPU::getIsaVersion(STI.getCPU());
324
325 // Accept integer masks for compatibility with old MIR.
326 if (!Src.consumeInteger(10, Imm))
327 return false;
328
329 // Initialize with all counters at max (no wait).
330 unsigned Loadcnt = AMDGPU::getLoadcntBitMask(Version);
331 unsigned Dscnt = AMDGPU::getDscntBitMask(Version);
332
333 // The input is in the form: .Name1_Num1_Name2_Num2
334 // Drop the '.' prefix.
335 if (!Src.consume_front(SWaitAluImmPrefix))
336 return ErrorCallback(Src.begin(), "expected prefix");
337 if (Src.empty())
338 return ErrorCallback(Src.begin(), "expected <CounterName>_<CounterNum>");
339
340 // Special case for all off (all counters at max).
341 if (Src == AllOff) {
342 Imm = AMDGPU::encodeLoadcntDscnt(Version, Loadcnt, Dscnt);
343 return false;
344 }
345
346 // Parse counter name, number pairs.
347 while (!Src.empty()) {
348 size_t DelimIdx = Src.find(SWaitAluDelim);
349 if (DelimIdx == StringRef::npos)
350 return ErrorCallback(Src.begin(), "expected <CounterName>_<CounterNum>");
351 StringRef Name = Src.substr(0, DelimIdx);
352 StringRef::iterator NamePos = Src.begin();
353 Src.consume_front(Name);
354 Src.consume_front(SWaitAluDelim);
355
356 int64_t Num;
357 StringRef::iterator NumPos = Src.begin();
358 if (Src.consumeInteger(10, Num) || Num < 0)
359 return ErrorCallback(NumPos,
360 "expected non-negative integer counter number");
361
362 unsigned Max;
363 if (Name == LoadcntName) {
365 Loadcnt = Num;
366 } else if (Name == DscntName) {
368 Dscnt = Num;
369 } else {
370 return ErrorCallback(NamePos, "invalid counter name");
371 }
372 if (Num >= Max)
373 return ErrorCallback(NumPos, "counter value too large");
374
375 Src.consume_front(SWaitAluDelim);
376 }
377
378 Imm = AMDGPU::encodeLoadcntDscnt(Version, Loadcnt, Dscnt);
379 return false;
380}
381
382bool AMDGPUMIRFormatter::parseSWaitAluImmMnemonic(
383 const unsigned int OpIdx, int64_t &Imm, StringRef &Src,
384 MIRFormatter::ErrorCallbackType &ErrorCallback) const {
385 // TODO: For now accept integer masks for compatibility with old MIR.
386 if (!Src.consumeInteger(10, Imm))
387 return false;
388
389 // Initialize with all checks off.
391 // The input is in the form: .Name1_Num1_Name2_Num2
392 // Drop the '.' prefix.
393 bool ConsumePrefix = Src.consume_front(SWaitAluImmPrefix);
394 if (!ConsumePrefix)
395 return ErrorCallback(Src.begin(), "expected prefix");
396 if (Src.empty())
397 return ErrorCallback(Src.begin(), "expected <CounterName>_<CounterNum>");
398
399 // Special case for all off.
400 if (Src == AllOff)
401 return false;
402
403 // Parse a counter name, number pair in each iteration.
404 while (!Src.empty()) {
405 // Src: Name1_Num1_Name2_Num2
406 // ^
407 size_t DelimIdx = Src.find(SWaitAluDelim);
408 if (DelimIdx == StringRef::npos)
409 return ErrorCallback(Src.begin(), "expected <CounterName>_<CounterNum>");
410 // Src: Name1_Num1_Name2_Num2
411 // ^^^^^
412 StringRef Name = Src.substr(0, DelimIdx);
413 // Save the position of the name for accurate error reporting.
414 StringRef::iterator NamePos = Src.begin();
415 [[maybe_unused]] bool ConsumeName = Src.consume_front(Name);
416 assert(ConsumeName && "Expected name");
417 [[maybe_unused]] bool ConsumeDelim = Src.consume_front(SWaitAluDelim);
418 assert(ConsumeDelim && "Expected delimiter");
419 // Src: Num1_Name2_Num2
420 // ^
421 DelimIdx = Src.find(SWaitAluDelim);
422 // Src: Num1_Name2_Num2
423 // ^^^^
424 int64_t Num;
425 // Save the position of the number for accurate error reporting.
426 StringRef::iterator NumPos = Src.begin();
427 if (Src.consumeInteger(10, Num) || Num < 0)
428 return ErrorCallback(NumPos,
429 "expected non-negative integer counter number");
430 unsigned Max;
431 if (Name == VaVdstName) {
434 } else if (Name == VmVsrcName) {
437 } else if (Name == VaSdstName) {
440 } else if (Name == VaSsrcName) {
443 } else if (Name == HoldCntName) {
444 const AMDGPU::IsaVersion &Version = AMDGPU::getIsaVersion(STI.getCPU());
447 } else if (Name == VaVccName) {
450 } else if (Name == SaSdstName) {
453 } else {
454 return ErrorCallback(NamePos, "invalid counter name");
455 }
456 // Don't allow the values to reach their maximum value.
457 if (Num >= Max)
458 return ErrorCallback(NumPos, "counter value too large");
459 // Src: Name2_Num2
460 Src.consume_front(SWaitAluDelim);
461 }
462 return false;
463}
464
465bool AMDGPUMIRFormatter::parseSDelayAluImmMnemonic(
466 const unsigned int OpIdx, int64_t &Imm, llvm::StringRef &Src,
467 llvm::MIRFormatter::ErrorCallbackType &ErrorCallback) const
468{
469 assert(OpIdx == 0);
470
471 Imm = 0;
472 bool Expected = Src.consume_front(".id0_");
473 if (!Expected)
474 return ErrorCallback(Src.begin(), "Expected .id0_");
475
476 auto ExpectInt = [&](StringRef &Src, int64_t Offset) -> int64_t {
477 int64_t Dep;
478 if (!Src.consumeInteger(10, Dep))
479 return Dep + Offset;
480
481 return -1;
482 };
483
484 auto DecodeDelay = [&](StringRef &Src) -> int64_t {
485 if (Src.consume_front("NONE"))
486 return 0;
487 if (Src.consume_front("VALU_DEP_"))
488 return ExpectInt(Src, 0);
489 if (Src.consume_front("TRANS32_DEP_"))
490 return ExpectInt(Src, 4);
491 if (Src.consume_front("SALU_CYCLE_"))
492 return ExpectInt(Src, 8);
493
494 return -1;
495 };
496
497 int64_t Delay0 = DecodeDelay(Src);
498 int64_t Skip = 0;
499 int64_t Delay1 = 0;
500 if (Delay0 == -1)
501 return ErrorCallback(Src.begin(), "Could not decode delay0");
502
503
504 // Set the Imm so far, to that early return has the correct value.
505 Imm = Delay0;
506
507 // If that was the end of the string, the second instruction is "same" and
508 // "none"
509 if (Src.begin() == Src.end())
510 return false;
511
512 Expected = Src.consume_front("_skip_");
513 if (!Expected)
514 return ErrorCallback(Src.begin(), "Expected _skip_");
515
516
517 if (Src.consume_front("SAME")) {
518 Skip = 0;
519 } else if (Src.consume_front("NEXT")) {
520 Skip = 1;
521 } else if (Src.consume_front("SKIP_")) {
522 if (Src.consumeInteger(10, Skip)) {
523 return ErrorCallback(Src.begin(), "Expected integer Skip value");
524 }
525 Skip += 1;
526 } else {
527 ErrorCallback(Src.begin(), "Unexpected Skip Value");
528 }
529
530 Expected = Src.consume_front("_id1_");
531 if (!Expected)
532 return ErrorCallback(Src.begin(), "Expected _id1_");
533
534 Delay1 = DecodeDelay(Src);
535 if (Delay1 == -1)
536 return ErrorCallback(Src.begin(), "Could not decode delay1");
537
538 Imm = Imm | (Skip << 4) | (Delay1 << 7);
539 return false;
540}
541
542// Parse the async stage mask of asyncmark/wait_asyncmark. The mnemonic names
543// the stages the mask names.
544bool AMDGPUMIRFormatter::parseAsyncStageMaskImmMnemonic(
545 const unsigned int OpIdx, int64_t &Imm, StringRef &Src,
546 MIRFormatter::ErrorCallbackType &ErrorCallback) const {
547 if (!Src.consumeInteger(10, Imm))
548 return false;
549
550 if (!Src.consume_front(AsyncStageImmPrefix))
551 return ErrorCallback(Src.begin(), "expected prefix");
552 if (Src.empty())
553 return ErrorCallback(Src.begin(), "expected <StageName>");
554
555 if (Src == AllStages) {
556 Imm = 0;
557 return false;
558 }
559
561 while (!Src.empty()) {
562 StringRef Name = Src.substr(0, Src.find(AsyncStageDelim));
563 StringRef::iterator NamePos = Src.begin();
564 Src.consume_front(Name);
565 Src.consume_front(AsyncStageDelim);
566
567 // The reserved stages arrive together as one hex bitmask.
568 StringRef Bits = Name;
569 if (Bits.consume_front(ReservedStagePrefix)) {
570 uint32_t Mask;
571 if (Bits.getAsInteger(16, Mask) || Bits.empty() || !Mask)
572 return ErrorCallback(NamePos, "invalid async stage mask");
574 return ErrorCallback(NamePos, "async stage mask out of range");
576 return ErrorCallback(NamePos,
577 "async stage mask names a non-reserved stage");
578 StageMask |= static_cast<AMDGPU::AsyncStages>(Mask);
579 continue;
580 }
581
582 const StringLiteral *It = find(AMDGPU::AsyncStageNames, Name);
583 if (It == std::end(AMDGPU::AsyncStageNames))
584 return ErrorCallback(NamePos, "invalid async stage name");
585 StageMask |= static_cast<AMDGPU::AsyncStages>(
586 1u << (It - std::begin(AMDGPU::AsyncStageNames)));
587 }
588
589 Imm = to_underlying(StageMask);
590 return false;
591}
592
595 const PseudoSourceValue *&PSV, ErrorCallbackType ErrorCallback) const {
597 const AMDGPUTargetMachine &TM =
598 static_cast<const AMDGPUTargetMachine &>(MF.getTarget());
599 if (Src == "GWSResource") {
600 PSV = MFI->getGWSPSV(TM);
601 return false;
602 }
603 llvm_unreachable("unknown MIR custom pseudo source value");
604}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Shared AMDGPU asyncmark stage definitions.
uint64_t uint64_t
uint64_t Imm
StringLiteral VmVsrcName
StringLiteral HoldCntName
StringLiteral ExpcntName
StringLiteral AllOff
StringLiteral VaVccName
StringLiteral SWaitAluDelim
const char SWaitAluImmPrefix
constexpr StringLiteral ReservedStagePrefix("RES")
StringLiteral LoadcntName
const char AsyncStageImmPrefix
StringLiteral VaSsrcName
StringLiteral LgkmcntName
StringLiteral VaSdstName
StringLiteral SaSdstName
constexpr StringLiteral AllStages("AllStages")
StringLiteral VmcntName
StringLiteral DscntName
constexpr StringLiteral AsyncStageDelim(".")
StringLiteral VaVdstName
AMDGPU specific overrides of MIRFormatter.
IRTranslator LLVM IR MI
bool parseCustomPseudoSourceValue(StringRef Src, MachineFunction &MF, PerFunctionMIParsingState &PFS, const PseudoSourceValue *&PSV, ErrorCallbackType ErrorCallback) const override
Implement target specific parsing of target custom pseudo source value.
void printImm(raw_ostream &OS, const MachineInstr &MI, std::optional< unsigned > OpIdx, int64_t Imm) const override
Implement target specific printing for machine operand immediate value, so that we can have more mean...
bool parseImmMnemonic(const unsigned OpCode, const unsigned OpIdx, StringRef Src, int64_t &Imm, ErrorCallbackType ErrorCallback) const override
Implement target specific parsing of immediate mnemonics.
A helper class to return the specified delimiter string after the first invocation of operator String...
function_ref< bool(StringRef::iterator Loc, const Twine &)> ErrorCallbackType
virtual void printImm(raw_ostream &OS, const MachineInstr &MI, std::optional< unsigned > OpIdx, int64_t Imm) const
Implement target specific printing for machine operand immediate value, so that we can have more mean...
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Representation of each machine instruction.
Special value supplied for machine level alias analysis.
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
const AMDGPUGWSResourcePseudoSourceValue * getGWSPSV(const AMDGPUTargetMachine &TM)
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
Definition StringRef.h:888
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
static constexpr size_t npos
Definition StringRef.h:58
const char * iterator
Definition StringRef.h:60
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned decodeFieldVaVcc(unsigned Encoded)
unsigned encodeFieldVaVcc(unsigned Encoded, unsigned VaVcc)
unsigned decodeFieldHoldCnt(unsigned Encoded, const IsaVersion &Version)
unsigned encodeFieldHoldCnt(unsigned Encoded, unsigned HoldCnt, const IsaVersion &Version)
unsigned encodeFieldVaSsrc(unsigned Encoded, unsigned VaSsrc)
unsigned encodeFieldVaVdst(unsigned Encoded, unsigned VaVdst)
unsigned decodeFieldSaSdst(unsigned Encoded)
unsigned getHoldCntBitMask(const IsaVersion &Version)
unsigned decodeFieldVaSdst(unsigned Encoded)
unsigned encodeFieldVmVsrc(unsigned Encoded, unsigned VmVsrc)
unsigned decodeFieldVaSsrc(unsigned Encoded)
unsigned encodeFieldSaSdst(unsigned Encoded, unsigned SaSdst)
unsigned decodeFieldVaVdst(unsigned Encoded)
int getDefaultDepCtrEncoding(const MCSubtargetInfo &STI)
unsigned decodeFieldVmVsrc(unsigned Encoded)
unsigned encodeFieldVaSdst(unsigned Encoded, unsigned VaSdst)
StringRef getAsyncStageName(AsyncStages Stage)
unsigned encodeLoadcntDscnt(const IsaVersion &Version, const Waitcnt &Decoded)
constexpr bool isValidAsyncStageMask(int64_t Mask)
AsyncStages
Bit mask of the async stages tracked by the asyncmark / wait_asyncmark intrinsics.
LLVM_ABI IsaVersion getIsaVersion(StringRef GPU)
constexpr StringLiteral AsyncStageNames[NumAsyncStages]
The name of each stage, indexed by the position of its bit.
unsigned encodeWaitcnt(const IsaVersion &Version, const Waitcnt &Decoded)
unsigned decodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt)
unsigned getVmcntBitMask(const IsaVersion &Version)
unsigned getLgkmcntBitMask(const IsaVersion &Version)
auto asyncStages(AsyncStages Mask)
unsigned decodeDscnt(const IsaVersion &Version, unsigned Waitcnt)
unsigned getExpcntBitMask(const IsaVersion &Version)
unsigned decodeExpcnt(const IsaVersion &Version, unsigned Waitcnt)
unsigned decodeVmcnt(const IsaVersion &Version, unsigned Waitcnt)
unsigned getLoadcntBitMask(const IsaVersion &Version)
unsigned decodeLoadcnt(const IsaVersion &Version, unsigned Waitcnt)
unsigned getDscntBitMask(const IsaVersion &Version)
constexpr bool any(E Val)
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1781
constexpr std::underlying_type_t< Enum > to_underlying(Enum E)
Returns underlying integer value of an enum.
FormattedNumber format_hex_no_prefix(uint64_t N, unsigned Width, bool Upper=false)
format_hex_no_prefix - Output N as a fixed width hexadecimal.
Definition Format.h:177