Home | History | Annotate | Download | only in AMDGPU
      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 "AMDGPUMachineFunction.h"
     18 #include "SIRegisterInfo.h"
     19 #include <array>
     20 #include <map>
     21 
     22 namespace llvm {
     23 
     24 class MachineRegisterInfo;
     25 
     26 /// This class keeps track of the SPI_SP_INPUT_ADDR config register, which
     27 /// tells the hardware which interpolation parameters to load.
     28 class SIMachineFunctionInfo final : public AMDGPUMachineFunction {
     29   // FIXME: This should be removed and getPreloadedValue moved here.
     30   friend struct SIRegisterInfo;
     31   void anchor() override;
     32 
     33   unsigned TIDReg;
     34 
     35   // Registers that may be reserved for spilling purposes. These may be the same
     36   // as the input registers.
     37   unsigned ScratchRSrcReg;
     38   unsigned ScratchWaveOffsetReg;
     39 
     40   // Input registers setup for the HSA ABI.
     41   // User SGPRs in allocation order.
     42   unsigned PrivateSegmentBufferUserSGPR;
     43   unsigned DispatchPtrUserSGPR;
     44   unsigned QueuePtrUserSGPR;
     45   unsigned KernargSegmentPtrUserSGPR;
     46   unsigned DispatchIDUserSGPR;
     47   unsigned FlatScratchInitUserSGPR;
     48   unsigned PrivateSegmentSizeUserSGPR;
     49   unsigned GridWorkGroupCountXUserSGPR;
     50   unsigned GridWorkGroupCountYUserSGPR;
     51   unsigned GridWorkGroupCountZUserSGPR;
     52 
     53   // System SGPRs in allocation order.
     54   unsigned WorkGroupIDXSystemSGPR;
     55   unsigned WorkGroupIDYSystemSGPR;
     56   unsigned WorkGroupIDZSystemSGPR;
     57   unsigned WorkGroupInfoSystemSGPR;
     58   unsigned PrivateSegmentWaveByteOffsetSystemSGPR;
     59 
     60   // Graphics info.
     61   unsigned PSInputAddr;
     62   bool ReturnsVoid;
     63 
     64   unsigned MaximumWorkGroupSize;
     65 
     66   // Number of reserved VGPRs for debugger usage.
     67   unsigned DebuggerReservedVGPRCount;
     68   // Stack object indices for work group IDs.
     69   std::array<int, 3> DebuggerWorkGroupIDStackObjectIndices;
     70   // Stack object indices for work item IDs.
     71   std::array<int, 3> DebuggerWorkItemIDStackObjectIndices;
     72 
     73 public:
     74   // FIXME: Make private
     75   unsigned LDSWaveSpillSize;
     76   unsigned PSInputEna;
     77   std::map<unsigned, unsigned> LaneVGPRs;
     78   unsigned ScratchOffsetReg;
     79   unsigned NumUserSGPRs;
     80   unsigned NumSystemSGPRs;
     81 
     82 private:
     83   bool HasSpilledSGPRs;
     84   bool HasSpilledVGPRs;
     85   bool HasNonSpillStackObjects;
     86   bool HasFlatInstructions;
     87 
     88   unsigned NumSpilledSGPRs;
     89   unsigned NumSpilledVGPRs;
     90 
     91   // Feature bits required for inputs passed in user SGPRs.
     92   bool PrivateSegmentBuffer : 1;
     93   bool DispatchPtr : 1;
     94   bool QueuePtr : 1;
     95   bool DispatchID : 1;
     96   bool KernargSegmentPtr : 1;
     97   bool FlatScratchInit : 1;
     98   bool GridWorkgroupCountX : 1;
     99   bool GridWorkgroupCountY : 1;
    100   bool GridWorkgroupCountZ : 1;
    101 
    102   // Feature bits required for inputs passed in system SGPRs.
    103   bool WorkGroupIDX : 1; // Always initialized.
    104   bool WorkGroupIDY : 1;
    105   bool WorkGroupIDZ : 1;
    106   bool WorkGroupInfo : 1;
    107   bool PrivateSegmentWaveByteOffset : 1;
    108 
    109   bool WorkItemIDX : 1; // Always initialized.
    110   bool WorkItemIDY : 1;
    111   bool WorkItemIDZ : 1;
    112 
    113   MCPhysReg getNextUserSGPR() const {
    114     assert(NumSystemSGPRs == 0 && "System SGPRs must be added after user SGPRs");
    115     return AMDGPU::SGPR0 + NumUserSGPRs;
    116   }
    117 
    118   MCPhysReg getNextSystemSGPR() const {
    119     return AMDGPU::SGPR0 + NumUserSGPRs + NumSystemSGPRs;
    120   }
    121 
    122 public:
    123   struct SpilledReg {
    124     unsigned VGPR;
    125     int Lane;
    126     SpilledReg(unsigned R, int L) : VGPR (R), Lane (L) { }
    127     SpilledReg() : VGPR(AMDGPU::NoRegister), Lane(-1) { }
    128     bool hasLane() { return Lane != -1;}
    129     bool hasReg() { return VGPR != AMDGPU::NoRegister;}
    130   };
    131 
    132   // SIMachineFunctionInfo definition
    133 
    134   SIMachineFunctionInfo(const MachineFunction &MF);
    135   SpilledReg getSpilledReg(MachineFunction *MF, unsigned FrameIndex,
    136                            unsigned SubIdx);
    137   bool hasCalculatedTID() const { return TIDReg != AMDGPU::NoRegister; };
    138   unsigned getTIDReg() const { return TIDReg; };
    139   void setTIDReg(unsigned Reg) { TIDReg = Reg; }
    140 
    141   // Add user SGPRs.
    142   unsigned addPrivateSegmentBuffer(const SIRegisterInfo &TRI);
    143   unsigned addDispatchPtr(const SIRegisterInfo &TRI);
    144   unsigned addQueuePtr(const SIRegisterInfo &TRI);
    145   unsigned addKernargSegmentPtr(const SIRegisterInfo &TRI);
    146   unsigned addFlatScratchInit(const SIRegisterInfo &TRI);
    147 
    148   // Add system SGPRs.
    149   unsigned addWorkGroupIDX() {
    150     WorkGroupIDXSystemSGPR = getNextSystemSGPR();
    151     NumSystemSGPRs += 1;
    152     return WorkGroupIDXSystemSGPR;
    153   }
    154 
    155   unsigned addWorkGroupIDY() {
    156     WorkGroupIDYSystemSGPR = getNextSystemSGPR();
    157     NumSystemSGPRs += 1;
    158     return WorkGroupIDYSystemSGPR;
    159   }
    160 
    161   unsigned addWorkGroupIDZ() {
    162     WorkGroupIDZSystemSGPR = getNextSystemSGPR();
    163     NumSystemSGPRs += 1;
    164     return WorkGroupIDZSystemSGPR;
    165   }
    166 
    167   unsigned addWorkGroupInfo() {
    168     WorkGroupInfoSystemSGPR = getNextSystemSGPR();
    169     NumSystemSGPRs += 1;
    170     return WorkGroupInfoSystemSGPR;
    171   }
    172 
    173   unsigned addPrivateSegmentWaveByteOffset() {
    174     PrivateSegmentWaveByteOffsetSystemSGPR = getNextSystemSGPR();
    175     NumSystemSGPRs += 1;
    176     return PrivateSegmentWaveByteOffsetSystemSGPR;
    177   }
    178 
    179   void setPrivateSegmentWaveByteOffset(unsigned Reg) {
    180     PrivateSegmentWaveByteOffsetSystemSGPR = Reg;
    181   }
    182 
    183   bool hasPrivateSegmentBuffer() const {
    184     return PrivateSegmentBuffer;
    185   }
    186 
    187   bool hasDispatchPtr() const {
    188     return DispatchPtr;
    189   }
    190 
    191   bool hasQueuePtr() const {
    192     return QueuePtr;
    193   }
    194 
    195   bool hasDispatchID() const {
    196     return DispatchID;
    197   }
    198 
    199   bool hasKernargSegmentPtr() const {
    200     return KernargSegmentPtr;
    201   }
    202 
    203   bool hasFlatScratchInit() const {
    204     return FlatScratchInit;
    205   }
    206 
    207   bool hasGridWorkgroupCountX() const {
    208     return GridWorkgroupCountX;
    209   }
    210 
    211   bool hasGridWorkgroupCountY() const {
    212     return GridWorkgroupCountY;
    213   }
    214 
    215   bool hasGridWorkgroupCountZ() const {
    216     return GridWorkgroupCountZ;
    217   }
    218 
    219   bool hasWorkGroupIDX() const {
    220     return WorkGroupIDX;
    221   }
    222 
    223   bool hasWorkGroupIDY() const {
    224     return WorkGroupIDY;
    225   }
    226 
    227   bool hasWorkGroupIDZ() const {
    228     return WorkGroupIDZ;
    229   }
    230 
    231   bool hasWorkGroupInfo() const {
    232     return WorkGroupInfo;
    233   }
    234 
    235   bool hasPrivateSegmentWaveByteOffset() const {
    236     return PrivateSegmentWaveByteOffset;
    237   }
    238 
    239   bool hasWorkItemIDX() const {
    240     return WorkItemIDX;
    241   }
    242 
    243   bool hasWorkItemIDY() const {
    244     return WorkItemIDY;
    245   }
    246 
    247   bool hasWorkItemIDZ() const {
    248     return WorkItemIDZ;
    249   }
    250 
    251   unsigned getNumUserSGPRs() const {
    252     return NumUserSGPRs;
    253   }
    254 
    255   unsigned getNumPreloadedSGPRs() const {
    256     return NumUserSGPRs + NumSystemSGPRs;
    257   }
    258 
    259   unsigned getPrivateSegmentWaveByteOffsetSystemSGPR() const {
    260     return PrivateSegmentWaveByteOffsetSystemSGPR;
    261   }
    262 
    263   /// \brief Returns the physical register reserved for use as the resource
    264   /// descriptor for scratch accesses.
    265   unsigned getScratchRSrcReg() const {
    266     return ScratchRSrcReg;
    267   }
    268 
    269   void setScratchRSrcReg(unsigned Reg) {
    270     assert(Reg != AMDGPU::NoRegister && "Should never be unset");
    271     ScratchRSrcReg = Reg;
    272   }
    273 
    274   unsigned getScratchWaveOffsetReg() const {
    275     return ScratchWaveOffsetReg;
    276   }
    277 
    278   void setScratchWaveOffsetReg(unsigned Reg) {
    279     assert(Reg != AMDGPU::NoRegister && "Should never be unset");
    280     ScratchWaveOffsetReg = Reg;
    281   }
    282 
    283   unsigned getQueuePtrUserSGPR() const {
    284     return QueuePtrUserSGPR;
    285   }
    286 
    287   bool hasSpilledSGPRs() const {
    288     return HasSpilledSGPRs;
    289   }
    290 
    291   void setHasSpilledSGPRs(bool Spill = true) {
    292     HasSpilledSGPRs = Spill;
    293   }
    294 
    295   bool hasSpilledVGPRs() const {
    296     return HasSpilledVGPRs;
    297   }
    298 
    299   void setHasSpilledVGPRs(bool Spill = true) {
    300     HasSpilledVGPRs = Spill;
    301   }
    302 
    303   bool hasNonSpillStackObjects() const {
    304     return HasNonSpillStackObjects;
    305   }
    306 
    307   void setHasNonSpillStackObjects(bool StackObject = true) {
    308     HasNonSpillStackObjects = StackObject;
    309   }
    310 
    311   bool hasFlatInstructions() const {
    312     return HasFlatInstructions;
    313   }
    314 
    315   void setHasFlatInstructions(bool UseFlat = true) {
    316     HasFlatInstructions = UseFlat;
    317   }
    318 
    319   unsigned getNumSpilledSGPRs() const {
    320     return NumSpilledSGPRs;
    321   }
    322 
    323   unsigned getNumSpilledVGPRs() const {
    324     return NumSpilledVGPRs;
    325   }
    326 
    327   void addToSpilledSGPRs(unsigned num) {
    328     NumSpilledSGPRs += num;
    329   }
    330 
    331   void addToSpilledVGPRs(unsigned num) {
    332     NumSpilledVGPRs += num;
    333   }
    334 
    335   unsigned getPSInputAddr() const {
    336     return PSInputAddr;
    337   }
    338 
    339   bool isPSInputAllocated(unsigned Index) const {
    340     return PSInputAddr & (1 << Index);
    341   }
    342 
    343   void markPSInputAllocated(unsigned Index) {
    344     PSInputAddr |= 1 << Index;
    345   }
    346 
    347   bool returnsVoid() const {
    348     return ReturnsVoid;
    349   }
    350 
    351   void setIfReturnsVoid(bool Value) {
    352     ReturnsVoid = Value;
    353   }
    354 
    355   /// \returns Number of reserved VGPRs for debugger usage.
    356   unsigned getDebuggerReservedVGPRCount() const {
    357     return DebuggerReservedVGPRCount;
    358   }
    359 
    360   /// \returns Stack object index for \p Dim's work group ID.
    361   int getDebuggerWorkGroupIDStackObjectIndex(unsigned Dim) const {
    362     assert(Dim < 3);
    363     return DebuggerWorkGroupIDStackObjectIndices[Dim];
    364   }
    365 
    366   /// \brief Sets stack object index for \p Dim's work group ID to \p ObjectIdx.
    367   void setDebuggerWorkGroupIDStackObjectIndex(unsigned Dim, int ObjectIdx) {
    368     assert(Dim < 3);
    369     DebuggerWorkGroupIDStackObjectIndices[Dim] = ObjectIdx;
    370   }
    371 
    372   /// \returns Stack object index for \p Dim's work item ID.
    373   int getDebuggerWorkItemIDStackObjectIndex(unsigned Dim) const {
    374     assert(Dim < 3);
    375     return DebuggerWorkItemIDStackObjectIndices[Dim];
    376   }
    377 
    378   /// \brief Sets stack object index for \p Dim's work item ID to \p ObjectIdx.
    379   void setDebuggerWorkItemIDStackObjectIndex(unsigned Dim, int ObjectIdx) {
    380     assert(Dim < 3);
    381     DebuggerWorkItemIDStackObjectIndices[Dim] = ObjectIdx;
    382   }
    383 
    384   /// \returns SGPR used for \p Dim's work group ID.
    385   unsigned getWorkGroupIDSGPR(unsigned Dim) const {
    386     switch (Dim) {
    387     case 0:
    388       assert(hasWorkGroupIDX());
    389       return WorkGroupIDXSystemSGPR;
    390     case 1:
    391       assert(hasWorkGroupIDY());
    392       return WorkGroupIDYSystemSGPR;
    393     case 2:
    394       assert(hasWorkGroupIDZ());
    395       return WorkGroupIDZSystemSGPR;
    396     }
    397     llvm_unreachable("unexpected dimension");
    398   }
    399 
    400   /// \returns VGPR used for \p Dim' work item ID.
    401   unsigned getWorkItemIDVGPR(unsigned Dim) const {
    402     switch (Dim) {
    403     case 0:
    404       assert(hasWorkItemIDX());
    405       return AMDGPU::VGPR0;
    406     case 1:
    407       assert(hasWorkItemIDY());
    408       return AMDGPU::VGPR1;
    409     case 2:
    410       assert(hasWorkItemIDZ());
    411       return AMDGPU::VGPR2;
    412     }
    413     llvm_unreachable("unexpected dimension");
    414   }
    415 
    416   unsigned getMaximumWorkGroupSize(const MachineFunction &MF) const;
    417 };
    418 
    419 } // End namespace llvm
    420 
    421 #endif
    422