brintos

brintos / llvm-project-archived public Read only

0
0
Text · 20.0 KiB · 2e2916f Raw
512 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8//9/// \file10/// Interface definition for SIRegisterInfo11//12//===----------------------------------------------------------------------===//13 14#ifndef LLVM_LIB_TARGET_AMDGPU_SIREGISTERINFO_H15#define LLVM_LIB_TARGET_AMDGPU_SIREGISTERINFO_H16 17#include "llvm/ADT/BitVector.h"18 19#define GET_REGINFO_HEADER20#include "AMDGPUGenRegisterInfo.inc"21 22#include "SIDefines.h"23 24namespace llvm {25 26class GCNSubtarget;27class LiveIntervals;28class LiveRegUnits;29class MachineInstrBuilder;30class RegisterBank;31struct SGPRSpillBuilder;32 33/// Register allocation hint types. Helps eliminate unneeded COPY with True1634namespace AMDGPURI {35 36enum { Size16 = 1, Size32 = 2 };37 38} // end namespace AMDGPURI39 40class SIRegisterInfo final : public AMDGPUGenRegisterInfo {41private:42  const GCNSubtarget &ST;43  bool SpillSGPRToVGPR;44  bool isWave32;45  BitVector RegPressureIgnoredUnits;46 47  /// Sub reg indexes for getRegSplitParts.48  /// First index represents subreg size from 1 to 32 Half DWORDS.49  /// The inner vector is sorted by bit offset.50  /// Provided a register can be fully split with given subregs,51  /// all elements of the inner vector combined give a full lane mask.52  static std::array<std::vector<int16_t>, 32> RegSplitParts;53 54  // Table representing sub reg of given width and offset.55  // First index is subreg size: 32, 64, 96, 128, 160, 192, 224, 256, 512.56  // Second index is 32 different dword offsets.57  static std::array<std::array<uint16_t, 32>, 9> SubRegFromChannelTable;58 59  void reserveRegisterTuples(BitVector &, MCRegister Reg) const;60 61public:62  SIRegisterInfo(const GCNSubtarget &ST);63 64  struct SpilledReg {65    Register VGPR;66    int Lane = -1;67 68    SpilledReg() = default;69    SpilledReg(Register R, int L) : VGPR(R), Lane(L) {}70 71    bool hasLane() { return Lane != -1; }72    bool hasReg() { return VGPR != 0; }73  };74 75  /// \returns the sub reg enum value for the given \p Channel76  /// (e.g. getSubRegFromChannel(0) -> AMDGPU::sub0)77  static unsigned getSubRegFromChannel(unsigned Channel, unsigned NumRegs = 1);78 79  bool spillSGPRToVGPR() const {80    return SpillSGPRToVGPR;81  }82 83  /// Return the largest available SGPR aligned to \p Align for the register84  /// class \p RC.85  MCRegister getAlignedHighSGPRForRC(const MachineFunction &MF,86                                     const unsigned Align,87                                     const TargetRegisterClass *RC) const;88 89  /// Return the end register initially reserved for the scratch buffer in case90  /// spilling is needed.91  MCRegister reservedPrivateSegmentBufferReg(const MachineFunction &MF) const;92 93  BitVector getReservedRegs(const MachineFunction &MF) const override;94  bool isAsmClobberable(const MachineFunction &MF,95                        MCRegister PhysReg) const override;96 97  const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;98  const MCPhysReg *getCalleeSavedRegsViaCopy(const MachineFunction *MF) const;99  const uint32_t *getCallPreservedMask(const MachineFunction &MF,100                                       CallingConv::ID) const override;101  const uint32_t *getNoPreservedMask() const override;102 103  // Functions with the amdgpu_cs_chain or amdgpu_cs_chain_preserve calling104  // conventions are free to use certain VGPRs without saving and restoring any105  // lanes (not even inactive ones).106  static bool isChainScratchRegister(Register VGPR);107 108  // Stack access is very expensive. CSRs are also the high registers, and we109  // want to minimize the number of used registers.110  unsigned getCSRFirstUseCost() const override {111    return 100;112  }113 114  // When building a block VGPR load, we only really transfer a subset of the115  // registers in the block, based on a mask. Liveness analysis is not aware of116  // the mask, so it might consider that any register in the block is available117  // before the load and may therefore be scavenged. This is not ok for CSRs118  // that are not clobbered, since the caller will expect them to be preserved.119  // This method will add artificial implicit uses for those registers on the120  // load instruction, so liveness analysis knows they're unavailable.121  void addImplicitUsesForBlockCSRLoad(MachineInstrBuilder &MIB,122                                      Register BlockReg) const;123 124  const TargetRegisterClass *125  getLargestLegalSuperClass(const TargetRegisterClass *RC,126                            const MachineFunction &MF) const override;127 128  Register getFrameRegister(const MachineFunction &MF) const override;129 130  bool hasBasePointer(const MachineFunction &MF) const;131  Register getBaseRegister() const;132 133  bool shouldRealignStack(const MachineFunction &MF) const override;134  bool requiresRegisterScavenging(const MachineFunction &Fn) const override;135 136  bool requiresFrameIndexScavenging(const MachineFunction &MF) const override;137  bool requiresFrameIndexReplacementScavenging(138    const MachineFunction &MF) const override;139  bool requiresVirtualBaseRegisters(const MachineFunction &Fn) const override;140 141  int64_t getScratchInstrOffset(const MachineInstr *MI) const;142 143  int64_t getFrameIndexInstrOffset(const MachineInstr *MI,144                                   int Idx) const override;145 146  bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override;147 148  Register materializeFrameBaseRegister(MachineBasicBlock *MBB, int FrameIdx,149                                        int64_t Offset) const override;150 151  void resolveFrameIndex(MachineInstr &MI, Register BaseReg,152                         int64_t Offset) const override;153 154  bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg,155                          int64_t Offset) const override;156 157  const TargetRegisterClass *158  getPointerRegClass(unsigned Kind = 0) const override;159 160  /// Returns a legal register class to copy a register in the specified class161  /// to or from. If it is possible to copy the register directly without using162  /// a cross register class copy, return the specified RC. Returns NULL if it163  /// is not possible to copy between two registers of the specified class.164  const TargetRegisterClass *165  getCrossCopyRegClass(const TargetRegisterClass *RC) const override;166 167  const TargetRegisterClass *168  getRegClassForBlockOp(const MachineFunction &MF) const {169    return &AMDGPU::VReg_1024RegClass;170  }171 172  void buildVGPRSpillLoadStore(SGPRSpillBuilder &SB, int Index, int Offset,173                               bool IsLoad, bool IsKill = true) const;174 175  /// If \p OnlyToVGPR is true, this will only succeed if this manages to find a176  /// free VGPR lane to spill.177  bool spillSGPR(MachineBasicBlock::iterator MI, int FI, RegScavenger *RS,178                 SlotIndexes *Indexes = nullptr, LiveIntervals *LIS = nullptr,179                 bool OnlyToVGPR = false,180                 bool SpillToPhysVGPRLane = false) const;181 182  bool restoreSGPR(MachineBasicBlock::iterator MI, int FI, RegScavenger *RS,183                   SlotIndexes *Indexes = nullptr, LiveIntervals *LIS = nullptr,184                   bool OnlyToVGPR = false,185                   bool SpillToPhysVGPRLane = false) const;186 187  bool spillEmergencySGPR(MachineBasicBlock::iterator MI,188                          MachineBasicBlock &RestoreMBB, Register SGPR,189                          RegScavenger *RS) const;190 191  bool eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj,192                           unsigned FIOperandNum,193                           RegScavenger *RS) const override;194 195  bool eliminateSGPRToVGPRSpillFrameIndex(196      MachineBasicBlock::iterator MI, int FI, RegScavenger *RS,197      SlotIndexes *Indexes = nullptr, LiveIntervals *LIS = nullptr,198      bool SpillToPhysVGPRLane = false) const;199 200  StringRef getRegAsmName(MCRegister Reg) const override;201 202  // Pseudo regs are not allowed203  unsigned getHWRegIndex(MCRegister Reg) const;204 205  LLVM_READONLY206  const TargetRegisterClass *getVGPRClassForBitWidth(unsigned BitWidth) const;207 208  LLVM_READONLY const TargetRegisterClass *209  getAlignedLo256VGPRClassForBitWidth(unsigned BitWidth) const;210 211  LLVM_READONLY212  const TargetRegisterClass *getAGPRClassForBitWidth(unsigned BitWidth) const;213 214  LLVM_READONLY215  const TargetRegisterClass *216  getVectorSuperClassForBitWidth(unsigned BitWidth) const;217 218  LLVM_READONLY219  const TargetRegisterClass *220  getDefaultVectorSuperClassForBitWidth(unsigned BitWidth) const;221 222  LLVM_READONLY223  static const TargetRegisterClass *getSGPRClassForBitWidth(unsigned BitWidth);224 225  /// \returns true if this class contains only SGPR registers226  static bool isSGPRClass(const TargetRegisterClass *RC) {227    return hasSGPRs(RC) && !hasVGPRs(RC) && !hasAGPRs(RC);228  }229 230  /// \returns true if this class ID contains only SGPR registers231  bool isSGPRClassID(unsigned RCID) const {232    return isSGPRClass(getRegClass(RCID));233  }234 235  bool isSGPRReg(const MachineRegisterInfo &MRI, Register Reg) const;236  bool isSGPRPhysReg(Register Reg) const {237    return isSGPRClass(getPhysRegBaseClass(Reg));238  }239 240  bool isVGPRPhysReg(Register Reg) const {241    return isVGPRClass(getPhysRegBaseClass(Reg));242  }243 244  /// \returns true if this class contains only VGPR registers245  static bool isVGPRClass(const TargetRegisterClass *RC) {246    return hasVGPRs(RC) && !hasAGPRs(RC) && !hasSGPRs(RC);247  }248 249  /// \returns true if this class contains only AGPR registers250  static bool isAGPRClass(const TargetRegisterClass *RC) {251    return hasAGPRs(RC) && !hasVGPRs(RC) && !hasSGPRs(RC);252  }253 254  /// \returns true only if this class contains both VGPR and AGPR registers255  bool isVectorSuperClass(const TargetRegisterClass *RC) const {256    return hasVGPRs(RC) && hasAGPRs(RC) && !hasSGPRs(RC);257  }258 259  /// \returns true only if this class contains both VGPR and SGPR registers260  bool isVSSuperClass(const TargetRegisterClass *RC) const {261    return hasVGPRs(RC) && hasSGPRs(RC) && !hasAGPRs(RC);262  }263 264  /// \returns true if this class contains VGPR registers.265  static bool hasVGPRs(const TargetRegisterClass *RC) {266    return RC->TSFlags & SIRCFlags::HasVGPR;267  }268 269  /// \returns true if this class contains AGPR registers.270  static bool hasAGPRs(const TargetRegisterClass *RC) {271    return RC->TSFlags & SIRCFlags::HasAGPR;272  }273 274  /// \returns true if this class contains SGPR registers.275  static bool hasSGPRs(const TargetRegisterClass *RC) {276    return RC->TSFlags & SIRCFlags::HasSGPR;277  }278 279  /// \returns true if this class contains any vector registers.280  static bool hasVectorRegisters(const TargetRegisterClass *RC) {281    return hasVGPRs(RC) || hasAGPRs(RC);282  }283 284  /// \returns A VGPR reg class with the same width as \p SRC285  const TargetRegisterClass *286  getEquivalentVGPRClass(const TargetRegisterClass *SRC) const;287 288  /// \returns An AGPR reg class with the same width as \p SRC289  const TargetRegisterClass *290  getEquivalentAGPRClass(const TargetRegisterClass *SRC) const;291 292  /// \returns An AGPR+VGPR super reg class with the same width as \p SRC293  const TargetRegisterClass *294  getEquivalentAVClass(const TargetRegisterClass *SRC) const;295 296  /// \returns A SGPR reg class with the same width as \p SRC297  const TargetRegisterClass *298  getEquivalentSGPRClass(const TargetRegisterClass *VRC) const;299 300  /// Returns a register class which is compatible with \p SuperRC, such that a301  /// subregister exists with class \p SubRC with subregister index \p302  /// SubIdx. If this is impossible (e.g., an unaligned subregister index within303  /// a register tuple), return null.304  const TargetRegisterClass *305  getCompatibleSubRegClass(const TargetRegisterClass *SuperRC,306                           const TargetRegisterClass *SubRC,307                           unsigned SubIdx) const;308 309  /// \returns True if operands defined with this operand type can accept310  /// a literal constant (i.e. any 32-bit immediate).311  bool opCanUseLiteralConstant(unsigned OpType) const;312 313  /// \returns True if operands defined with this operand type can accept314  /// an inline constant. i.e. An integer value in the range (-16, 64) or315  /// -4.0f, -2.0f, -1.0f, -0.5f, 0.0f, 0.5f, 1.0f, 2.0f, 4.0f.316  bool opCanUseInlineConstant(unsigned OpType) const;317 318  MCRegister findUnusedRegister(const MachineRegisterInfo &MRI,319                                const TargetRegisterClass *RC,320                                const MachineFunction &MF,321                                bool ReserveHighestVGPR = false) const;322 323  const TargetRegisterClass *getRegClassForReg(const MachineRegisterInfo &MRI,324                                               Register Reg) const;325  const TargetRegisterClass *326  getRegClassForOperandReg(const MachineRegisterInfo &MRI,327                           const MachineOperand &MO) const;328 329  bool isVGPR(const MachineRegisterInfo &MRI, Register Reg) const;330  bool isAGPR(const MachineRegisterInfo &MRI, Register Reg) const;331  bool isVectorRegister(const MachineRegisterInfo &MRI, Register Reg) const {332    return isVGPR(MRI, Reg) || isAGPR(MRI, Reg);333  }334 335  // FIXME: SGPRs are assumed to be uniform, but this is not true for i1 SGPRs336  // (such as VCC) which hold a wave-wide vector of boolean values. Examining337  // just the register class is not suffcient; it needs to be combined with a338  // value type. The next predicate isUniformReg() does this correctly.339  bool isDivergentRegClass(const TargetRegisterClass *RC) const override {340    return !isSGPRClass(RC);341  }342 343  bool isUniformReg(const MachineRegisterInfo &MRI, const RegisterBankInfo &RBI,344                    Register Reg) const override;345 346  ArrayRef<int16_t> getRegSplitParts(const TargetRegisterClass *RC,347                                     unsigned EltSize) const;348 349  unsigned getRegPressureLimit(const TargetRegisterClass *RC,350                               MachineFunction &MF) const override;351 352  unsigned getRegPressureSetLimit(const MachineFunction &MF,353                                  unsigned Idx) const override;354 355  bool getRegAllocationHints(Register VirtReg, ArrayRef<MCPhysReg> Order,356                             SmallVectorImpl<MCPhysReg> &Hints,357                             const MachineFunction &MF, const VirtRegMap *VRM,358                             const LiveRegMatrix *Matrix) const override;359 360  const int *getRegUnitPressureSets(MCRegUnit RegUnit) const override;361 362  MCRegister getReturnAddressReg(const MachineFunction &MF) const;363 364  const TargetRegisterClass *365  getRegClassForSizeOnBank(unsigned Size, const RegisterBank &Bank) const;366 367  const TargetRegisterClass *368  getRegClassForTypeOnBank(LLT Ty, const RegisterBank &Bank) const {369    return getRegClassForSizeOnBank(Ty.getSizeInBits(), Bank);370  }371 372  const TargetRegisterClass *373  getConstrainedRegClassForOperand(const MachineOperand &MO,374                                 const MachineRegisterInfo &MRI) const override;375 376  const TargetRegisterClass *getBoolRC() const {377    return isWave32 ? &AMDGPU::SReg_32RegClass378                    : &AMDGPU::SReg_64RegClass;379  }380 381  const TargetRegisterClass *getWaveMaskRegClass() const {382    return isWave32 ? &AMDGPU::SReg_32_XM0_XEXECRegClass383                    : &AMDGPU::SReg_64_XEXECRegClass;384  }385 386  // Return the appropriate register class to use for 64-bit VGPRs for the387  // subtarget.388  const TargetRegisterClass *getVGPR64Class() const;389 390  MCRegister getVCC() const;391 392  MCRegister getExec() const;393 394  // Find reaching register definition395  MachineInstr *findReachingDef(Register Reg, unsigned SubReg,396                                MachineInstr &Use,397                                MachineRegisterInfo &MRI,398                                LiveIntervals *LIS) const;399 400  const uint32_t *getAllVGPRRegMask() const;401  const uint32_t *getAllAGPRRegMask() const;402  const uint32_t *getAllVectorRegMask() const;403  const uint32_t *getAllAllocatableSRegMask() const;404 405  // \returns number of 32 bit registers covered by a \p LM406  static unsigned getNumCoveredRegs(LaneBitmask LM) {407    // The assumption is that every lo16 subreg is an even bit and every hi16408    // is an adjacent odd bit or vice versa.409    uint64_t Mask = LM.getAsInteger();410    uint64_t Even = Mask & 0xAAAAAAAAAAAAAAAAULL;411    Mask = (Even >> 1) | Mask;412    uint64_t Odd = Mask & 0x5555555555555555ULL;413    return llvm::popcount(Odd);414  }415 416  // \returns a DWORD offset of a \p SubReg417  unsigned getChannelFromSubReg(unsigned SubReg) const {418    return SubReg ? (getSubRegIdxOffset(SubReg) + 31) / 32 : 0;419  }420 421  // \returns a DWORD size of a \p SubReg422  unsigned getNumChannelsFromSubReg(unsigned SubReg) const {423    return getNumCoveredRegs(getSubRegIndexLaneMask(SubReg));424  }425 426  // For a given 16 bit \p Reg \returns a 32 bit register holding it.427  // \returns \p Reg otherwise.428  MCPhysReg get32BitRegister(MCPhysReg Reg) const;429 430  // Returns true if a given register class is properly aligned for431  // the subtarget.432  bool isProperlyAlignedRC(const TargetRegisterClass &RC) const;433 434  /// Return all SGPR128 which satisfy the waves per execution unit requirement435  /// of the subtarget.436  ArrayRef<MCPhysReg> getAllSGPR128(const MachineFunction &MF) const;437 438  /// Return all SGPR64 which satisfy the waves per execution unit requirement439  /// of the subtarget.440  ArrayRef<MCPhysReg> getAllSGPR64(const MachineFunction &MF) const;441 442  /// Return all SGPR32 which satisfy the waves per execution unit requirement443  /// of the subtarget.444  ArrayRef<MCPhysReg> getAllSGPR32(const MachineFunction &MF) const;445 446  // Insert spill or restore instructions.447  // When lowering spill pseudos, the RegScavenger should be set.448  // For creating spill instructions during frame lowering, where no scavenger449  // is available, LiveUnits can be used.450  void buildSpillLoadStore(MachineBasicBlock &MBB,451                           MachineBasicBlock::iterator MI, const DebugLoc &DL,452                           unsigned LoadStoreOp, int Index, Register ValueReg,453                           bool ValueIsKill, MCRegister ScratchOffsetReg,454                           int64_t InstrOffset, MachineMemOperand *MMO,455                           RegScavenger *RS,456                           LiveRegUnits *LiveUnits = nullptr) const;457 458  // Return alignment in register file of first register in a register tuple.459  unsigned getRegClassAlignmentNumBits(const TargetRegisterClass *RC) const {460    return (RC->TSFlags & SIRCFlags::RegTupleAlignUnitsMask) * 32;461  }462 463  // Check if register class RC has required alignment.464  bool isRegClassAligned(const TargetRegisterClass *RC,465                         unsigned AlignNumBits) const {466    assert(AlignNumBits != 0);467    unsigned RCAlign = getRegClassAlignmentNumBits(RC);468    return RCAlign == AlignNumBits ||469           (RCAlign > AlignNumBits && (RCAlign % AlignNumBits) == 0);470  }471 472  // Return alignment of a SubReg relative to start of a register in RC class.473  // No check if the subreg is supported by the current RC is made.474  unsigned getSubRegAlignmentNumBits(const TargetRegisterClass *RC,475                                     unsigned SubReg) const;476 477  // \returns a number of registers of a given \p RC used in a function.478  // Does not go inside function calls. If \p IncludeCalls is true, it will479  // include registers that may be clobbered by calls.480  unsigned getNumUsedPhysRegs(const MachineRegisterInfo &MRI,481                              const TargetRegisterClass &RC,482                              bool IncludeCalls = true) const;483 484  std::optional<uint8_t> getVRegFlagValue(StringRef Name) const override {485    return Name == "WWM_REG" ? AMDGPU::VirtRegFlag::WWM_REG486                             : std::optional<uint8_t>{};487  }488 489  SmallVector<StringLiteral>490  getVRegFlagsOfReg(Register Reg, const MachineFunction &MF) const override;491 492  float493  getSpillWeightScaleFactor(const TargetRegisterClass *RC) const override {494    // Prioritize VGPR_32_Lo256 over other classes which may occupy registers495    // beyond v256.496    return AMDGPUGenRegisterInfo::getSpillWeightScaleFactor(RC) *497           ((RC == &AMDGPU::VGPR_32_Lo256RegClass ||498             RC == &AMDGPU::VReg_64_Lo256_Align2RegClass)499                ? 2.0500                : 1.0);501  }502};503 504namespace AMDGPU {505/// Get the size in bits of a register from the register class \p RC.506unsigned getRegBitWidth(const TargetRegisterClass &RC);507} // namespace AMDGPU508 509} // End namespace llvm510 511#endif512