Home | History | Annotate | Line # | Download | only in AMDGPU
      1 //===-- SIRegisterInfo.h - SI Register Info 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 /// Interface definition for SIRegisterInfo
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_LIB_TARGET_AMDGPU_SIREGISTERINFO_H
     15 #define LLVM_LIB_TARGET_AMDGPU_SIREGISTERINFO_H
     16 
     17 #define GET_REGINFO_HEADER
     18 #include "AMDGPUGenRegisterInfo.inc"
     19 
     20 namespace llvm {
     21 
     22 class GCNSubtarget;
     23 class LiveIntervals;
     24 class LivePhysRegs;
     25 class RegisterBank;
     26 struct SGPRSpillBuilder;
     27 class SIMachineFunctionInfo;
     28 
     29 class SIRegisterInfo final : public AMDGPUGenRegisterInfo {
     30 private:
     31   const GCNSubtarget &ST;
     32   bool SpillSGPRToVGPR;
     33   bool isWave32;
     34   BitVector RegPressureIgnoredUnits;
     35 
     36   /// Sub reg indexes for getRegSplitParts.
     37   /// First index represents subreg size from 1 to 16 DWORDs.
     38   /// The inner vector is sorted by bit offset.
     39   /// Provided a register can be fully split with given subregs,
     40   /// all elements of the inner vector combined give a full lane mask.
     41   static std::array<std::vector<int16_t>, 16> RegSplitParts;
     42 
     43   // Table representing sub reg of given width and offset.
     44   // First index is subreg size: 32, 64, 96, 128, 160, 192, 224, 256, 512.
     45   // Second index is 32 different dword offsets.
     46   static std::array<std::array<uint16_t, 32>, 9> SubRegFromChannelTable;
     47 
     48   void reserveRegisterTuples(BitVector &, MCRegister Reg) const;
     49 
     50 public:
     51   SIRegisterInfo(const GCNSubtarget &ST);
     52 
     53   /// \returns the sub reg enum value for the given \p Channel
     54   /// (e.g. getSubRegFromChannel(0) -> AMDGPU::sub0)
     55   static unsigned getSubRegFromChannel(unsigned Channel, unsigned NumRegs = 1);
     56 
     57   bool spillSGPRToVGPR() const {
     58     return SpillSGPRToVGPR;
     59   }
     60 
     61   /// Return the end register initially reserved for the scratch buffer in case
     62   /// spilling is needed.
     63   MCRegister reservedPrivateSegmentBufferReg(const MachineFunction &MF) const;
     64 
     65   BitVector getReservedRegs(const MachineFunction &MF) const override;
     66 
     67   const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;
     68   const MCPhysReg *getCalleeSavedRegsViaCopy(const MachineFunction *MF) const;
     69   const uint32_t *getCallPreservedMask(const MachineFunction &MF,
     70                                        CallingConv::ID) const override;
     71   const uint32_t *getNoPreservedMask() const override;
     72 
     73   // Stack access is very expensive. CSRs are also the high registers, and we
     74   // want to minimize the number of used registers.
     75   unsigned getCSRFirstUseCost() const override {
     76     return 100;
     77   }
     78 
     79   Register getFrameRegister(const MachineFunction &MF) const override;
     80 
     81   bool hasBasePointer(const MachineFunction &MF) const;
     82   Register getBaseRegister() const;
     83 
     84   bool shouldRealignStack(const MachineFunction &MF) const override;
     85   bool requiresRegisterScavenging(const MachineFunction &Fn) const override;
     86 
     87   bool requiresFrameIndexScavenging(const MachineFunction &MF) const override;
     88   bool requiresFrameIndexReplacementScavenging(
     89     const MachineFunction &MF) const override;
     90   bool requiresVirtualBaseRegisters(const MachineFunction &Fn) const override;
     91 
     92   int64_t getScratchInstrOffset(const MachineInstr *MI) const;
     93 
     94   int64_t getFrameIndexInstrOffset(const MachineInstr *MI,
     95                                    int Idx) const override;
     96 
     97   bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override;
     98 
     99   Register materializeFrameBaseRegister(MachineBasicBlock *MBB, int FrameIdx,
    100                                         int64_t Offset) const override;
    101 
    102   void resolveFrameIndex(MachineInstr &MI, Register BaseReg,
    103                          int64_t Offset) const override;
    104 
    105   bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg,
    106                           int64_t Offset) const override;
    107 
    108   const TargetRegisterClass *getPointerRegClass(
    109     const MachineFunction &MF, unsigned Kind = 0) const override;
    110 
    111   void buildVGPRSpillLoadStore(SGPRSpillBuilder &SB, int Index, int Offset,
    112                                bool IsLoad, bool IsKill = true) const;
    113 
    114   void buildSGPRSpillLoadStore(SGPRSpillBuilder &SB, int Offset,
    115                                int64_t VGPRLanes) const;
    116 
    117   /// If \p OnlyToVGPR is true, this will only succeed if this
    118   bool spillSGPR(MachineBasicBlock::iterator MI,
    119                  int FI, RegScavenger *RS,
    120                  bool OnlyToVGPR = false) const;
    121 
    122   bool restoreSGPR(MachineBasicBlock::iterator MI,
    123                    int FI, RegScavenger *RS,
    124                    bool OnlyToVGPR = false) const;
    125 
    126   void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj,
    127                            unsigned FIOperandNum,
    128                            RegScavenger *RS) const override;
    129 
    130   bool eliminateSGPRToVGPRSpillFrameIndex(MachineBasicBlock::iterator MI,
    131                                           int FI, RegScavenger *RS) const;
    132 
    133   StringRef getRegAsmName(MCRegister Reg) const override;
    134 
    135   // Pseudo regs are not allowed
    136   unsigned getHWRegIndex(MCRegister Reg) const {
    137     return getEncodingValue(Reg) & 0xff;
    138   }
    139 
    140   LLVM_READONLY
    141   const TargetRegisterClass *getVGPRClassForBitWidth(unsigned BitWidth) const;
    142 
    143   LLVM_READONLY
    144   const TargetRegisterClass *getAGPRClassForBitWidth(unsigned BitWidth) const;
    145 
    146   LLVM_READONLY
    147   static const TargetRegisterClass *getSGPRClassForBitWidth(unsigned BitWidth);
    148 
    149   /// Return the 'base' register class for this register.
    150   /// e.g. SGPR0 => SReg_32, VGPR => VGPR_32 SGPR0_SGPR1 -> SReg_32, etc.
    151   const TargetRegisterClass *getPhysRegClass(MCRegister Reg) const;
    152 
    153   /// \returns true if this class contains only SGPR registers
    154   bool isSGPRClass(const TargetRegisterClass *RC) const {
    155     return !hasVGPRs(RC) && !hasAGPRs(RC);
    156   }
    157 
    158   /// \returns true if this class ID contains only SGPR registers
    159   bool isSGPRClassID(unsigned RCID) const {
    160     return isSGPRClass(getRegClass(RCID));
    161   }
    162 
    163   bool isSGPRReg(const MachineRegisterInfo &MRI, Register Reg) const;
    164 
    165   /// \returns true if this class contains only AGPR registers
    166   bool isAGPRClass(const TargetRegisterClass *RC) const {
    167     return hasAGPRs(RC) && !hasVGPRs(RC);
    168   }
    169 
    170   /// \returns true if this class contains VGPR registers.
    171   bool hasVGPRs(const TargetRegisterClass *RC) const;
    172 
    173   /// \returns true if this class contains AGPR registers.
    174   bool hasAGPRs(const TargetRegisterClass *RC) const;
    175 
    176   /// \returns true if this class contains any vector registers.
    177   bool hasVectorRegisters(const TargetRegisterClass *RC) const {
    178     return hasVGPRs(RC) || hasAGPRs(RC);
    179   }
    180 
    181   /// \returns A VGPR reg class with the same width as \p SRC
    182   const TargetRegisterClass *
    183   getEquivalentVGPRClass(const TargetRegisterClass *SRC) const;
    184 
    185   /// \returns An AGPR reg class with the same width as \p SRC
    186   const TargetRegisterClass *
    187   getEquivalentAGPRClass(const TargetRegisterClass *SRC) const;
    188 
    189   /// \returns A SGPR reg class with the same width as \p SRC
    190   const TargetRegisterClass *
    191   getEquivalentSGPRClass(const TargetRegisterClass *VRC) const;
    192 
    193   /// \returns The canonical register class that is used for a sub-register of
    194   /// \p RC for the given \p SubIdx.  If \p SubIdx equals NoSubRegister, \p RC
    195   /// will be returned.
    196   const TargetRegisterClass *getSubRegClass(const TargetRegisterClass *RC,
    197                                             unsigned SubIdx) const;
    198 
    199   /// Returns a register class which is compatible with \p SuperRC, such that a
    200   /// subregister exists with class \p SubRC with subregister index \p
    201   /// SubIdx. If this is impossible (e.g., an unaligned subregister index within
    202   /// a register tuple), return null.
    203   const TargetRegisterClass *
    204   getCompatibleSubRegClass(const TargetRegisterClass *SuperRC,
    205                            const TargetRegisterClass *SubRC,
    206                            unsigned SubIdx) const;
    207 
    208   bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC,
    209                             unsigned DefSubReg,
    210                             const TargetRegisterClass *SrcRC,
    211                             unsigned SrcSubReg) const override;
    212 
    213   /// \returns True if operands defined with this operand type can accept
    214   /// a literal constant (i.e. any 32-bit immediate).
    215   bool opCanUseLiteralConstant(unsigned OpType) const;
    216 
    217   /// \returns True if operands defined with this operand type can accept
    218   /// an inline constant. i.e. An integer value in the range (-16, 64) or
    219   /// -4.0f, -2.0f, -1.0f, -0.5f, 0.0f, 0.5f, 1.0f, 2.0f, 4.0f.
    220   bool opCanUseInlineConstant(unsigned OpType) const;
    221 
    222   MCRegister findUnusedRegister(const MachineRegisterInfo &MRI,
    223                                 const TargetRegisterClass *RC,
    224                                 const MachineFunction &MF,
    225                                 bool ReserveHighestVGPR = false) const;
    226 
    227   const TargetRegisterClass *getRegClassForReg(const MachineRegisterInfo &MRI,
    228                                                Register Reg) const;
    229   bool isVGPR(const MachineRegisterInfo &MRI, Register Reg) const;
    230   bool isAGPR(const MachineRegisterInfo &MRI, Register Reg) const;
    231   bool isVectorRegister(const MachineRegisterInfo &MRI, Register Reg) const {
    232     return isVGPR(MRI, Reg) || isAGPR(MRI, Reg);
    233   }
    234 
    235   bool isConstantPhysReg(MCRegister PhysReg) const override;
    236 
    237   bool isDivergentRegClass(const TargetRegisterClass *RC) const override {
    238     return !isSGPRClass(RC);
    239   }
    240 
    241   ArrayRef<int16_t> getRegSplitParts(const TargetRegisterClass *RC,
    242                                      unsigned EltSize) const;
    243 
    244   bool shouldCoalesce(MachineInstr *MI,
    245                       const TargetRegisterClass *SrcRC,
    246                       unsigned SubReg,
    247                       const TargetRegisterClass *DstRC,
    248                       unsigned DstSubReg,
    249                       const TargetRegisterClass *NewRC,
    250                       LiveIntervals &LIS) const override;
    251 
    252   unsigned getRegPressureLimit(const TargetRegisterClass *RC,
    253                                MachineFunction &MF) const override;
    254 
    255   unsigned getRegPressureSetLimit(const MachineFunction &MF,
    256                                   unsigned Idx) const override;
    257 
    258   const int *getRegUnitPressureSets(unsigned RegUnit) const override;
    259 
    260   MCRegister getReturnAddressReg(const MachineFunction &MF) const;
    261 
    262   const TargetRegisterClass *
    263   getRegClassForSizeOnBank(unsigned Size,
    264                            const RegisterBank &Bank,
    265                            const MachineRegisterInfo &MRI) const;
    266 
    267   const TargetRegisterClass *
    268   getRegClassForTypeOnBank(LLT Ty,
    269                            const RegisterBank &Bank,
    270                            const MachineRegisterInfo &MRI) const {
    271     return getRegClassForSizeOnBank(Ty.getSizeInBits(), Bank, MRI);
    272   }
    273 
    274   const TargetRegisterClass *
    275   getConstrainedRegClassForOperand(const MachineOperand &MO,
    276                                  const MachineRegisterInfo &MRI) const override;
    277 
    278   const TargetRegisterClass *getBoolRC() const {
    279     return isWave32 ? &AMDGPU::SReg_32RegClass
    280                     : &AMDGPU::SReg_64RegClass;
    281   }
    282 
    283   const TargetRegisterClass *getWaveMaskRegClass() const {
    284     return isWave32 ? &AMDGPU::SReg_32_XM0_XEXECRegClass
    285                     : &AMDGPU::SReg_64_XEXECRegClass;
    286   }
    287 
    288   // Return the appropriate register class to use for 64-bit VGPRs for the
    289   // subtarget.
    290   const TargetRegisterClass *getVGPR64Class() const;
    291 
    292   MCRegister getVCC() const;
    293 
    294   const TargetRegisterClass *getRegClass(unsigned RCID) const;
    295 
    296   // Find reaching register definition
    297   MachineInstr *findReachingDef(Register Reg, unsigned SubReg,
    298                                 MachineInstr &Use,
    299                                 MachineRegisterInfo &MRI,
    300                                 LiveIntervals *LIS) const;
    301 
    302   const uint32_t *getAllVGPRRegMask() const;
    303   const uint32_t *getAllAGPRRegMask() const;
    304   const uint32_t *getAllVectorRegMask() const;
    305   const uint32_t *getAllAllocatableSRegMask() const;
    306 
    307   // \returns number of 32 bit registers covered by a \p LM
    308   static unsigned getNumCoveredRegs(LaneBitmask LM) {
    309     // The assumption is that every lo16 subreg is an even bit and every hi16
    310     // is an adjacent odd bit or vice versa.
    311     uint64_t Mask = LM.getAsInteger();
    312     uint64_t Even = Mask & 0xAAAAAAAAAAAAAAAAULL;
    313     Mask = (Even >> 1) | Mask;
    314     uint64_t Odd = Mask & 0x5555555555555555ULL;
    315     return countPopulation(Odd);
    316   }
    317 
    318   // \returns a DWORD offset of a \p SubReg
    319   unsigned getChannelFromSubReg(unsigned SubReg) const {
    320     return SubReg ? (getSubRegIdxOffset(SubReg) + 31) / 32 : 0;
    321   }
    322 
    323   // \returns a DWORD size of a \p SubReg
    324   unsigned getNumChannelsFromSubReg(unsigned SubReg) const {
    325     return getNumCoveredRegs(getSubRegIndexLaneMask(SubReg));
    326   }
    327 
    328   // For a given 16 bit \p Reg \returns a 32 bit register holding it.
    329   // \returns \p Reg otherwise.
    330   MCPhysReg get32BitRegister(MCPhysReg Reg) const;
    331 
    332   // Returns true if a given register class is properly aligned for
    333   // the subtarget.
    334   bool isProperlyAlignedRC(const TargetRegisterClass &RC) const;
    335 
    336   /// Return all SGPR128 which satisfy the waves per execution unit requirement
    337   /// of the subtarget.
    338   ArrayRef<MCPhysReg> getAllSGPR128(const MachineFunction &MF) const;
    339 
    340   /// Return all SGPR64 which satisfy the waves per execution unit requirement
    341   /// of the subtarget.
    342   ArrayRef<MCPhysReg> getAllSGPR64(const MachineFunction &MF) const;
    343 
    344   /// Return all SGPR32 which satisfy the waves per execution unit requirement
    345   /// of the subtarget.
    346   ArrayRef<MCPhysReg> getAllSGPR32(const MachineFunction &MF) const;
    347 
    348   // Insert spill or restore instructions.
    349   // When lowering spill pseudos, the RegScavenger should be set.
    350   // For creating spill instructions during frame lowering, where no scavenger
    351   // is available, LiveRegs can be used.
    352   void buildSpillLoadStore(MachineBasicBlock &MBB,
    353                            MachineBasicBlock::iterator MI, unsigned LoadStoreOp,
    354                            int Index, Register ValueReg, bool ValueIsKill,
    355                            MCRegister ScratchOffsetReg, int64_t InstrOffset,
    356                            MachineMemOperand *MMO, RegScavenger *RS,
    357                            LivePhysRegs *LiveRegs = nullptr) const;
    358 };
    359 
    360 } // End namespace llvm
    361 
    362 #endif
    363