LLVM 19.0.0git
SIMachineFunctionInfo.h
Go to the documentation of this file.
1//==- SIMachineFunctionInfo.h - SIMachineFunctionInfo interface --*- C++ -*-==//
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//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_LIB_TARGET_AMDGPU_SIMACHINEFUNCTIONINFO_H
14#define LLVM_LIB_TARGET_AMDGPU_SIMACHINEFUNCTIONINFO_H
15
18#include "AMDGPUTargetMachine.h"
19#include "GCNSubtarget.h"
21#include "SIInstrInfo.h"
23#include "llvm/ADT/SetVector.h"
28#include <optional>
29
30namespace llvm {
31
32class MachineFrameInfo;
33class MachineFunction;
34class SIMachineFunctionInfo;
35class SIRegisterInfo;
36class TargetRegisterClass;
37
39public:
40 enum AMDGPUPSVKind : unsigned {
43 };
44
45protected:
47 : PseudoSourceValue(Kind, TM) {}
48
49public:
50 bool isConstant(const MachineFrameInfo *) const override {
51 // This should probably be true for most images, but we will start by being
52 // conservative.
53 return false;
54 }
55
56 bool isAliased(const MachineFrameInfo *) const override {
57 return true;
58 }
59
60 bool mayAlias(const MachineFrameInfo *) const override {
61 return true;
62 }
63};
64
66public:
69
70 static bool classof(const PseudoSourceValue *V) {
71 return V->kind() == GWSResource;
72 }
73
74 // These are inaccessible memory from IR.
75 bool isAliased(const MachineFrameInfo *) const override {
76 return false;
77 }
78
79 // These are inaccessible memory from IR.
80 bool mayAlias(const MachineFrameInfo *) const override {
81 return false;
82 }
83
84 void printCustom(raw_ostream &OS) const override {
85 OS << "GWSResource";
86 }
87};
88
89namespace yaml {
90
91struct SIArgument {
93 union {
95 unsigned StackOffset;
96 };
97 std::optional<unsigned> Mask;
98
99 // Default constructor, which creates a stack argument.
102 IsRegister = Other.IsRegister;
103 if (IsRegister) {
104 ::new ((void *)std::addressof(RegisterName))
105 StringValue(Other.RegisterName);
106 } else
107 StackOffset = Other.StackOffset;
108 Mask = Other.Mask;
109 }
111 IsRegister = Other.IsRegister;
112 if (IsRegister) {
113 ::new ((void *)std::addressof(RegisterName))
114 StringValue(Other.RegisterName);
115 } else
116 StackOffset = Other.StackOffset;
117 Mask = Other.Mask;
118 return *this;
119 }
121 if (IsRegister)
122 RegisterName.~StringValue();
123 }
124
125 // Helper to create a register or stack argument.
126 static inline SIArgument createArgument(bool IsReg) {
127 if (IsReg)
128 return SIArgument(IsReg);
129 return SIArgument();
130 }
131
132private:
133 // Construct a register argument.
135};
136
137template <> struct MappingTraits<SIArgument> {
138 static void mapping(IO &YamlIO, SIArgument &A) {
139 if (YamlIO.outputting()) {
140 if (A.IsRegister)
141 YamlIO.mapRequired("reg", A.RegisterName);
142 else
143 YamlIO.mapRequired("offset", A.StackOffset);
144 } else {
145 auto Keys = YamlIO.keys();
146 if (is_contained(Keys, "reg")) {
148 YamlIO.mapRequired("reg", A.RegisterName);
149 } else if (is_contained(Keys, "offset"))
150 YamlIO.mapRequired("offset", A.StackOffset);
151 else
152 YamlIO.setError("missing required key 'reg' or 'offset'");
153 }
154 YamlIO.mapOptional("mask", A.Mask);
155 }
156 static const bool flow = true;
157};
158
160 std::optional<SIArgument> PrivateSegmentBuffer;
161 std::optional<SIArgument> DispatchPtr;
162 std::optional<SIArgument> QueuePtr;
163 std::optional<SIArgument> KernargSegmentPtr;
164 std::optional<SIArgument> DispatchID;
165 std::optional<SIArgument> FlatScratchInit;
166 std::optional<SIArgument> PrivateSegmentSize;
167
168 std::optional<SIArgument> WorkGroupIDX;
169 std::optional<SIArgument> WorkGroupIDY;
170 std::optional<SIArgument> WorkGroupIDZ;
171 std::optional<SIArgument> WorkGroupInfo;
172 std::optional<SIArgument> LDSKernelId;
173 std::optional<SIArgument> PrivateSegmentWaveByteOffset;
174
175 std::optional<SIArgument> ImplicitArgPtr;
176 std::optional<SIArgument> ImplicitBufferPtr;
177
178 std::optional<SIArgument> WorkItemIDX;
179 std::optional<SIArgument> WorkItemIDY;
180 std::optional<SIArgument> WorkItemIDZ;
181};
182
183template <> struct MappingTraits<SIArgumentInfo> {
184 static void mapping(IO &YamlIO, SIArgumentInfo &AI) {
185 YamlIO.mapOptional("privateSegmentBuffer", AI.PrivateSegmentBuffer);
186 YamlIO.mapOptional("dispatchPtr", AI.DispatchPtr);
187 YamlIO.mapOptional("queuePtr", AI.QueuePtr);
188 YamlIO.mapOptional("kernargSegmentPtr", AI.KernargSegmentPtr);
189 YamlIO.mapOptional("dispatchID", AI.DispatchID);
190 YamlIO.mapOptional("flatScratchInit", AI.FlatScratchInit);
191 YamlIO.mapOptional("privateSegmentSize", AI.PrivateSegmentSize);
192
193 YamlIO.mapOptional("workGroupIDX", AI.WorkGroupIDX);
194 YamlIO.mapOptional("workGroupIDY", AI.WorkGroupIDY);
195 YamlIO.mapOptional("workGroupIDZ", AI.WorkGroupIDZ);
196 YamlIO.mapOptional("workGroupInfo", AI.WorkGroupInfo);
197 YamlIO.mapOptional("LDSKernelId", AI.LDSKernelId);
198 YamlIO.mapOptional("privateSegmentWaveByteOffset",
200
201 YamlIO.mapOptional("implicitArgPtr", AI.ImplicitArgPtr);
202 YamlIO.mapOptional("implicitBufferPtr", AI.ImplicitBufferPtr);
203
204 YamlIO.mapOptional("workItemIDX", AI.WorkItemIDX);
205 YamlIO.mapOptional("workItemIDY", AI.WorkItemIDY);
206 YamlIO.mapOptional("workItemIDZ", AI.WorkItemIDZ);
207 }
208};
209
210// Default to default mode for default calling convention.
211struct SIMode {
212 bool IEEE = true;
213 bool DX10Clamp = true;
218
219 SIMode() = default;
220
222 IEEE = Mode.IEEE;
223 DX10Clamp = Mode.DX10Clamp;
224 FP32InputDenormals = Mode.FP32Denormals.Input != DenormalMode::PreserveSign;
226 Mode.FP32Denormals.Output != DenormalMode::PreserveSign;
228 Mode.FP64FP16Denormals.Input != DenormalMode::PreserveSign;
230 Mode.FP64FP16Denormals.Output != DenormalMode::PreserveSign;
231 }
232
233 bool operator ==(const SIMode Other) const {
234 return IEEE == Other.IEEE &&
235 DX10Clamp == Other.DX10Clamp &&
236 FP32InputDenormals == Other.FP32InputDenormals &&
237 FP32OutputDenormals == Other.FP32OutputDenormals &&
238 FP64FP16InputDenormals == Other.FP64FP16InputDenormals &&
239 FP64FP16OutputDenormals == Other.FP64FP16OutputDenormals;
240 }
241};
242
243template <> struct MappingTraits<SIMode> {
244 static void mapping(IO &YamlIO, SIMode &Mode) {
245 YamlIO.mapOptional("ieee", Mode.IEEE, true);
246 YamlIO.mapOptional("dx10-clamp", Mode.DX10Clamp, true);
247 YamlIO.mapOptional("fp32-input-denormals", Mode.FP32InputDenormals, true);
248 YamlIO.mapOptional("fp32-output-denormals", Mode.FP32OutputDenormals, true);
249 YamlIO.mapOptional("fp64-fp16-input-denormals", Mode.FP64FP16InputDenormals, true);
250 YamlIO.mapOptional("fp64-fp16-output-denormals", Mode.FP64FP16OutputDenormals, true);
251 }
252};
253
260 bool IsEntryFunction = false;
261 bool IsChainFunction = false;
263 bool MemoryBound = false;
264 bool WaveLimiter = false;
265 bool HasSpilledSGPRs = false;
266 bool HasSpilledVGPRs = false;
268
269 // TODO: 10 may be a better default since it's the maximum.
270 unsigned Occupancy = 0;
271
273
274 StringValue ScratchRSrcReg = "$private_rsrc_reg";
277
279 bool ReturnsVoid = true;
280
281 std::optional<SIArgumentInfo> ArgInfo;
282
283 unsigned PSInputAddr = 0;
284 unsigned PSInputEnable = 0;
285
287 std::optional<FrameIndex> ScavengeFI;
291
294 const TargetRegisterInfo &TRI,
295 const llvm::MachineFunction &MF);
296
297 void mappingImpl(yaml::IO &YamlIO) override;
299};
300
302 static void mapping(IO &YamlIO, SIMachineFunctionInfo &MFI) {
303 YamlIO.mapOptional("explicitKernArgSize", MFI.ExplicitKernArgSize,
304 UINT64_C(0));
305 YamlIO.mapOptional("maxKernArgAlign", MFI.MaxKernArgAlign);
306 YamlIO.mapOptional("ldsSize", MFI.LDSSize, 0u);
307 YamlIO.mapOptional("gdsSize", MFI.GDSSize, 0u);
308 YamlIO.mapOptional("dynLDSAlign", MFI.DynLDSAlign, Align());
309 YamlIO.mapOptional("isEntryFunction", MFI.IsEntryFunction, false);
310 YamlIO.mapOptional("isChainFunction", MFI.IsChainFunction, false);
311 YamlIO.mapOptional("noSignedZerosFPMath", MFI.NoSignedZerosFPMath, false);
312 YamlIO.mapOptional("memoryBound", MFI.MemoryBound, false);
313 YamlIO.mapOptional("waveLimiter", MFI.WaveLimiter, false);
314 YamlIO.mapOptional("hasSpilledSGPRs", MFI.HasSpilledSGPRs, false);
315 YamlIO.mapOptional("hasSpilledVGPRs", MFI.HasSpilledVGPRs, false);
316 YamlIO.mapOptional("scratchRSrcReg", MFI.ScratchRSrcReg,
317 StringValue("$private_rsrc_reg"));
318 YamlIO.mapOptional("frameOffsetReg", MFI.FrameOffsetReg,
319 StringValue("$fp_reg"));
320 YamlIO.mapOptional("stackPtrOffsetReg", MFI.StackPtrOffsetReg,
321 StringValue("$sp_reg"));
322 YamlIO.mapOptional("bytesInStackArgArea", MFI.BytesInStackArgArea, 0u);
323 YamlIO.mapOptional("returnsVoid", MFI.ReturnsVoid, true);
324 YamlIO.mapOptional("argumentInfo", MFI.ArgInfo);
325 YamlIO.mapOptional("psInputAddr", MFI.PSInputAddr, 0u);
326 YamlIO.mapOptional("psInputEnable", MFI.PSInputEnable, 0u);
327 YamlIO.mapOptional("mode", MFI.Mode, SIMode());
328 YamlIO.mapOptional("highBitsOf32BitAddress",
329 MFI.HighBitsOf32BitAddress, 0u);
330 YamlIO.mapOptional("occupancy", MFI.Occupancy, 0);
331 YamlIO.mapOptional("wwmReservedRegs", MFI.WWMReservedRegs);
332 YamlIO.mapOptional("scavengeFI", MFI.ScavengeFI);
333 YamlIO.mapOptional("vgprForAGPRCopy", MFI.VGPRForAGPRCopy,
334 StringValue()); // Don't print out when it's empty.
335 YamlIO.mapOptional("sgprForEXECCopy", MFI.SGPRForEXECCopy,
336 StringValue()); // Don't print out when it's empty.
337 YamlIO.mapOptional("longBranchReservedReg", MFI.LongBranchReservedReg,
338 StringValue());
339 }
340};
341
342} // end namespace yaml
343
344// A CSR SGPR value can be preserved inside a callee using one of the following
345// methods.
346// 1. Copy to an unused scratch SGPR.
347// 2. Spill to a VGPR lane.
348// 3. Spill to memory via. a scratch VGPR.
349// class PrologEpilogSGPRSaveRestoreInfo represents the save/restore method used
350// for an SGPR at function prolog/epilog.
351enum class SGPRSaveKind : uint8_t {
355};
356
358 SGPRSaveKind Kind;
359 union {
360 int Index;
362 };
363
364public:
367 : Kind(K), Reg(R) {}
368 Register getReg() const { return Reg; }
369 int getIndex() const { return Index; }
370 SGPRSaveKind getKind() const { return Kind; }
371};
372
373/// This class keeps track of the SPI_SP_INPUT_ADDR config register, which
374/// tells the hardware which interpolation parameters to load.
377 friend class GCNTargetMachine;
378
379 // State of MODE register, assumed FP mode.
381
382 // Registers that may be reserved for spilling purposes. These may be the same
383 // as the input registers.
384 Register ScratchRSrcReg = AMDGPU::PRIVATE_RSRC_REG;
385
386 // This is the unswizzled offset from the current dispatch's scratch wave
387 // base to the beginning of the current function's frame.
388 Register FrameOffsetReg = AMDGPU::FP_REG;
389
390 // This is an ABI register used in the non-entry calling convention to
391 // communicate the unswizzled offset from the current dispatch's scratch wave
392 // base to the beginning of the new function's frame.
393 Register StackPtrOffsetReg = AMDGPU::SP_REG;
394
395 // Registers that may be reserved when RA doesn't allocate enough
396 // registers to plan for the case where an indirect branch ends up
397 // being needed during branch relaxation.
398 Register LongBranchReservedReg;
399
401
402 // Graphics info.
403 unsigned PSInputAddr = 0;
404 unsigned PSInputEnable = 0;
405
406 /// Number of bytes of arguments this function has on the stack. If the callee
407 /// is expected to restore the argument stack this should be a multiple of 16,
408 /// all usable during a tail call.
409 ///
410 /// The alternative would forbid tail call optimisation in some cases: if we
411 /// want to transfer control from a function with 8-bytes of stack-argument
412 /// space to a function with 16-bytes then misalignment of this value would
413 /// make a stack adjustment necessary, which could not be undone by the
414 /// callee.
415 unsigned BytesInStackArgArea = 0;
416
417 bool ReturnsVoid = true;
418
419 // A pair of default/requested minimum/maximum flat work group sizes.
420 // Minimum - first, maximum - second.
421 std::pair<unsigned, unsigned> FlatWorkGroupSizes = {0, 0};
422
423 // A pair of default/requested minimum/maximum number of waves per execution
424 // unit. Minimum - first, maximum - second.
425 std::pair<unsigned, unsigned> WavesPerEU = {0, 0};
426
427 const AMDGPUGWSResourcePseudoSourceValue GWSResourcePSV;
428
429 // Default/requested number of work groups for the function.
430 SmallVector<unsigned> MaxNumWorkGroups = {0, 0, 0};
431
432private:
433 unsigned NumUserSGPRs = 0;
434 unsigned NumSystemSGPRs = 0;
435
436 bool HasSpilledSGPRs = false;
437 bool HasSpilledVGPRs = false;
438 bool HasNonSpillStackObjects = false;
439 bool IsStackRealigned = false;
440
441 unsigned NumSpilledSGPRs = 0;
442 unsigned NumSpilledVGPRs = 0;
443
444 // Tracks information about user SGPRs that will be setup by hardware which
445 // will apply to all wavefronts of the grid.
446 GCNUserSGPRUsageInfo UserSGPRInfo;
447
448 // Feature bits required for inputs passed in system SGPRs.
449 bool WorkGroupIDX : 1; // Always initialized.
450 bool WorkGroupIDY : 1;
451 bool WorkGroupIDZ : 1;
452 bool WorkGroupInfo : 1;
453 bool LDSKernelId : 1;
454 bool PrivateSegmentWaveByteOffset : 1;
455
456 bool WorkItemIDX : 1; // Always initialized.
457 bool WorkItemIDY : 1;
458 bool WorkItemIDZ : 1;
459
460 // Pointer to where the ABI inserts special kernel arguments separate from the
461 // user arguments. This is an offset from the KernargSegmentPtr.
462 bool ImplicitArgPtr : 1;
463
464 bool MayNeedAGPRs : 1;
465
466 // The hard-wired high half of the address of the global information table
467 // for AMDPAL OS type. 0xffffffff represents no hard-wired high half, since
468 // current hardware only allows a 16 bit value.
469 unsigned GITPtrHigh;
470
471 unsigned HighBitsOf32BitAddress;
472
473 // Flags associated with the virtual registers.
474 IndexedMap<uint8_t, VirtReg2IndexFunctor> VRegFlags;
475
476 // Current recorded maximum possible occupancy.
477 unsigned Occupancy;
478
479 mutable std::optional<bool> UsesAGPRs;
480
481 MCPhysReg getNextUserSGPR() const;
482
483 MCPhysReg getNextSystemSGPR() const;
484
485 // MachineRegisterInfo callback functions to notify events.
486 void MRI_NoteNewVirtualRegister(Register Reg) override;
487 void MRI_NoteCloneVirtualRegister(Register NewReg, Register SrcReg) override;
488
489public:
492 bool FullyAllocated = false;
493 bool IsDead = false;
494 };
495
496private:
497 // To track virtual VGPR + lane index for each subregister of the SGPR spilled
498 // to frameindex key during SILowerSGPRSpills pass.
500 SGPRSpillsToVirtualVGPRLanes;
501 // To track physical VGPR + lane index for CSR SGPR spills and special SGPRs
502 // like Frame Pointer identified during PrologEpilogInserter.
504 SGPRSpillsToPhysicalVGPRLanes;
505 unsigned NumVirtualVGPRSpillLanes = 0;
506 unsigned NumPhysicalVGPRSpillLanes = 0;
507 SmallVector<Register, 2> SpillVGPRs;
508 SmallVector<Register, 2> SpillPhysVGPRs;
510 // To track the registers used in instructions that can potentially modify the
511 // inactive lanes. The WWM instructions and the writelane instructions for
512 // spilling SGPRs to VGPRs fall under such category of operations. The VGPRs
513 // modified by them should be spilled/restored at function prolog/epilog to
514 // avoid any undesired outcome. Each entry in this map holds a pair of values,
515 // the VGPR and its stack slot index.
516 WWMSpillsMap WWMSpills;
517
519 // To track the VGPRs reserved for WWM instructions. They get stack slots
520 // later during PrologEpilogInserter and get added into the superset WWMSpills
521 // for actual spilling. A separate set makes the register reserved part and
522 // the serialization easier.
523 ReservedRegSet WWMReservedRegs;
524
527 // To track the SGPR spill method used for a CSR SGPR register during
528 // frame lowering. Even though the SGPR spills are handled during
529 // SILowerSGPRSpills pass, some special handling needed later during the
530 // PrologEpilogInserter.
531 PrologEpilogSGPRSpillsMap PrologEpilogSGPRSpills;
532
533 // To save/restore EXEC MASK around WWM spills and copies.
534 Register SGPRForEXECCopy;
535
536 DenseMap<int, VGPRSpillToAGPR> VGPRToAGPRSpills;
537
538 // AGPRs used for VGPR spills.
540
541 // VGPRs used for AGPR spills.
543
544 // Emergency stack slot. Sometimes, we create this before finalizing the stack
545 // frame, so save it here and add it to the RegScavenger later.
546 std::optional<int> ScavengeFI;
547
548private:
549 Register VGPRForAGPRCopy;
550
551 bool allocateVirtualVGPRForSGPRSpills(MachineFunction &MF, int FI,
552 unsigned LaneIndex);
553 bool allocatePhysicalVGPRForSGPRSpills(MachineFunction &MF, int FI,
554 unsigned LaneIndex,
555 bool IsPrologEpilog);
556
557public:
559 return VGPRForAGPRCopy;
560 }
561
562 void setVGPRForAGPRCopy(Register NewVGPRForAGPRCopy) {
563 VGPRForAGPRCopy = NewVGPRForAGPRCopy;
564 }
565
566 bool isCalleeSavedReg(const MCPhysReg *CSRegs, MCPhysReg Reg) const;
567
568public:
570 SIMachineFunctionInfo(const Function &F, const GCNSubtarget *STI);
571
575 const override;
576
578 const MachineFunction &MF,
580 SMDiagnostic &Error, SMRange &SourceRange);
581
582 void reserveWWMRegister(Register Reg) { WWMReservedRegs.insert(Reg); }
583
584 SIModeRegisterDefaults getMode() const { return Mode; }
585
587 getSGPRSpillToVirtualVGPRLanes(int FrameIndex) const {
588 auto I = SGPRSpillsToVirtualVGPRLanes.find(FrameIndex);
589 return (I == SGPRSpillsToVirtualVGPRLanes.end())
591 : ArrayRef(I->second);
592 }
593
594 ArrayRef<Register> getSGPRSpillVGPRs() const { return SpillVGPRs; }
595
596 const WWMSpillsMap &getWWMSpills() const { return WWMSpills; }
597 const ReservedRegSet &getWWMReservedRegs() const { return WWMReservedRegs; }
598
600 return PrologEpilogSGPRSpills;
601 }
602
603 GCNUserSGPRUsageInfo &getUserSGPRInfo() { return UserSGPRInfo; }
604
605 const GCNUserSGPRUsageInfo &getUserSGPRInfo() const { return UserSGPRInfo; }
606
609 PrologEpilogSGPRSpills.insert(std::make_pair(Reg, SI));
610 }
611
612 // Check if an entry created for \p Reg in PrologEpilogSGPRSpills. Return true
613 // on success and false otherwise.
615 return PrologEpilogSGPRSpills.contains(Reg);
616 }
617
618 // Get the scratch SGPR if allocated to save/restore \p Reg.
620 auto I = PrologEpilogSGPRSpills.find(Reg);
621 if (I != PrologEpilogSGPRSpills.end() &&
622 I->second.getKind() == SGPRSaveKind::COPY_TO_SCRATCH_SGPR)
623 return I->second.getReg();
624
625 return AMDGPU::NoRegister;
626 }
627
628 // Get all scratch SGPRs allocated to copy/restore the SGPR spills.
630 for (const auto &SI : PrologEpilogSGPRSpills) {
631 if (SI.second.getKind() == SGPRSaveKind::COPY_TO_SCRATCH_SGPR)
632 Regs.push_back(SI.second.getReg());
633 }
634 }
635
636 // Check if \p FI is allocated for any SGPR spill to a VGPR lane during PEI.
638 return find_if(PrologEpilogSGPRSpills,
639 [FI](const std::pair<Register,
641 return SI.second.getKind() ==
643 SI.second.getIndex() == FI;
644 }) != PrologEpilogSGPRSpills.end();
645 }
646
649 auto I = PrologEpilogSGPRSpills.find(Reg);
650 assert(I != PrologEpilogSGPRSpills.end());
651
652 return I->second;
653 }
654
656 getSGPRSpillToPhysicalVGPRLanes(int FrameIndex) const {
657 auto I = SGPRSpillsToPhysicalVGPRLanes.find(FrameIndex);
658 return (I == SGPRSpillsToPhysicalVGPRLanes.end())
660 : ArrayRef(I->second);
661 }
662
663 void setFlag(Register Reg, uint8_t Flag) {
664 assert(Reg.isVirtual());
665 if (VRegFlags.inBounds(Reg))
666 VRegFlags[Reg] |= Flag;
667 }
668
669 bool checkFlag(Register Reg, uint8_t Flag) const {
670 if (Reg.isPhysical())
671 return false;
672
673 return VRegFlags.inBounds(Reg) && VRegFlags[Reg] & Flag;
674 }
675
676 bool hasVRegFlags() { return VRegFlags.size(); }
677
679 Align Alignment = Align(4));
680
682 MachineFunction &MF,
683 SmallVectorImpl<std::pair<Register, int>> &CalleeSavedRegs,
684 SmallVectorImpl<std::pair<Register, int>> &ScratchRegs) const;
685
687 return SpillAGPR;
688 }
689
690 Register getSGPRForEXECCopy() const { return SGPRForEXECCopy; }
691
692 void setSGPRForEXECCopy(Register Reg) { SGPRForEXECCopy = Reg; }
693
695 return SpillVGPR;
696 }
697
698 MCPhysReg getVGPRToAGPRSpill(int FrameIndex, unsigned Lane) const {
699 auto I = VGPRToAGPRSpills.find(FrameIndex);
700 return (I == VGPRToAGPRSpills.end()) ? (MCPhysReg)AMDGPU::NoRegister
701 : I->second.Lanes[Lane];
702 }
703
704 void setVGPRToAGPRSpillDead(int FrameIndex) {
705 auto I = VGPRToAGPRSpills.find(FrameIndex);
706 if (I != VGPRToAGPRSpills.end())
707 I->second.IsDead = true;
708 }
709
710 // To bring the Physical VGPRs in the highest range allocated for CSR SGPR
711 // spilling into the lowest available range.
713
715 bool SpillToPhysVGPRLane = false,
716 bool IsPrologEpilog = false);
717 bool allocateVGPRSpillToAGPR(MachineFunction &MF, int FI, bool isAGPRtoVGPR);
718
719 /// If \p ResetSGPRSpillStackIDs is true, reset the stack ID from sgpr-spill
720 /// to the default stack.
722 bool ResetSGPRSpillStackIDs);
723
725 std::optional<int> getOptionalScavengeFI() const { return ScavengeFI; }
726
727 unsigned getBytesInStackArgArea() const {
728 return BytesInStackArgArea;
729 }
730
731 void setBytesInStackArgArea(unsigned Bytes) {
732 BytesInStackArgArea = Bytes;
733 }
734
735 // Add user SGPRs.
746 unsigned AllocSizeDWord, int KernArgIdx,
747 int PaddingSGPRs);
748
749 /// Increment user SGPRs used for padding the argument list only.
751 Register Next = getNextUserSGPR();
752 ++NumUserSGPRs;
753 return Next;
754 }
755
756 // Add system SGPRs.
758 ArgInfo.WorkGroupIDX = ArgDescriptor::createRegister(getNextSystemSGPR());
759 NumSystemSGPRs += 1;
760 return ArgInfo.WorkGroupIDX.getRegister();
761 }
762
764 ArgInfo.WorkGroupIDY = ArgDescriptor::createRegister(getNextSystemSGPR());
765 NumSystemSGPRs += 1;
766 return ArgInfo.WorkGroupIDY.getRegister();
767 }
768
770 ArgInfo.WorkGroupIDZ = ArgDescriptor::createRegister(getNextSystemSGPR());
771 NumSystemSGPRs += 1;
772 return ArgInfo.WorkGroupIDZ.getRegister();
773 }
774
776 ArgInfo.WorkGroupInfo = ArgDescriptor::createRegister(getNextSystemSGPR());
777 NumSystemSGPRs += 1;
778 return ArgInfo.WorkGroupInfo.getRegister();
779 }
780
781 bool hasLDSKernelId() const { return LDSKernelId; }
782
783 // Add special VGPR inputs
785 ArgInfo.WorkItemIDX = Arg;
786 }
787
789 ArgInfo.WorkItemIDY = Arg;
790 }
791
793 ArgInfo.WorkItemIDZ = Arg;
794 }
795
797 ArgInfo.PrivateSegmentWaveByteOffset
798 = ArgDescriptor::createRegister(getNextSystemSGPR());
799 NumSystemSGPRs += 1;
800 return ArgInfo.PrivateSegmentWaveByteOffset.getRegister();
801 }
802
804 ArgInfo.PrivateSegmentWaveByteOffset = ArgDescriptor::createRegister(Reg);
805 }
806
807 bool hasWorkGroupIDX() const {
808 return WorkGroupIDX;
809 }
810
811 bool hasWorkGroupIDY() const {
812 return WorkGroupIDY;
813 }
814
815 bool hasWorkGroupIDZ() const {
816 return WorkGroupIDZ;
817 }
818
819 bool hasWorkGroupInfo() const {
820 return WorkGroupInfo;
821 }
822
824 return PrivateSegmentWaveByteOffset;
825 }
826
827 bool hasWorkItemIDX() const {
828 return WorkItemIDX;
829 }
830
831 bool hasWorkItemIDY() const {
832 return WorkItemIDY;
833 }
834
835 bool hasWorkItemIDZ() const {
836 return WorkItemIDZ;
837 }
838
839 bool hasImplicitArgPtr() const {
840 return ImplicitArgPtr;
841 }
842
844 return ArgInfo;
845 }
846
848 return ArgInfo;
849 }
850
851 std::tuple<const ArgDescriptor *, const TargetRegisterClass *, LLT>
853 return ArgInfo.getPreloadedValue(Value);
854 }
855
857 auto Arg = std::get<0>(ArgInfo.getPreloadedValue(Value));
858 return Arg ? Arg->getRegister() : MCRegister();
859 }
860
861 unsigned getGITPtrHigh() const {
862 return GITPtrHigh;
863 }
864
865 Register getGITPtrLoReg(const MachineFunction &MF) const;
866
868 return HighBitsOf32BitAddress;
869 }
870
871 unsigned getNumUserSGPRs() const {
872 return NumUserSGPRs;
873 }
874
875 unsigned getNumPreloadedSGPRs() const {
876 return NumUserSGPRs + NumSystemSGPRs;
877 }
878
880 return UserSGPRInfo.getNumKernargPreloadSGPRs();
881 }
882
884 return ArgInfo.PrivateSegmentWaveByteOffset.getRegister();
885 }
886
887 /// Returns the physical register reserved for use as the resource
888 /// descriptor for scratch accesses.
890 return ScratchRSrcReg;
891 }
892
894 assert(Reg != 0 && "Should never be unset");
895 ScratchRSrcReg = Reg;
896 }
897
899 return FrameOffsetReg;
900 }
901
903 assert(Reg != 0 && "Should never be unset");
904 FrameOffsetReg = Reg;
905 }
906
908 assert(Reg != 0 && "Should never be unset");
909 StackPtrOffsetReg = Reg;
910 }
911
912 void setLongBranchReservedReg(Register Reg) { LongBranchReservedReg = Reg; }
913
914 // Note the unset value for this is AMDGPU::SP_REG rather than
915 // NoRegister. This is mostly a workaround for MIR tests where state that
916 // can't be directly computed from the function is not preserved in serialized
917 // MIR.
919 return StackPtrOffsetReg;
920 }
921
922 Register getLongBranchReservedReg() const { return LongBranchReservedReg; }
923
925 return ArgInfo.QueuePtr.getRegister();
926 }
927
929 return ArgInfo.ImplicitBufferPtr.getRegister();
930 }
931
932 bool hasSpilledSGPRs() const {
933 return HasSpilledSGPRs;
934 }
935
936 void setHasSpilledSGPRs(bool Spill = true) {
937 HasSpilledSGPRs = Spill;
938 }
939
940 bool hasSpilledVGPRs() const {
941 return HasSpilledVGPRs;
942 }
943
944 void setHasSpilledVGPRs(bool Spill = true) {
945 HasSpilledVGPRs = Spill;
946 }
947
949 return HasNonSpillStackObjects;
950 }
951
952 void setHasNonSpillStackObjects(bool StackObject = true) {
953 HasNonSpillStackObjects = StackObject;
954 }
955
956 bool isStackRealigned() const {
957 return IsStackRealigned;
958 }
959
960 void setIsStackRealigned(bool Realigned = true) {
961 IsStackRealigned = Realigned;
962 }
963
964 unsigned getNumSpilledSGPRs() const {
965 return NumSpilledSGPRs;
966 }
967
968 unsigned getNumSpilledVGPRs() const {
969 return NumSpilledVGPRs;
970 }
971
972 void addToSpilledSGPRs(unsigned num) {
973 NumSpilledSGPRs += num;
974 }
975
976 void addToSpilledVGPRs(unsigned num) {
977 NumSpilledVGPRs += num;
978 }
979
980 unsigned getPSInputAddr() const {
981 return PSInputAddr;
982 }
983
984 unsigned getPSInputEnable() const {
985 return PSInputEnable;
986 }
987
988 bool isPSInputAllocated(unsigned Index) const {
989 return PSInputAddr & (1 << Index);
990 }
991
993 PSInputAddr |= 1 << Index;
994 }
995
996 void markPSInputEnabled(unsigned Index) {
997 PSInputEnable |= 1 << Index;
998 }
999
1000 bool returnsVoid() const {
1001 return ReturnsVoid;
1002 }
1003
1005 ReturnsVoid = Value;
1006 }
1007
1008 /// \returns A pair of default/requested minimum/maximum flat work group sizes
1009 /// for this function.
1010 std::pair<unsigned, unsigned> getFlatWorkGroupSizes() const {
1011 return FlatWorkGroupSizes;
1012 }
1013
1014 /// \returns Default/requested minimum flat work group size for this function.
1015 unsigned getMinFlatWorkGroupSize() const {
1016 return FlatWorkGroupSizes.first;
1017 }
1018
1019 /// \returns Default/requested maximum flat work group size for this function.
1020 unsigned getMaxFlatWorkGroupSize() const {
1021 return FlatWorkGroupSizes.second;
1022 }
1023
1024 /// \returns A pair of default/requested minimum/maximum number of waves per
1025 /// execution unit.
1026 std::pair<unsigned, unsigned> getWavesPerEU() const {
1027 return WavesPerEU;
1028 }
1029
1030 /// \returns Default/requested minimum number of waves per execution unit.
1031 unsigned getMinWavesPerEU() const {
1032 return WavesPerEU.first;
1033 }
1034
1035 /// \returns Default/requested maximum number of waves per execution unit.
1036 unsigned getMaxWavesPerEU() const {
1037 return WavesPerEU.second;
1038 }
1039
1042 return &GWSResourcePSV;
1043 }
1044
1045 unsigned getOccupancy() const {
1046 return Occupancy;
1047 }
1048
1049 unsigned getMinAllowedOccupancy() const {
1050 if (!isMemoryBound() && !needsWaveLimiter())
1051 return Occupancy;
1052 return (Occupancy < 4) ? Occupancy : 4;
1053 }
1054
1055 void limitOccupancy(const MachineFunction &MF);
1056
1057 void limitOccupancy(unsigned Limit) {
1058 if (Occupancy > Limit)
1059 Occupancy = Limit;
1060 }
1061
1062 void increaseOccupancy(const MachineFunction &MF, unsigned Limit) {
1063 if (Occupancy < Limit)
1064 Occupancy = Limit;
1065 limitOccupancy(MF);
1066 }
1067
1068 bool mayNeedAGPRs() const {
1069 return MayNeedAGPRs;
1070 }
1071
1072 // \returns true if a function has a use of AGPRs via inline asm or
1073 // has a call which may use it.
1074 bool mayUseAGPRs(const Function &F) const;
1075
1076 // \returns true if a function needs or may need AGPRs.
1077 bool usesAGPRs(const MachineFunction &MF) const;
1078
1079 /// \returns Default/requested number of work groups for this function.
1080 SmallVector<unsigned> getMaxNumWorkGroups() const { return MaxNumWorkGroups; }
1081
1082 unsigned getMaxNumWorkGroupsX() const { return MaxNumWorkGroups[0]; }
1083 unsigned getMaxNumWorkGroupsY() const { return MaxNumWorkGroups[1]; }
1084 unsigned getMaxNumWorkGroupsZ() const { return MaxNumWorkGroups[2]; }
1085};
1086
1087} // end namespace llvm
1088
1089#endif // LLVM_LIB_TARGET_AMDGPU_SIMACHINEFUNCTIONINFO_H
Provides AMDGPU specific target descriptions.
The AMDGPU TargetMachine interface definition for hw codegen targets.
basic Basic Alias true
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
uint64_t Size
IO & YamlIO
Definition: ELFYAML.cpp:1289
AMD GCN specific subclass of TargetSubtarget.
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
unsigned const TargetRegisterInfo * TRI
unsigned Reg
Promote Memory to Register
Definition: Mem2Reg.cpp:110
const char LLVMTargetMachineRef TM
Basic Register Allocator
static cl::opt< RegAllocEvictionAdvisorAnalysis::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Development, "development", "for training")))
Interface definition for SIInstrInfo.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallVector class.
void printCustom(raw_ostream &OS) const override
Implement printing for PseudoSourceValue.
static bool classof(const PseudoSourceValue *V)
AMDGPUGWSResourcePseudoSourceValue(const AMDGPUTargetMachine &TM)
bool mayAlias(const MachineFrameInfo *) const override
Return true if the memory pointed to by this PseudoSourceValue can ever alias an LLVM IR Value.
bool isAliased(const MachineFrameInfo *) const override
Test whether the memory pointed to by this PseudoSourceValue may also be pointed to by an LLVM IR Val...
bool isConstant(const MachineFrameInfo *) const override
Test whether the memory pointed to by this PseudoSourceValue has a constant value.
AMDGPUPseudoSourceValue(unsigned Kind, const AMDGPUTargetMachine &TM)
bool mayAlias(const MachineFrameInfo *) const override
Return true if the memory pointed to by this PseudoSourceValue can ever alias an LLVM IR Value.
bool isAliased(const MachineFrameInfo *) const override
Test whether the memory pointed to by this PseudoSourceValue may also be pointed to by an LLVM IR Val...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:66
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:155
iterator end()
Definition: DenseMap.h:84
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
Definition: DenseMap.h:145
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:220
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
PrologEpilogSGPRSaveRestoreInfo(SGPRSaveKind K, Register R)
PrologEpilogSGPRSaveRestoreInfo(SGPRSaveKind K, int I)
Special value supplied for machine level alias analysis.
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
const WWMSpillsMap & getWWMSpills() const
bool usesAGPRs(const MachineFunction &MF) const
bool isPSInputAllocated(unsigned Index) const
void getAllScratchSGPRCopyDstRegs(SmallVectorImpl< Register > &Regs) const
ArrayRef< MCPhysReg > getAGPRSpillVGPRs() const
bool initializeBaseYamlFields(const yaml::SIMachineFunctionInfo &YamlMFI, const MachineFunction &MF, PerFunctionMIParsingState &PFS, SMDiagnostic &Error, SMRange &SourceRange)
void setWorkItemIDY(ArgDescriptor Arg)
const PrologEpilogSGPRSpillsMap & getPrologEpilogSGPRSpills() const
void increaseOccupancy(const MachineFunction &MF, unsigned Limit)
void setWorkItemIDZ(ArgDescriptor Arg)
std::pair< unsigned, unsigned > getWavesPerEU() const
MCPhysReg getVGPRToAGPRSpill(int FrameIndex, unsigned Lane) const
GCNUserSGPRUsageInfo & getUserSGPRInfo()
void allocateWWMSpill(MachineFunction &MF, Register VGPR, uint64_t Size=4, Align Alignment=Align(4))
Register addDispatchPtr(const SIRegisterInfo &TRI)
void setFlag(Register Reg, uint8_t Flag)
void setVGPRToAGPRSpillDead(int FrameIndex)
std::pair< unsigned, unsigned > getFlatWorkGroupSizes() const
Register addFlatScratchInit(const SIRegisterInfo &TRI)
Register getScratchRSrcReg() const
Returns the physical register reserved for use as the resource descriptor for scratch accesses.
void setStackPtrOffsetReg(Register Reg)
Register addReservedUserSGPR()
Increment user SGPRs used for padding the argument list only.
ArrayRef< MCPhysReg > getVGPRSpillAGPRs() const
int getScavengeFI(MachineFrameInfo &MFI, const SIRegisterInfo &TRI)
Register addQueuePtr(const SIRegisterInfo &TRI)
ArrayRef< SIRegisterInfo::SpilledReg > getSGPRSpillToVirtualVGPRLanes(int FrameIndex) const
SIMachineFunctionInfo(const SIMachineFunctionInfo &MFI)=default
SmallVector< unsigned > getMaxNumWorkGroups() const
bool hasPrologEpilogSGPRSpillEntry(Register Reg) const
Register getGITPtrLoReg(const MachineFunction &MF) const
void setVGPRForAGPRCopy(Register NewVGPRForAGPRCopy)
bool allocateVGPRSpillToAGPR(MachineFunction &MF, int FI, bool isAGPRtoVGPR)
Reserve AGPRs or VGPRs to support spilling for FrameIndex FI.
void splitWWMSpillRegisters(MachineFunction &MF, SmallVectorImpl< std::pair< Register, int > > &CalleeSavedRegs, SmallVectorImpl< std::pair< Register, int > > &ScratchRegs) const
void setBytesInStackArgArea(unsigned Bytes)
SIModeRegisterDefaults getMode() const
ArrayRef< SIRegisterInfo::SpilledReg > getSGPRSpillToPhysicalVGPRLanes(int FrameIndex) const
std::tuple< const ArgDescriptor *, const TargetRegisterClass *, LLT > getPreloadedValue(AMDGPUFunctionArgInfo::PreloadedValue Value) const
bool mayUseAGPRs(const Function &F) const
bool isCalleeSavedReg(const MCPhysReg *CSRegs, MCPhysReg Reg) const
void shiftSpillPhysVGPRsToLowestRange(MachineFunction &MF)
const GCNUserSGPRUsageInfo & getUserSGPRInfo() const
bool allocateSGPRSpillToVGPRLane(MachineFunction &MF, int FI, bool SpillToPhysVGPRLane=false, bool IsPrologEpilog=false)
void setPrivateSegmentWaveByteOffset(Register Reg)
void setLongBranchReservedReg(Register Reg)
const AMDGPUFunctionArgInfo & getArgInfo() const
Register addKernargSegmentPtr(const SIRegisterInfo &TRI)
Register addDispatchID(const SIRegisterInfo &TRI)
void setHasSpilledVGPRs(bool Spill=true)
bool removeDeadFrameIndices(MachineFrameInfo &MFI, bool ResetSGPRSpillStackIDs)
If ResetSGPRSpillStackIDs is true, reset the stack ID from sgpr-spill to the default stack.
void markPSInputAllocated(unsigned Index)
void setWorkItemIDX(ArgDescriptor Arg)
MachineFunctionInfo * clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, const DenseMap< MachineBasicBlock *, MachineBasicBlock * > &Src2DstMBB) const override
Make a functionally equivalent copy of this MachineFunctionInfo in MF.
bool checkFlag(Register Reg, uint8_t Flag) const
void markPSInputEnabled(unsigned Index)
MCRegister getPreloadedReg(AMDGPUFunctionArgInfo::PreloadedValue Value) const
void setHasSpilledSGPRs(bool Spill=true)
bool checkIndexInPrologEpilogSGPRSpills(int FI) const
unsigned getNumKernargPreloadedSGPRs() const
Register addPrivateSegmentBuffer(const SIRegisterInfo &TRI)
const ReservedRegSet & getWWMReservedRegs() const
Register getImplicitBufferPtrUserSGPR() const
std::optional< int > getOptionalScavengeFI() const
Register addImplicitBufferPtr(const SIRegisterInfo &TRI)
AMDGPUFunctionArgInfo & getArgInfo()
const PrologEpilogSGPRSaveRestoreInfo & getPrologEpilogSGPRSaveRestoreInfo(Register Reg) const
void setHasNonSpillStackObjects(bool StackObject=true)
void setIsStackRealigned(bool Realigned=true)
void limitOccupancy(const MachineFunction &MF)
ArrayRef< Register > getSGPRSpillVGPRs() const
SmallVectorImpl< MCRegister > * addPreloadedKernArg(const SIRegisterInfo &TRI, const TargetRegisterClass *RC, unsigned AllocSizeDWord, int KernArgIdx, int PaddingSGPRs)
void addToPrologEpilogSGPRSpills(Register Reg, PrologEpilogSGPRSaveRestoreInfo SI)
Register getScratchSGPRCopyDstReg(Register Reg) const
Register getPrivateSegmentWaveByteOffsetSystemSGPR() const
const AMDGPUGWSResourcePseudoSourceValue * getGWSPSV(const AMDGPUTargetMachine &TM)
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
Definition: SourceMgr.h:281
Represents a range in source code.
Definition: SMLoc.h:48
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition: SetVector.h:162
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:586
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
StackOffset holds a fixed and a scalable offset in bytes.
Definition: TypeSize.h:33
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
LLVM Value Representation.
Definition: Value.h:74
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition: MCRegister.h:21
@ Other
Any other memory.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1758
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition: STLExtras.h:1888
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
static ArgDescriptor createRegister(Register Reg, unsigned Mask=~0u)
Helper struct shared between Function Specialization and SCCP Solver.
Definition: SCCPSolver.h:41
@ PreserveSign
The sign of a flushed-to-zero number is preserved in the sign of 0.
MachineFunctionInfo - This class can be derived from and used by targets to hold private target-speci...
Targets should override this in a way that mirrors the implementation of llvm::MachineFunctionInfo.
static void mapping(IO &YamlIO, SIArgumentInfo &AI)
static void mapping(IO &YamlIO, SIArgument &A)
static void mapping(IO &YamlIO, SIMachineFunctionInfo &MFI)
static void mapping(IO &YamlIO, SIMode &Mode)
std::optional< SIArgument > PrivateSegmentWaveByteOffset
std::optional< SIArgument > WorkGroupIDY
std::optional< SIArgument > FlatScratchInit
std::optional< SIArgument > DispatchPtr
std::optional< SIArgument > DispatchID
std::optional< SIArgument > WorkItemIDY
std::optional< SIArgument > WorkGroupIDX
std::optional< SIArgument > ImplicitArgPtr
std::optional< SIArgument > QueuePtr
std::optional< SIArgument > WorkGroupInfo
std::optional< SIArgument > LDSKernelId
std::optional< SIArgument > ImplicitBufferPtr
std::optional< SIArgument > WorkItemIDX
std::optional< SIArgument > KernargSegmentPtr
std::optional< SIArgument > WorkItemIDZ
std::optional< SIArgument > PrivateSegmentSize
std::optional< SIArgument > PrivateSegmentBuffer
std::optional< SIArgument > WorkGroupIDZ
std::optional< unsigned > Mask
SIArgument(const SIArgument &Other)
SIArgument & operator=(const SIArgument &Other)
static SIArgument createArgument(bool IsReg)
SmallVector< StringValue > WWMReservedRegs
void mappingImpl(yaml::IO &YamlIO) override
std::optional< SIArgumentInfo > ArgInfo
std::optional< FrameIndex > ScavengeFI
SIMode(const SIModeRegisterDefaults &Mode)
bool operator==(const SIMode Other) const
A wrapper around std::string which contains a source range that's being set during parsing.