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