Home | History | Annotate | Download | only in AMDGPU
      1 //===-- SIRegisterInfo.h - SI Register Info 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 /// Interface definition for SIRegisterInfo
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_LIB_TARGET_AMDGPU_SIREGISTERINFO_H
     16 #define LLVM_LIB_TARGET_AMDGPU_SIREGISTERINFO_H
     17 
     18 #include "AMDGPURegisterInfo.h"
     19 #include "SIDefines.h"
     20 #include "llvm/CodeGen/MachineRegisterInfo.h"
     21 
     22 namespace llvm {
     23 
     24 class GCNSubtarget;
     25 class LiveIntervals;
     26 class MachineRegisterInfo;
     27 class SIMachineFunctionInfo;
     28 
     29 class SIRegisterInfo final : public AMDGPURegisterInfo {
     30 private:
     31   unsigned SGPRSetID;
     32   unsigned VGPRSetID;
     33   BitVector SGPRPressureSets;
     34   BitVector VGPRPressureSets;
     35   bool SpillSGPRToVGPR;
     36   bool SpillSGPRToSMEM;
     37 
     38   void classifyPressureSet(unsigned PSetID, unsigned Reg,
     39                            BitVector &PressureSets) const;
     40 public:
     41   SIRegisterInfo(const GCNSubtarget &ST);
     42 
     43   bool spillSGPRToVGPR() const {
     44     return SpillSGPRToVGPR;
     45   }
     46 
     47   bool spillSGPRToSMEM() const {
     48     return SpillSGPRToSMEM;
     49   }
     50 
     51   /// Return the end register initially reserved for the scratch buffer in case
     52   /// spilling is needed.
     53   unsigned reservedPrivateSegmentBufferReg(const MachineFunction &MF) const;
     54 
     55   /// Return the end register initially reserved for the scratch wave offset in
     56   /// case spilling is needed.
     57   unsigned reservedPrivateSegmentWaveByteOffsetReg(
     58     const MachineFunction &MF) const;
     59 
     60   unsigned reservedStackPtrOffsetReg(const MachineFunction &MF) const;
     61 
     62   BitVector getReservedRegs(const MachineFunction &MF) const override;
     63 
     64   const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;
     65   const MCPhysReg *getCalleeSavedRegsViaCopy(const MachineFunction *MF) const;
     66   const uint32_t *getCallPreservedMask(const MachineFunction &MF,
     67                                        CallingConv::ID) const override;
     68 
     69   // Stack access is very expensive. CSRs are also the high registers, and we
     70   // want to minimize the number of used registers.
     71   unsigned getCSRFirstUseCost() const override {
     72     return 100;
     73   }
     74 
     75   unsigned getFrameRegister(const MachineFunction &MF) const override;
     76 
     77   bool requiresRegisterScavenging(const MachineFunction &Fn) const override;
     78 
     79   bool requiresFrameIndexScavenging(const MachineFunction &MF) const override;
     80   bool requiresFrameIndexReplacementScavenging(
     81     const MachineFunction &MF) const override;
     82   bool requiresVirtualBaseRegisters(const MachineFunction &Fn) const override;
     83   bool trackLivenessAfterRegAlloc(const MachineFunction &MF) const override;
     84 
     85   int64_t getMUBUFInstrOffset(const MachineInstr *MI) const;
     86 
     87   int64_t getFrameIndexInstrOffset(const MachineInstr *MI,
     88                                    int Idx) const override;
     89 
     90   bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override;
     91 
     92   void materializeFrameBaseRegister(MachineBasicBlock *MBB,
     93                                     unsigned BaseReg, int FrameIdx,
     94                                     int64_t Offset) const override;
     95 
     96   void resolveFrameIndex(MachineInstr &MI, unsigned BaseReg,
     97                          int64_t Offset) const override;
     98 
     99   bool isFrameOffsetLegal(const MachineInstr *MI, unsigned BaseReg,
    100                           int64_t Offset) const override;
    101 
    102   const TargetRegisterClass *getPointerRegClass(
    103     const MachineFunction &MF, unsigned Kind = 0) const override;
    104 
    105   /// If \p OnlyToVGPR is true, this will only succeed if this
    106   bool spillSGPR(MachineBasicBlock::iterator MI,
    107                  int FI, RegScavenger *RS,
    108                  bool OnlyToVGPR = false) const;
    109 
    110   bool restoreSGPR(MachineBasicBlock::iterator MI,
    111                    int FI, RegScavenger *RS,
    112                    bool OnlyToVGPR = false) const;
    113 
    114   void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj,
    115                            unsigned FIOperandNum,
    116                            RegScavenger *RS) const override;
    117 
    118   bool eliminateSGPRToVGPRSpillFrameIndex(MachineBasicBlock::iterator MI,
    119                                           int FI, RegScavenger *RS) const;
    120 
    121   StringRef getRegAsmName(unsigned Reg) const override;
    122 
    123   unsigned getHWRegIndex(unsigned Reg) const {
    124     return getEncodingValue(Reg) & 0xff;
    125   }
    126 
    127   /// Return the 'base' register class for this register.
    128   /// e.g. SGPR0 => SReg_32, VGPR => VGPR_32 SGPR0_SGPR1 -> SReg_32, etc.
    129   const TargetRegisterClass *getPhysRegClass(unsigned Reg) const;
    130 
    131   /// \returns true if this class contains only SGPR registers
    132   bool isSGPRClass(const TargetRegisterClass *RC) const {
    133     return !hasVGPRs(RC);
    134   }
    135 
    136   /// \returns true if this class ID contains only SGPR registers
    137   bool isSGPRClassID(unsigned RCID) const {
    138     return isSGPRClass(getRegClass(RCID));
    139   }
    140 
    141   bool isSGPRReg(const MachineRegisterInfo &MRI, unsigned Reg) const {
    142     const TargetRegisterClass *RC;
    143     if (TargetRegisterInfo::isVirtualRegister(Reg))
    144       RC = MRI.getRegClass(Reg);
    145     else
    146       RC = getPhysRegClass(Reg);
    147     return isSGPRClass(RC);
    148   }
    149 
    150   /// \returns true if this class contains VGPR registers.
    151   bool hasVGPRs(const TargetRegisterClass *RC) const;
    152 
    153   /// \returns A VGPR reg class with the same width as \p SRC
    154   const TargetRegisterClass *getEquivalentVGPRClass(
    155                                           const TargetRegisterClass *SRC) const;
    156 
    157   /// \returns A SGPR reg class with the same width as \p SRC
    158   const TargetRegisterClass *getEquivalentSGPRClass(
    159                                            const TargetRegisterClass *VRC) const;
    160 
    161   /// \returns The register class that is used for a sub-register of \p RC for
    162   /// the given \p SubIdx.  If \p SubIdx equals NoSubRegister, \p RC will
    163   /// be returned.
    164   const TargetRegisterClass *getSubRegClass(const TargetRegisterClass *RC,
    165                                             unsigned SubIdx) const;
    166 
    167   bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC,
    168                             unsigned DefSubReg,
    169                             const TargetRegisterClass *SrcRC,
    170                             unsigned SrcSubReg) const override;
    171 
    172   /// \returns True if operands defined with this operand type can accept
    173   /// a literal constant (i.e. any 32-bit immediate).
    174   bool opCanUseLiteralConstant(unsigned OpType) const {
    175     // TODO: 64-bit operands have extending behavior from 32-bit literal.
    176     return OpType >= AMDGPU::OPERAND_REG_IMM_FIRST &&
    177            OpType <= AMDGPU::OPERAND_REG_IMM_LAST;
    178   }
    179 
    180   /// \returns True if operands defined with this operand type can accept
    181   /// an inline constant. i.e. An integer value in the range (-16, 64) or
    182   /// -4.0f, -2.0f, -1.0f, -0.5f, 0.0f, 0.5f, 1.0f, 2.0f, 4.0f.
    183   bool opCanUseInlineConstant(unsigned OpType) const {
    184     return OpType >= AMDGPU::OPERAND_SRC_FIRST &&
    185            OpType <= AMDGPU::OPERAND_SRC_LAST;
    186   }
    187 
    188   unsigned findUnusedRegister(const MachineRegisterInfo &MRI,
    189                               const TargetRegisterClass *RC,
    190                               const MachineFunction &MF) const;
    191 
    192   unsigned getSGPRPressureSet() const { return SGPRSetID; };
    193   unsigned getVGPRPressureSet() const { return VGPRSetID; };
    194 
    195   const TargetRegisterClass *getRegClassForReg(const MachineRegisterInfo &MRI,
    196                                                unsigned Reg) const;
    197   bool isVGPR(const MachineRegisterInfo &MRI, unsigned Reg) const;
    198 
    199   bool isSGPRPressureSet(unsigned SetID) const {
    200     return SGPRPressureSets.test(SetID) && !VGPRPressureSets.test(SetID);
    201   }
    202   bool isVGPRPressureSet(unsigned SetID) const {
    203     return VGPRPressureSets.test(SetID) && !SGPRPressureSets.test(SetID);
    204   }
    205 
    206   ArrayRef<int16_t> getRegSplitParts(const TargetRegisterClass *RC,
    207                                      unsigned EltSize) const;
    208 
    209   bool shouldCoalesce(MachineInstr *MI,
    210                       const TargetRegisterClass *SrcRC,
    211                       unsigned SubReg,
    212                       const TargetRegisterClass *DstRC,
    213                       unsigned DstSubReg,
    214                       const TargetRegisterClass *NewRC,
    215                       LiveIntervals &LIS) const override;
    216 
    217   unsigned getRegPressureLimit(const TargetRegisterClass *RC,
    218                                MachineFunction &MF) const override;
    219 
    220   unsigned getRegPressureSetLimit(const MachineFunction &MF,
    221                                   unsigned Idx) const override;
    222 
    223   const int *getRegUnitPressureSets(unsigned RegUnit) const override;
    224 
    225   unsigned getReturnAddressReg(const MachineFunction &MF) const;
    226 
    227   const TargetRegisterClass *
    228   getConstrainedRegClassForOperand(const MachineOperand &MO,
    229                                  const MachineRegisterInfo &MRI) const override;
    230 
    231 private:
    232   void buildSpillLoadStore(MachineBasicBlock::iterator MI,
    233                            unsigned LoadStoreOp,
    234                            int Index,
    235                            unsigned ValueReg,
    236                            bool ValueIsKill,
    237                            unsigned ScratchRsrcReg,
    238                            unsigned ScratchOffsetReg,
    239                            int64_t InstrOffset,
    240                            MachineMemOperand *MMO,
    241                            RegScavenger *RS) const;
    242 };
    243 
    244 } // End namespace llvm
    245 
    246 #endif
    247