xref: /llvm-project/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h (revision bc6d07ca46d7e77f3602281a0d0b89ac818ef40d)
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 
16 #include "AMDGPUArgumentUsageInfo.h"
17 #include "AMDGPUMachineFunction.h"
18 #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
19 #include "SIInstrInfo.h"
20 #include "SIRegisterInfo.h"
21 #include "llvm/ADT/ArrayRef.h"
22 #include "llvm/ADT/DenseMap.h"
23 #include "llvm/ADT/Optional.h"
24 #include "llvm/ADT/SmallVector.h"
25 #include "llvm/CodeGen/MIRYamlMapping.h"
26 #include "llvm/CodeGen/PseudoSourceValue.h"
27 #include "llvm/CodeGen/TargetInstrInfo.h"
28 #include "llvm/MC/MCRegisterInfo.h"
29 #include "llvm/Support/ErrorHandling.h"
30 #include <array>
31 #include <cassert>
32 #include <utility>
33 #include <vector>
34 
35 namespace llvm {
36 
37 class MachineFrameInfo;
38 class MachineFunction;
39 class TargetRegisterClass;
40 
41 class AMDGPUImagePseudoSourceValue : public PseudoSourceValue {
42 public:
43   // TODO: Is the img rsrc useful?
44   explicit AMDGPUImagePseudoSourceValue(const TargetInstrInfo &TII) :
45     PseudoSourceValue(PseudoSourceValue::TargetCustom, TII) {}
46 
47   bool isConstant(const MachineFrameInfo *) const override {
48     // This should probably be true for most images, but we will start by being
49     // conservative.
50     return false;
51   }
52 
53   bool isAliased(const MachineFrameInfo *) const override {
54     return true;
55   }
56 
57   bool mayAlias(const MachineFrameInfo *) const override {
58     return true;
59   }
60 };
61 
62 class AMDGPUBufferPseudoSourceValue : public PseudoSourceValue {
63 public:
64   explicit AMDGPUBufferPseudoSourceValue(const TargetInstrInfo &TII) :
65     PseudoSourceValue(PseudoSourceValue::TargetCustom, TII) { }
66 
67   bool isConstant(const MachineFrameInfo *) const override {
68     // This should probably be true for most images, but we will start by being
69     // conservative.
70     return false;
71   }
72 
73   bool isAliased(const MachineFrameInfo *) const override {
74     return true;
75   }
76 
77   bool mayAlias(const MachineFrameInfo *) const override {
78     return true;
79   }
80 };
81 
82 namespace yaml {
83 
84 struct SIMachineFunctionInfo final : public yaml::MachineFunctionInfo {
85   uint64_t ExplicitKernArgSize = 0;
86   unsigned MaxKernArgAlign = 0;
87   unsigned LDSSize = 0;
88   bool IsEntryFunction = false;
89   bool NoSignedZerosFPMath = false;
90   bool MemoryBound = false;
91   bool WaveLimiter = false;
92 
93   StringValue ScratchRSrcReg = "$private_rsrc_reg";
94   StringValue ScratchWaveOffsetReg = "$scratch_wave_offset_reg";
95   StringValue FrameOffsetReg = "$fp_reg";
96   StringValue StackPtrOffsetReg = "$sp_reg";
97 
98   SIMachineFunctionInfo() = default;
99   SIMachineFunctionInfo(const llvm::SIMachineFunctionInfo &,
100                         const TargetRegisterInfo &TRI);
101 
102   void mappingImpl(yaml::IO &YamlIO) override;
103   ~SIMachineFunctionInfo() = default;
104 };
105 
106 template <> struct MappingTraits<SIMachineFunctionInfo> {
107   static void mapping(IO &YamlIO, SIMachineFunctionInfo &MFI) {
108     YamlIO.mapOptional("explicitKernArgSize", MFI.ExplicitKernArgSize,
109                        UINT64_C(0));
110     YamlIO.mapOptional("maxKernArgAlign", MFI.MaxKernArgAlign, 0u);
111     YamlIO.mapOptional("ldsSize", MFI.LDSSize, 0u);
112     YamlIO.mapOptional("isEntryFunction", MFI.IsEntryFunction, false);
113     YamlIO.mapOptional("noSignedZerosFPMath", MFI.NoSignedZerosFPMath, false);
114     YamlIO.mapOptional("memoryBound", MFI.MemoryBound, false);
115     YamlIO.mapOptional("waveLimiter", MFI.WaveLimiter, false);
116     YamlIO.mapOptional("scratchRSrcReg", MFI.ScratchRSrcReg,
117                        StringValue("$private_rsrc_reg"));
118     YamlIO.mapOptional("scratchWaveOffsetReg", MFI.ScratchWaveOffsetReg,
119                        StringValue("$scratch_wave_offset_reg"));
120     YamlIO.mapOptional("frameOffsetReg", MFI.FrameOffsetReg,
121                        StringValue("$fp_reg"));
122     YamlIO.mapOptional("stackPtrOffsetReg", MFI.StackPtrOffsetReg,
123                        StringValue("$sp_reg"));
124   }
125 };
126 
127 } // end namespace yaml
128 
129 /// This class keeps track of the SPI_SP_INPUT_ADDR config register, which
130 /// tells the hardware which interpolation parameters to load.
131 class SIMachineFunctionInfo final : public AMDGPUMachineFunction {
132   friend class GCNTargetMachine;
133 
134   unsigned TIDReg = AMDGPU::NoRegister;
135 
136   // Registers that may be reserved for spilling purposes. These may be the same
137   // as the input registers.
138   unsigned ScratchRSrcReg = AMDGPU::PRIVATE_RSRC_REG;
139   unsigned ScratchWaveOffsetReg = AMDGPU::SCRATCH_WAVE_OFFSET_REG;
140 
141   // This is the current function's incremented size from the kernel's scratch
142   // wave offset register. For an entry function, this is exactly the same as
143   // the ScratchWaveOffsetReg.
144   unsigned FrameOffsetReg = AMDGPU::FP_REG;
145 
146   // Top of the stack SGPR offset derived from the ScratchWaveOffsetReg.
147   unsigned StackPtrOffsetReg = AMDGPU::SP_REG;
148 
149   AMDGPUFunctionArgInfo ArgInfo;
150 
151   // Graphics info.
152   unsigned PSInputAddr = 0;
153   unsigned PSInputEnable = 0;
154 
155   /// Number of bytes of arguments this function has on the stack. If the callee
156   /// is expected to restore the argument stack this should be a multiple of 16,
157   /// all usable during a tail call.
158   ///
159   /// The alternative would forbid tail call optimisation in some cases: if we
160   /// want to transfer control from a function with 8-bytes of stack-argument
161   /// space to a function with 16-bytes then misalignment of this value would
162   /// make a stack adjustment necessary, which could not be undone by the
163   /// callee.
164   unsigned BytesInStackArgArea = 0;
165 
166   bool ReturnsVoid = true;
167 
168   // A pair of default/requested minimum/maximum flat work group sizes.
169   // Minimum - first, maximum - second.
170   std::pair<unsigned, unsigned> FlatWorkGroupSizes = {0, 0};
171 
172   // A pair of default/requested minimum/maximum number of waves per execution
173   // unit. Minimum - first, maximum - second.
174   std::pair<unsigned, unsigned> WavesPerEU = {0, 0};
175 
176   DenseMap<const Value *,
177            std::unique_ptr<const AMDGPUBufferPseudoSourceValue>> BufferPSVs;
178   DenseMap<const Value *,
179            std::unique_ptr<const AMDGPUImagePseudoSourceValue>> ImagePSVs;
180 
181 private:
182   unsigned LDSWaveSpillSize = 0;
183   unsigned NumUserSGPRs = 0;
184   unsigned NumSystemSGPRs = 0;
185 
186   bool HasSpilledSGPRs = false;
187   bool HasSpilledVGPRs = false;
188   bool HasNonSpillStackObjects = false;
189   bool IsStackRealigned = false;
190 
191   unsigned NumSpilledSGPRs = 0;
192   unsigned NumSpilledVGPRs = 0;
193 
194   // Feature bits required for inputs passed in user SGPRs.
195   bool PrivateSegmentBuffer : 1;
196   bool DispatchPtr : 1;
197   bool QueuePtr : 1;
198   bool KernargSegmentPtr : 1;
199   bool DispatchID : 1;
200   bool FlatScratchInit : 1;
201 
202   // Feature bits required for inputs passed in system SGPRs.
203   bool WorkGroupIDX : 1; // Always initialized.
204   bool WorkGroupIDY : 1;
205   bool WorkGroupIDZ : 1;
206   bool WorkGroupInfo : 1;
207   bool PrivateSegmentWaveByteOffset : 1;
208 
209   bool WorkItemIDX : 1; // Always initialized.
210   bool WorkItemIDY : 1;
211   bool WorkItemIDZ : 1;
212 
213   // Private memory buffer
214   // Compute directly in sgpr[0:1]
215   // Other shaders indirect 64-bits at sgpr[0:1]
216   bool ImplicitBufferPtr : 1;
217 
218   // Pointer to where the ABI inserts special kernel arguments separate from the
219   // user arguments. This is an offset from the KernargSegmentPtr.
220   bool ImplicitArgPtr : 1;
221 
222   // The hard-wired high half of the address of the global information table
223   // for AMDPAL OS type. 0xffffffff represents no hard-wired high half, since
224   // current hardware only allows a 16 bit value.
225   unsigned GITPtrHigh;
226 
227   unsigned HighBitsOf32BitAddress;
228 
229   // Current recorded maximum possible occupancy.
230   unsigned Occupancy;
231 
232   MCPhysReg getNextUserSGPR() const;
233 
234   MCPhysReg getNextSystemSGPR() const;
235 
236 public:
237   struct SpilledReg {
238     unsigned VGPR = 0;
239     int Lane = -1;
240 
241     SpilledReg() = default;
242     SpilledReg(unsigned R, int L) : VGPR (R), Lane (L) {}
243 
244     bool hasLane() { return Lane != -1;}
245     bool hasReg() { return VGPR != 0;}
246   };
247 
248   struct SGPRSpillVGPRCSR {
249     // VGPR used for SGPR spills
250     unsigned VGPR;
251 
252     // If the VGPR is a CSR, the stack slot used to save/restore it in the
253     // prolog/epilog.
254     Optional<int> FI;
255 
256     SGPRSpillVGPRCSR(unsigned V, Optional<int> F) : VGPR(V), FI(F) {}
257   };
258 
259 private:
260   // SGPR->VGPR spilling support.
261   using SpillRegMask = std::pair<unsigned, unsigned>;
262 
263   // Track VGPR + wave index for each subregister of the SGPR spilled to
264   // frameindex key.
265   DenseMap<int, std::vector<SpilledReg>> SGPRToVGPRSpills;
266   unsigned NumVGPRSpillLanes = 0;
267   SmallVector<SGPRSpillVGPRCSR, 2> SpillVGPRs;
268 
269 public:
270   SIMachineFunctionInfo(const MachineFunction &MF);
271 
272   bool initializeBaseYamlFields(const yaml::SIMachineFunctionInfo &YamlMFI);
273 
274   ArrayRef<SpilledReg> getSGPRToVGPRSpills(int FrameIndex) const {
275     auto I = SGPRToVGPRSpills.find(FrameIndex);
276     return (I == SGPRToVGPRSpills.end()) ?
277       ArrayRef<SpilledReg>() : makeArrayRef(I->second);
278   }
279 
280   ArrayRef<SGPRSpillVGPRCSR> getSGPRSpillVGPRs() const {
281     return SpillVGPRs;
282   }
283 
284   bool allocateSGPRSpillToVGPR(MachineFunction &MF, int FI);
285   void removeSGPRToVGPRFrameIndices(MachineFrameInfo &MFI);
286 
287   bool hasCalculatedTID() const { return TIDReg != 0; };
288   unsigned getTIDReg() const { return TIDReg; };
289   void setTIDReg(unsigned Reg) { TIDReg = Reg; }
290 
291   unsigned getBytesInStackArgArea() const {
292     return BytesInStackArgArea;
293   }
294 
295   void setBytesInStackArgArea(unsigned Bytes) {
296     BytesInStackArgArea = Bytes;
297   }
298 
299   // Add user SGPRs.
300   unsigned addPrivateSegmentBuffer(const SIRegisterInfo &TRI);
301   unsigned addDispatchPtr(const SIRegisterInfo &TRI);
302   unsigned addQueuePtr(const SIRegisterInfo &TRI);
303   unsigned addKernargSegmentPtr(const SIRegisterInfo &TRI);
304   unsigned addDispatchID(const SIRegisterInfo &TRI);
305   unsigned addFlatScratchInit(const SIRegisterInfo &TRI);
306   unsigned addImplicitBufferPtr(const SIRegisterInfo &TRI);
307 
308   // Add system SGPRs.
309   unsigned addWorkGroupIDX() {
310     ArgInfo.WorkGroupIDX = ArgDescriptor::createRegister(getNextSystemSGPR());
311     NumSystemSGPRs += 1;
312     return ArgInfo.WorkGroupIDX.getRegister();
313   }
314 
315   unsigned addWorkGroupIDY() {
316     ArgInfo.WorkGroupIDY = ArgDescriptor::createRegister(getNextSystemSGPR());
317     NumSystemSGPRs += 1;
318     return ArgInfo.WorkGroupIDY.getRegister();
319   }
320 
321   unsigned addWorkGroupIDZ() {
322     ArgInfo.WorkGroupIDZ = ArgDescriptor::createRegister(getNextSystemSGPR());
323     NumSystemSGPRs += 1;
324     return ArgInfo.WorkGroupIDZ.getRegister();
325   }
326 
327   unsigned addWorkGroupInfo() {
328     ArgInfo.WorkGroupInfo = ArgDescriptor::createRegister(getNextSystemSGPR());
329     NumSystemSGPRs += 1;
330     return ArgInfo.WorkGroupInfo.getRegister();
331   }
332 
333   // Add special VGPR inputs
334   void setWorkItemIDX(ArgDescriptor Arg) {
335     ArgInfo.WorkItemIDX = Arg;
336   }
337 
338   void setWorkItemIDY(ArgDescriptor Arg) {
339     ArgInfo.WorkItemIDY = Arg;
340   }
341 
342   void setWorkItemIDZ(ArgDescriptor Arg) {
343     ArgInfo.WorkItemIDZ = Arg;
344   }
345 
346   unsigned addPrivateSegmentWaveByteOffset() {
347     ArgInfo.PrivateSegmentWaveByteOffset
348       = ArgDescriptor::createRegister(getNextSystemSGPR());
349     NumSystemSGPRs += 1;
350     return ArgInfo.PrivateSegmentWaveByteOffset.getRegister();
351   }
352 
353   void setPrivateSegmentWaveByteOffset(unsigned Reg) {
354     ArgInfo.PrivateSegmentWaveByteOffset = ArgDescriptor::createRegister(Reg);
355   }
356 
357   bool hasPrivateSegmentBuffer() const {
358     return PrivateSegmentBuffer;
359   }
360 
361   bool hasDispatchPtr() const {
362     return DispatchPtr;
363   }
364 
365   bool hasQueuePtr() const {
366     return QueuePtr;
367   }
368 
369   bool hasKernargSegmentPtr() const {
370     return KernargSegmentPtr;
371   }
372 
373   bool hasDispatchID() const {
374     return DispatchID;
375   }
376 
377   bool hasFlatScratchInit() const {
378     return FlatScratchInit;
379   }
380 
381   bool hasWorkGroupIDX() const {
382     return WorkGroupIDX;
383   }
384 
385   bool hasWorkGroupIDY() const {
386     return WorkGroupIDY;
387   }
388 
389   bool hasWorkGroupIDZ() const {
390     return WorkGroupIDZ;
391   }
392 
393   bool hasWorkGroupInfo() const {
394     return WorkGroupInfo;
395   }
396 
397   bool hasPrivateSegmentWaveByteOffset() const {
398     return PrivateSegmentWaveByteOffset;
399   }
400 
401   bool hasWorkItemIDX() const {
402     return WorkItemIDX;
403   }
404 
405   bool hasWorkItemIDY() const {
406     return WorkItemIDY;
407   }
408 
409   bool hasWorkItemIDZ() const {
410     return WorkItemIDZ;
411   }
412 
413   bool hasImplicitArgPtr() const {
414     return ImplicitArgPtr;
415   }
416 
417   bool hasImplicitBufferPtr() const {
418     return ImplicitBufferPtr;
419   }
420 
421   AMDGPUFunctionArgInfo &getArgInfo() {
422     return ArgInfo;
423   }
424 
425   const AMDGPUFunctionArgInfo &getArgInfo() const {
426     return ArgInfo;
427   }
428 
429   std::pair<const ArgDescriptor *, const TargetRegisterClass *>
430   getPreloadedValue(AMDGPUFunctionArgInfo::PreloadedValue Value) const {
431     return ArgInfo.getPreloadedValue(Value);
432   }
433 
434   unsigned getPreloadedReg(AMDGPUFunctionArgInfo::PreloadedValue Value) const {
435     return ArgInfo.getPreloadedValue(Value).first->getRegister();
436   }
437 
438   unsigned getGITPtrHigh() const {
439     return GITPtrHigh;
440   }
441 
442   unsigned get32BitAddressHighBits() const {
443     return HighBitsOf32BitAddress;
444   }
445 
446   unsigned getNumUserSGPRs() const {
447     return NumUserSGPRs;
448   }
449 
450   unsigned getNumPreloadedSGPRs() const {
451     return NumUserSGPRs + NumSystemSGPRs;
452   }
453 
454   unsigned getPrivateSegmentWaveByteOffsetSystemSGPR() const {
455     return ArgInfo.PrivateSegmentWaveByteOffset.getRegister();
456   }
457 
458   /// Returns the physical register reserved for use as the resource
459   /// descriptor for scratch accesses.
460   unsigned getScratchRSrcReg() const {
461     return ScratchRSrcReg;
462   }
463 
464   void setScratchRSrcReg(unsigned Reg) {
465     assert(Reg != 0 && "Should never be unset");
466     ScratchRSrcReg = Reg;
467   }
468 
469   unsigned getScratchWaveOffsetReg() const {
470     return ScratchWaveOffsetReg;
471   }
472 
473   unsigned getFrameOffsetReg() const {
474     return FrameOffsetReg;
475   }
476 
477   void setStackPtrOffsetReg(unsigned Reg) {
478     assert(Reg != 0 && "Should never be unset");
479     StackPtrOffsetReg = Reg;
480   }
481 
482   // Note the unset value for this is AMDGPU::SP_REG rather than
483   // NoRegister. This is mostly a workaround for MIR tests where state that
484   // can't be directly computed from the function is not preserved in serialized
485   // MIR.
486   unsigned getStackPtrOffsetReg() const {
487     return StackPtrOffsetReg;
488   }
489 
490   void setScratchWaveOffsetReg(unsigned Reg) {
491     assert(Reg != 0 && "Should never be unset");
492     ScratchWaveOffsetReg = Reg;
493     if (isEntryFunction())
494       FrameOffsetReg = ScratchWaveOffsetReg;
495   }
496 
497   unsigned getQueuePtrUserSGPR() const {
498     return ArgInfo.QueuePtr.getRegister();
499   }
500 
501   unsigned getImplicitBufferPtrUserSGPR() const {
502     return ArgInfo.ImplicitBufferPtr.getRegister();
503   }
504 
505   bool hasSpilledSGPRs() const {
506     return HasSpilledSGPRs;
507   }
508 
509   void setHasSpilledSGPRs(bool Spill = true) {
510     HasSpilledSGPRs = Spill;
511   }
512 
513   bool hasSpilledVGPRs() const {
514     return HasSpilledVGPRs;
515   }
516 
517   void setHasSpilledVGPRs(bool Spill = true) {
518     HasSpilledVGPRs = Spill;
519   }
520 
521   bool hasNonSpillStackObjects() const {
522     return HasNonSpillStackObjects;
523   }
524 
525   void setHasNonSpillStackObjects(bool StackObject = true) {
526     HasNonSpillStackObjects = StackObject;
527   }
528 
529   bool isStackRealigned() const {
530     return IsStackRealigned;
531   }
532 
533   void setIsStackRealigned(bool Realigned = true) {
534     IsStackRealigned = Realigned;
535   }
536 
537   unsigned getNumSpilledSGPRs() const {
538     return NumSpilledSGPRs;
539   }
540 
541   unsigned getNumSpilledVGPRs() const {
542     return NumSpilledVGPRs;
543   }
544 
545   void addToSpilledSGPRs(unsigned num) {
546     NumSpilledSGPRs += num;
547   }
548 
549   void addToSpilledVGPRs(unsigned num) {
550     NumSpilledVGPRs += num;
551   }
552 
553   unsigned getPSInputAddr() const {
554     return PSInputAddr;
555   }
556 
557   unsigned getPSInputEnable() const {
558     return PSInputEnable;
559   }
560 
561   bool isPSInputAllocated(unsigned Index) const {
562     return PSInputAddr & (1 << Index);
563   }
564 
565   void markPSInputAllocated(unsigned Index) {
566     PSInputAddr |= 1 << Index;
567   }
568 
569   void markPSInputEnabled(unsigned Index) {
570     PSInputEnable |= 1 << Index;
571   }
572 
573   bool returnsVoid() const {
574     return ReturnsVoid;
575   }
576 
577   void setIfReturnsVoid(bool Value) {
578     ReturnsVoid = Value;
579   }
580 
581   /// \returns A pair of default/requested minimum/maximum flat work group sizes
582   /// for this function.
583   std::pair<unsigned, unsigned> getFlatWorkGroupSizes() const {
584     return FlatWorkGroupSizes;
585   }
586 
587   /// \returns Default/requested minimum flat work group size for this function.
588   unsigned getMinFlatWorkGroupSize() const {
589     return FlatWorkGroupSizes.first;
590   }
591 
592   /// \returns Default/requested maximum flat work group size for this function.
593   unsigned getMaxFlatWorkGroupSize() const {
594     return FlatWorkGroupSizes.second;
595   }
596 
597   /// \returns A pair of default/requested minimum/maximum number of waves per
598   /// execution unit.
599   std::pair<unsigned, unsigned> getWavesPerEU() const {
600     return WavesPerEU;
601   }
602 
603   /// \returns Default/requested minimum number of waves per execution unit.
604   unsigned getMinWavesPerEU() const {
605     return WavesPerEU.first;
606   }
607 
608   /// \returns Default/requested maximum number of waves per execution unit.
609   unsigned getMaxWavesPerEU() const {
610     return WavesPerEU.second;
611   }
612 
613   /// \returns SGPR used for \p Dim's work group ID.
614   unsigned getWorkGroupIDSGPR(unsigned Dim) const {
615     switch (Dim) {
616     case 0:
617       assert(hasWorkGroupIDX());
618       return ArgInfo.WorkGroupIDX.getRegister();
619     case 1:
620       assert(hasWorkGroupIDY());
621       return ArgInfo.WorkGroupIDY.getRegister();
622     case 2:
623       assert(hasWorkGroupIDZ());
624       return ArgInfo.WorkGroupIDZ.getRegister();
625     }
626     llvm_unreachable("unexpected dimension");
627   }
628 
629   /// \returns VGPR used for \p Dim' work item ID.
630   unsigned getWorkItemIDVGPR(unsigned Dim) const;
631 
632   unsigned getLDSWaveSpillSize() const {
633     return LDSWaveSpillSize;
634   }
635 
636   const AMDGPUBufferPseudoSourceValue *getBufferPSV(const SIInstrInfo &TII,
637                                                     const Value *BufferRsrc) {
638     assert(BufferRsrc);
639     auto PSV = BufferPSVs.try_emplace(
640       BufferRsrc,
641       llvm::make_unique<AMDGPUBufferPseudoSourceValue>(TII));
642     return PSV.first->second.get();
643   }
644 
645   const AMDGPUImagePseudoSourceValue *getImagePSV(const SIInstrInfo &TII,
646                                                   const Value *ImgRsrc) {
647     assert(ImgRsrc);
648     auto PSV = ImagePSVs.try_emplace(
649       ImgRsrc,
650       llvm::make_unique<AMDGPUImagePseudoSourceValue>(TII));
651     return PSV.first->second.get();
652   }
653 
654   unsigned getOccupancy() const {
655     return Occupancy;
656   }
657 
658   unsigned getMinAllowedOccupancy() const {
659     if (!isMemoryBound() && !needsWaveLimiter())
660       return Occupancy;
661     return (Occupancy < 4) ? Occupancy : 4;
662   }
663 
664   void limitOccupancy(const MachineFunction &MF);
665 
666   void limitOccupancy(unsigned Limit) {
667     if (Occupancy > Limit)
668       Occupancy = Limit;
669   }
670 
671   void increaseOccupancy(const MachineFunction &MF, unsigned Limit) {
672     if (Occupancy < Limit)
673       Occupancy = Limit;
674     limitOccupancy(MF);
675   }
676 };
677 
678 } // end namespace llvm
679 
680 #endif // LLVM_LIB_TARGET_AMDGPU_SIMACHINEFUNCTIONINFO_H
681