10b57cec5SDimitry Andric //===-- SIRegisterInfo.h - SI Register Info Interface ----------*- C++ -*--===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric /// \file 100b57cec5SDimitry Andric /// Interface definition for SIRegisterInfo 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_AMDGPU_SIREGISTERINFO_H 150b57cec5SDimitry Andric #define LLVM_LIB_TARGET_AMDGPU_SIREGISTERINFO_H 160b57cec5SDimitry Andric 17*5f757f3fSDimitry Andric #include "llvm/ADT/BitVector.h" 18*5f757f3fSDimitry Andric 195ffd83dbSDimitry Andric #define GET_REGINFO_HEADER 205ffd83dbSDimitry Andric #include "AMDGPUGenRegisterInfo.inc" 215ffd83dbSDimitry Andric 22349cc55cSDimitry Andric #include "SIDefines.h" 23349cc55cSDimitry Andric 240b57cec5SDimitry Andric namespace llvm { 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric class GCNSubtarget; 270b57cec5SDimitry Andric class LiveIntervals; 28*5f757f3fSDimitry Andric class LiveRegUnits; 29e8d8bef9SDimitry Andric class RegisterBank; 30fe6060f1SDimitry Andric struct SGPRSpillBuilder; 310b57cec5SDimitry Andric 325ffd83dbSDimitry Andric class SIRegisterInfo final : public AMDGPUGenRegisterInfo { 330b57cec5SDimitry Andric private: 348bcb0991SDimitry Andric const GCNSubtarget &ST; 350b57cec5SDimitry Andric bool SpillSGPRToVGPR; 360b57cec5SDimitry Andric bool isWave32; 375ffd83dbSDimitry Andric BitVector RegPressureIgnoredUnits; 380b57cec5SDimitry Andric 395ffd83dbSDimitry Andric /// Sub reg indexes for getRegSplitParts. 405ffd83dbSDimitry Andric /// First index represents subreg size from 1 to 16 DWORDs. 415ffd83dbSDimitry Andric /// The inner vector is sorted by bit offset. 425ffd83dbSDimitry Andric /// Provided a register can be fully split with given subregs, 435ffd83dbSDimitry Andric /// all elements of the inner vector combined give a full lane mask. 445ffd83dbSDimitry Andric static std::array<std::vector<int16_t>, 16> RegSplitParts; 455ffd83dbSDimitry Andric 46e8d8bef9SDimitry Andric // Table representing sub reg of given width and offset. 47e8d8bef9SDimitry Andric // First index is subreg size: 32, 64, 96, 128, 160, 192, 224, 256, 512. 48e8d8bef9SDimitry Andric // Second index is 32 different dword offsets. 49e8d8bef9SDimitry Andric static std::array<std::array<uint16_t, 32>, 9> SubRegFromChannelTable; 50e8d8bef9SDimitry Andric 515ffd83dbSDimitry Andric void reserveRegisterTuples(BitVector &, MCRegister Reg) const; 525ffd83dbSDimitry Andric 530b57cec5SDimitry Andric public: 540b57cec5SDimitry Andric SIRegisterInfo(const GCNSubtarget &ST); 550b57cec5SDimitry Andric 5681ad6265SDimitry Andric struct SpilledReg { 5781ad6265SDimitry Andric Register VGPR; 5881ad6265SDimitry Andric int Lane = -1; 5981ad6265SDimitry Andric 6081ad6265SDimitry Andric SpilledReg() = default; 6181ad6265SDimitry Andric SpilledReg(Register R, int L) : VGPR(R), Lane(L) {} 6281ad6265SDimitry Andric 6381ad6265SDimitry Andric bool hasLane() { return Lane != -1; } 6481ad6265SDimitry Andric bool hasReg() { return VGPR != 0; } 6581ad6265SDimitry Andric }; 6681ad6265SDimitry Andric 675ffd83dbSDimitry Andric /// \returns the sub reg enum value for the given \p Channel 685ffd83dbSDimitry Andric /// (e.g. getSubRegFromChannel(0) -> AMDGPU::sub0) 695ffd83dbSDimitry Andric static unsigned getSubRegFromChannel(unsigned Channel, unsigned NumRegs = 1); 705ffd83dbSDimitry Andric 710b57cec5SDimitry Andric bool spillSGPRToVGPR() const { 720b57cec5SDimitry Andric return SpillSGPRToVGPR; 730b57cec5SDimitry Andric } 740b57cec5SDimitry Andric 7506c3fb27SDimitry Andric /// Return the largest available SGPR aligned to \p Align for the register 7606c3fb27SDimitry Andric /// class \p RC. 7706c3fb27SDimitry Andric MCRegister getAlignedHighSGPRForRC(const MachineFunction &MF, 7806c3fb27SDimitry Andric const unsigned Align, 7906c3fb27SDimitry Andric const TargetRegisterClass *RC) const; 8006c3fb27SDimitry Andric 810b57cec5SDimitry Andric /// Return the end register initially reserved for the scratch buffer in case 820b57cec5SDimitry Andric /// spilling is needed. 835ffd83dbSDimitry Andric MCRegister reservedPrivateSegmentBufferReg(const MachineFunction &MF) const; 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric BitVector getReservedRegs(const MachineFunction &MF) const override; 8681ad6265SDimitry Andric bool isAsmClobberable(const MachineFunction &MF, 8781ad6265SDimitry Andric MCRegister PhysReg) const override; 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override; 900b57cec5SDimitry Andric const MCPhysReg *getCalleeSavedRegsViaCopy(const MachineFunction *MF) const; 910b57cec5SDimitry Andric const uint32_t *getCallPreservedMask(const MachineFunction &MF, 920b57cec5SDimitry Andric CallingConv::ID) const override; 93e8d8bef9SDimitry Andric const uint32_t *getNoPreservedMask() const override; 940b57cec5SDimitry Andric 95*5f757f3fSDimitry Andric // Functions with the amdgpu_cs_chain or amdgpu_cs_chain_preserve calling 96*5f757f3fSDimitry Andric // conventions are free to use certain VGPRs without saving and restoring any 97*5f757f3fSDimitry Andric // lanes (not even inactive ones). 98*5f757f3fSDimitry Andric static bool isChainScratchRegister(Register VGPR); 99*5f757f3fSDimitry Andric 1000b57cec5SDimitry Andric // Stack access is very expensive. CSRs are also the high registers, and we 1010b57cec5SDimitry Andric // want to minimize the number of used registers. 1020b57cec5SDimitry Andric unsigned getCSRFirstUseCost() const override { 1030b57cec5SDimitry Andric return 100; 1040b57cec5SDimitry Andric } 1050b57cec5SDimitry Andric 1064824e7fdSDimitry Andric const TargetRegisterClass * 1074824e7fdSDimitry Andric getLargestLegalSuperClass(const TargetRegisterClass *RC, 1084824e7fdSDimitry Andric const MachineFunction &MF) const override; 1094824e7fdSDimitry Andric 1100b57cec5SDimitry Andric Register getFrameRegister(const MachineFunction &MF) const override; 1110b57cec5SDimitry Andric 1125ffd83dbSDimitry Andric bool hasBasePointer(const MachineFunction &MF) const; 1135ffd83dbSDimitry Andric Register getBaseRegister() const; 1145ffd83dbSDimitry Andric 115fe6060f1SDimitry Andric bool shouldRealignStack(const MachineFunction &MF) const override; 1160b57cec5SDimitry Andric bool requiresRegisterScavenging(const MachineFunction &Fn) const override; 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andric bool requiresFrameIndexScavenging(const MachineFunction &MF) const override; 1190b57cec5SDimitry Andric bool requiresFrameIndexReplacementScavenging( 1200b57cec5SDimitry Andric const MachineFunction &MF) const override; 1210b57cec5SDimitry Andric bool requiresVirtualBaseRegisters(const MachineFunction &Fn) const override; 1220b57cec5SDimitry Andric 123e8d8bef9SDimitry Andric int64_t getScratchInstrOffset(const MachineInstr *MI) const; 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric int64_t getFrameIndexInstrOffset(const MachineInstr *MI, 1260b57cec5SDimitry Andric int Idx) const override; 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override; 1290b57cec5SDimitry Andric 130e8d8bef9SDimitry Andric Register materializeFrameBaseRegister(MachineBasicBlock *MBB, int FrameIdx, 1310b57cec5SDimitry Andric int64_t Offset) const override; 1320b57cec5SDimitry Andric 1335ffd83dbSDimitry Andric void resolveFrameIndex(MachineInstr &MI, Register BaseReg, 1340b57cec5SDimitry Andric int64_t Offset) const override; 1350b57cec5SDimitry Andric 1365ffd83dbSDimitry Andric bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg, 1370b57cec5SDimitry Andric int64_t Offset) const override; 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric const TargetRegisterClass *getPointerRegClass( 1400b57cec5SDimitry Andric const MachineFunction &MF, unsigned Kind = 0) const override; 1410b57cec5SDimitry Andric 142349cc55cSDimitry Andric /// Returns a legal register class to copy a register in the specified class 143349cc55cSDimitry Andric /// to or from. If it is possible to copy the register directly without using 144349cc55cSDimitry Andric /// a cross register class copy, return the specified RC. Returns NULL if it 145349cc55cSDimitry Andric /// is not possible to copy between two registers of the specified class. 146349cc55cSDimitry Andric const TargetRegisterClass * 147349cc55cSDimitry Andric getCrossCopyRegClass(const TargetRegisterClass *RC) const override; 148349cc55cSDimitry Andric 149fe6060f1SDimitry Andric void buildVGPRSpillLoadStore(SGPRSpillBuilder &SB, int Index, int Offset, 150fe6060f1SDimitry Andric bool IsLoad, bool IsKill = true) const; 1515ffd83dbSDimitry Andric 152*5f757f3fSDimitry Andric /// If \p OnlyToVGPR is true, this will only succeed if this manages to find a 153*5f757f3fSDimitry Andric /// free VGPR lane to spill. 154bdd1243dSDimitry Andric bool spillSGPR(MachineBasicBlock::iterator MI, int FI, RegScavenger *RS, 155bdd1243dSDimitry Andric SlotIndexes *Indexes = nullptr, LiveIntervals *LIS = nullptr, 156*5f757f3fSDimitry Andric bool OnlyToVGPR = false, 157*5f757f3fSDimitry Andric bool SpillToPhysVGPRLane = false) const; 1580b57cec5SDimitry Andric 159bdd1243dSDimitry Andric bool restoreSGPR(MachineBasicBlock::iterator MI, int FI, RegScavenger *RS, 160bdd1243dSDimitry Andric SlotIndexes *Indexes = nullptr, LiveIntervals *LIS = nullptr, 161*5f757f3fSDimitry Andric bool OnlyToVGPR = false, 162*5f757f3fSDimitry Andric bool SpillToPhysVGPRLane = false) const; 1630b57cec5SDimitry Andric 164349cc55cSDimitry Andric bool spillEmergencySGPR(MachineBasicBlock::iterator MI, 165349cc55cSDimitry Andric MachineBasicBlock &RestoreMBB, Register SGPR, 166349cc55cSDimitry Andric RegScavenger *RS) const; 167349cc55cSDimitry Andric 168bdd1243dSDimitry Andric bool eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, 1690b57cec5SDimitry Andric unsigned FIOperandNum, 1700b57cec5SDimitry Andric RegScavenger *RS) const override; 1710b57cec5SDimitry Andric 172*5f757f3fSDimitry Andric bool eliminateSGPRToVGPRSpillFrameIndex( 173*5f757f3fSDimitry Andric MachineBasicBlock::iterator MI, int FI, RegScavenger *RS, 174*5f757f3fSDimitry Andric SlotIndexes *Indexes = nullptr, LiveIntervals *LIS = nullptr, 175*5f757f3fSDimitry Andric bool SpillToPhysVGPRLane = false) const; 1760b57cec5SDimitry Andric 1775ffd83dbSDimitry Andric StringRef getRegAsmName(MCRegister Reg) const override; 1780b57cec5SDimitry Andric 179e8d8bef9SDimitry Andric // Pseudo regs are not allowed 1805ffd83dbSDimitry Andric unsigned getHWRegIndex(MCRegister Reg) const { 1810b57cec5SDimitry Andric return getEncodingValue(Reg) & 0xff; 1820b57cec5SDimitry Andric } 1830b57cec5SDimitry Andric 184fe6060f1SDimitry Andric LLVM_READONLY 185fe6060f1SDimitry Andric const TargetRegisterClass *getVGPRClassForBitWidth(unsigned BitWidth) const; 186fe6060f1SDimitry Andric 187fe6060f1SDimitry Andric LLVM_READONLY 188fe6060f1SDimitry Andric const TargetRegisterClass *getAGPRClassForBitWidth(unsigned BitWidth) const; 189fe6060f1SDimitry Andric 190fe6060f1SDimitry Andric LLVM_READONLY 1914824e7fdSDimitry Andric const TargetRegisterClass * 1924824e7fdSDimitry Andric getVectorSuperClassForBitWidth(unsigned BitWidth) const; 1934824e7fdSDimitry Andric 1944824e7fdSDimitry Andric LLVM_READONLY 1955ffd83dbSDimitry Andric static const TargetRegisterClass *getSGPRClassForBitWidth(unsigned BitWidth); 1965ffd83dbSDimitry Andric 1970b57cec5SDimitry Andric /// \returns true if this class contains only SGPR registers 198349cc55cSDimitry Andric static bool isSGPRClass(const TargetRegisterClass *RC) { 1994824e7fdSDimitry Andric return hasSGPRs(RC) && !hasVGPRs(RC) && !hasAGPRs(RC); 2000b57cec5SDimitry Andric } 2010b57cec5SDimitry Andric 2020b57cec5SDimitry Andric /// \returns true if this class ID contains only SGPR registers 2030b57cec5SDimitry Andric bool isSGPRClassID(unsigned RCID) const { 2040b57cec5SDimitry Andric return isSGPRClass(getRegClass(RCID)); 2050b57cec5SDimitry Andric } 2060b57cec5SDimitry Andric 207e8d8bef9SDimitry Andric bool isSGPRReg(const MachineRegisterInfo &MRI, Register Reg) const; 2080b57cec5SDimitry Andric 209349cc55cSDimitry Andric /// \returns true if this class contains only VGPR registers 210349cc55cSDimitry Andric static bool isVGPRClass(const TargetRegisterClass *RC) { 2114824e7fdSDimitry Andric return hasVGPRs(RC) && !hasAGPRs(RC) && !hasSGPRs(RC); 212349cc55cSDimitry Andric } 213349cc55cSDimitry Andric 214480093f4SDimitry Andric /// \returns true if this class contains only AGPR registers 215349cc55cSDimitry Andric static bool isAGPRClass(const TargetRegisterClass *RC) { 2164824e7fdSDimitry Andric return hasAGPRs(RC) && !hasVGPRs(RC) && !hasSGPRs(RC); 2174824e7fdSDimitry Andric } 2184824e7fdSDimitry Andric 2194824e7fdSDimitry Andric /// \returns true only if this class contains both VGPR and AGPR registers 2204824e7fdSDimitry Andric bool isVectorSuperClass(const TargetRegisterClass *RC) const { 2214824e7fdSDimitry Andric return hasVGPRs(RC) && hasAGPRs(RC) && !hasSGPRs(RC); 2224824e7fdSDimitry Andric } 2234824e7fdSDimitry Andric 2244824e7fdSDimitry Andric /// \returns true only if this class contains both VGPR and SGPR registers 2254824e7fdSDimitry Andric bool isVSSuperClass(const TargetRegisterClass *RC) const { 2264824e7fdSDimitry Andric return hasVGPRs(RC) && hasSGPRs(RC) && !hasAGPRs(RC); 227480093f4SDimitry Andric } 228480093f4SDimitry Andric 2290b57cec5SDimitry Andric /// \returns true if this class contains VGPR registers. 230349cc55cSDimitry Andric static bool hasVGPRs(const TargetRegisterClass *RC) { 231349cc55cSDimitry Andric return RC->TSFlags & SIRCFlags::HasVGPR; 232349cc55cSDimitry Andric } 2330b57cec5SDimitry Andric 2340b57cec5SDimitry Andric /// \returns true if this class contains AGPR registers. 235349cc55cSDimitry Andric static bool hasAGPRs(const TargetRegisterClass *RC) { 236349cc55cSDimitry Andric return RC->TSFlags & SIRCFlags::HasAGPR; 237349cc55cSDimitry Andric } 2380b57cec5SDimitry Andric 2394824e7fdSDimitry Andric /// \returns true if this class contains SGPR registers. 2404824e7fdSDimitry Andric static bool hasSGPRs(const TargetRegisterClass *RC) { 2414824e7fdSDimitry Andric return RC->TSFlags & SIRCFlags::HasSGPR; 2424824e7fdSDimitry Andric } 2434824e7fdSDimitry Andric 2440b57cec5SDimitry Andric /// \returns true if this class contains any vector registers. 245349cc55cSDimitry Andric static bool hasVectorRegisters(const TargetRegisterClass *RC) { 2460b57cec5SDimitry Andric return hasVGPRs(RC) || hasAGPRs(RC); 2470b57cec5SDimitry Andric } 2480b57cec5SDimitry Andric 2490b57cec5SDimitry Andric /// \returns A VGPR reg class with the same width as \p SRC 2505ffd83dbSDimitry Andric const TargetRegisterClass * 2515ffd83dbSDimitry Andric getEquivalentVGPRClass(const TargetRegisterClass *SRC) const; 2520b57cec5SDimitry Andric 2530b57cec5SDimitry Andric /// \returns An AGPR reg class with the same width as \p SRC 2545ffd83dbSDimitry Andric const TargetRegisterClass * 2555ffd83dbSDimitry Andric getEquivalentAGPRClass(const TargetRegisterClass *SRC) const; 2560b57cec5SDimitry Andric 2570b57cec5SDimitry Andric /// \returns A SGPR reg class with the same width as \p SRC 2585ffd83dbSDimitry Andric const TargetRegisterClass * 2595ffd83dbSDimitry Andric getEquivalentSGPRClass(const TargetRegisterClass *VRC) const; 2600b57cec5SDimitry Andric 261fe6060f1SDimitry Andric /// Returns a register class which is compatible with \p SuperRC, such that a 262fe6060f1SDimitry Andric /// subregister exists with class \p SubRC with subregister index \p 263fe6060f1SDimitry Andric /// SubIdx. If this is impossible (e.g., an unaligned subregister index within 264fe6060f1SDimitry Andric /// a register tuple), return null. 265fe6060f1SDimitry Andric const TargetRegisterClass * 266fe6060f1SDimitry Andric getCompatibleSubRegClass(const TargetRegisterClass *SuperRC, 267fe6060f1SDimitry Andric const TargetRegisterClass *SubRC, 268fe6060f1SDimitry Andric unsigned SubIdx) const; 269fe6060f1SDimitry Andric 2700b57cec5SDimitry Andric bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC, 2710b57cec5SDimitry Andric unsigned DefSubReg, 2720b57cec5SDimitry Andric const TargetRegisterClass *SrcRC, 2730b57cec5SDimitry Andric unsigned SrcSubReg) const override; 2740b57cec5SDimitry Andric 2750b57cec5SDimitry Andric /// \returns True if operands defined with this operand type can accept 2760b57cec5SDimitry Andric /// a literal constant (i.e. any 32-bit immediate). 277e8d8bef9SDimitry Andric bool opCanUseLiteralConstant(unsigned OpType) const; 2780b57cec5SDimitry Andric 2790b57cec5SDimitry Andric /// \returns True if operands defined with this operand type can accept 2800b57cec5SDimitry Andric /// an inline constant. i.e. An integer value in the range (-16, 64) or 2810b57cec5SDimitry Andric /// -4.0f, -2.0f, -1.0f, -0.5f, 0.0f, 0.5f, 1.0f, 2.0f, 4.0f. 2828bcb0991SDimitry Andric bool opCanUseInlineConstant(unsigned OpType) const; 2830b57cec5SDimitry Andric 2845ffd83dbSDimitry Andric MCRegister findUnusedRegister(const MachineRegisterInfo &MRI, 2850b57cec5SDimitry Andric const TargetRegisterClass *RC, 2865ffd83dbSDimitry Andric const MachineFunction &MF, 2875ffd83dbSDimitry Andric bool ReserveHighestVGPR = false) const; 2880b57cec5SDimitry Andric 2890b57cec5SDimitry Andric const TargetRegisterClass *getRegClassForReg(const MachineRegisterInfo &MRI, 2905ffd83dbSDimitry Andric Register Reg) const; 291bdd1243dSDimitry Andric const TargetRegisterClass * 292bdd1243dSDimitry Andric getRegClassForOperandReg(const MachineRegisterInfo &MRI, 293bdd1243dSDimitry Andric const MachineOperand &MO) const; 294bdd1243dSDimitry Andric 2955ffd83dbSDimitry Andric bool isVGPR(const MachineRegisterInfo &MRI, Register Reg) const; 2965ffd83dbSDimitry Andric bool isAGPR(const MachineRegisterInfo &MRI, Register Reg) const; 2975ffd83dbSDimitry Andric bool isVectorRegister(const MachineRegisterInfo &MRI, Register Reg) const { 2980b57cec5SDimitry Andric return isVGPR(MRI, Reg) || isAGPR(MRI, Reg); 2990b57cec5SDimitry Andric } 3000b57cec5SDimitry Andric 30106c3fb27SDimitry Andric // FIXME: SGPRs are assumed to be uniform, but this is not true for i1 SGPRs 30206c3fb27SDimitry Andric // (such as VCC) which hold a wave-wide vector of boolean values. Examining 30306c3fb27SDimitry Andric // just the register class is not suffcient; it needs to be combined with a 30406c3fb27SDimitry Andric // value type. The next predicate isUniformReg() does this correctly. 3055ffd83dbSDimitry Andric bool isDivergentRegClass(const TargetRegisterClass *RC) const override { 3065ffd83dbSDimitry Andric return !isSGPRClass(RC); 3070b57cec5SDimitry Andric } 3080b57cec5SDimitry Andric 30906c3fb27SDimitry Andric bool isUniformReg(const MachineRegisterInfo &MRI, const RegisterBankInfo &RBI, 31006c3fb27SDimitry Andric Register Reg) const override; 31106c3fb27SDimitry Andric 3120b57cec5SDimitry Andric ArrayRef<int16_t> getRegSplitParts(const TargetRegisterClass *RC, 3130b57cec5SDimitry Andric unsigned EltSize) const; 3140b57cec5SDimitry Andric 3150b57cec5SDimitry Andric bool shouldCoalesce(MachineInstr *MI, 3160b57cec5SDimitry Andric const TargetRegisterClass *SrcRC, 3170b57cec5SDimitry Andric unsigned SubReg, 3180b57cec5SDimitry Andric const TargetRegisterClass *DstRC, 3190b57cec5SDimitry Andric unsigned DstSubReg, 3200b57cec5SDimitry Andric const TargetRegisterClass *NewRC, 3210b57cec5SDimitry Andric LiveIntervals &LIS) const override; 3220b57cec5SDimitry Andric 3230b57cec5SDimitry Andric unsigned getRegPressureLimit(const TargetRegisterClass *RC, 3240b57cec5SDimitry Andric MachineFunction &MF) const override; 3250b57cec5SDimitry Andric 3260b57cec5SDimitry Andric unsigned getRegPressureSetLimit(const MachineFunction &MF, 3270b57cec5SDimitry Andric unsigned Idx) const override; 3280b57cec5SDimitry Andric 3290b57cec5SDimitry Andric const int *getRegUnitPressureSets(unsigned RegUnit) const override; 3300b57cec5SDimitry Andric 3315ffd83dbSDimitry Andric MCRegister getReturnAddressReg(const MachineFunction &MF) const; 3320b57cec5SDimitry Andric 3330b57cec5SDimitry Andric const TargetRegisterClass * 33481ad6265SDimitry Andric getRegClassForSizeOnBank(unsigned Size, const RegisterBank &Bank) const; 3350b57cec5SDimitry Andric 3360b57cec5SDimitry Andric const TargetRegisterClass * 33781ad6265SDimitry Andric getRegClassForTypeOnBank(LLT Ty, const RegisterBank &Bank) const { 33881ad6265SDimitry Andric return getRegClassForSizeOnBank(Ty.getSizeInBits(), Bank); 3390b57cec5SDimitry Andric } 3400b57cec5SDimitry Andric 3410b57cec5SDimitry Andric const TargetRegisterClass * 3420b57cec5SDimitry Andric getConstrainedRegClassForOperand(const MachineOperand &MO, 3430b57cec5SDimitry Andric const MachineRegisterInfo &MRI) const override; 3440b57cec5SDimitry Andric 3450b57cec5SDimitry Andric const TargetRegisterClass *getBoolRC() const { 3468bcb0991SDimitry Andric return isWave32 ? &AMDGPU::SReg_32RegClass 3470b57cec5SDimitry Andric : &AMDGPU::SReg_64RegClass; 3480b57cec5SDimitry Andric } 3490b57cec5SDimitry Andric 3500b57cec5SDimitry Andric const TargetRegisterClass *getWaveMaskRegClass() const { 3510b57cec5SDimitry Andric return isWave32 ? &AMDGPU::SReg_32_XM0_XEXECRegClass 3520b57cec5SDimitry Andric : &AMDGPU::SReg_64_XEXECRegClass; 3530b57cec5SDimitry Andric } 3540b57cec5SDimitry Andric 355fe6060f1SDimitry Andric // Return the appropriate register class to use for 64-bit VGPRs for the 356fe6060f1SDimitry Andric // subtarget. 357fe6060f1SDimitry Andric const TargetRegisterClass *getVGPR64Class() const; 358fe6060f1SDimitry Andric 3595ffd83dbSDimitry Andric MCRegister getVCC() const; 3600b57cec5SDimitry Andric 361753f127fSDimitry Andric MCRegister getExec() const; 362753f127fSDimitry Andric 3630b57cec5SDimitry Andric const TargetRegisterClass *getRegClass(unsigned RCID) const; 3640b57cec5SDimitry Andric 3650b57cec5SDimitry Andric // Find reaching register definition 3665ffd83dbSDimitry Andric MachineInstr *findReachingDef(Register Reg, unsigned SubReg, 3670b57cec5SDimitry Andric MachineInstr &Use, 3680b57cec5SDimitry Andric MachineRegisterInfo &MRI, 3690b57cec5SDimitry Andric LiveIntervals *LIS) const; 3700b57cec5SDimitry Andric 3710b57cec5SDimitry Andric const uint32_t *getAllVGPRRegMask() const; 372fe6060f1SDimitry Andric const uint32_t *getAllAGPRRegMask() const; 373fe6060f1SDimitry Andric const uint32_t *getAllVectorRegMask() const; 3740b57cec5SDimitry Andric const uint32_t *getAllAllocatableSRegMask() const; 3750b57cec5SDimitry Andric 3765ffd83dbSDimitry Andric // \returns number of 32 bit registers covered by a \p LM 3775ffd83dbSDimitry Andric static unsigned getNumCoveredRegs(LaneBitmask LM) { 3785ffd83dbSDimitry Andric // The assumption is that every lo16 subreg is an even bit and every hi16 3795ffd83dbSDimitry Andric // is an adjacent odd bit or vice versa. 3805ffd83dbSDimitry Andric uint64_t Mask = LM.getAsInteger(); 3815ffd83dbSDimitry Andric uint64_t Even = Mask & 0xAAAAAAAAAAAAAAAAULL; 3825ffd83dbSDimitry Andric Mask = (Even >> 1) | Mask; 3835ffd83dbSDimitry Andric uint64_t Odd = Mask & 0x5555555555555555ULL; 384bdd1243dSDimitry Andric return llvm::popcount(Odd); 3855ffd83dbSDimitry Andric } 3865ffd83dbSDimitry Andric 3875ffd83dbSDimitry Andric // \returns a DWORD offset of a \p SubReg 3885ffd83dbSDimitry Andric unsigned getChannelFromSubReg(unsigned SubReg) const { 3895ffd83dbSDimitry Andric return SubReg ? (getSubRegIdxOffset(SubReg) + 31) / 32 : 0; 3905ffd83dbSDimitry Andric } 3915ffd83dbSDimitry Andric 3925ffd83dbSDimitry Andric // \returns a DWORD size of a \p SubReg 3935ffd83dbSDimitry Andric unsigned getNumChannelsFromSubReg(unsigned SubReg) const { 3945ffd83dbSDimitry Andric return getNumCoveredRegs(getSubRegIndexLaneMask(SubReg)); 3955ffd83dbSDimitry Andric } 3965ffd83dbSDimitry Andric 3975ffd83dbSDimitry Andric // For a given 16 bit \p Reg \returns a 32 bit register holding it. 3985ffd83dbSDimitry Andric // \returns \p Reg otherwise. 3995ffd83dbSDimitry Andric MCPhysReg get32BitRegister(MCPhysReg Reg) const; 4005ffd83dbSDimitry Andric 401fe6060f1SDimitry Andric // Returns true if a given register class is properly aligned for 402fe6060f1SDimitry Andric // the subtarget. 403fe6060f1SDimitry Andric bool isProperlyAlignedRC(const TargetRegisterClass &RC) const; 404fe6060f1SDimitry Andric 40581ad6265SDimitry Andric // Given \p RC returns corresponding aligned register class if required 40681ad6265SDimitry Andric // by the subtarget. 40781ad6265SDimitry Andric const TargetRegisterClass * 40881ad6265SDimitry Andric getProperlyAlignedRC(const TargetRegisterClass *RC) const; 40981ad6265SDimitry Andric 4105ffd83dbSDimitry Andric /// Return all SGPR128 which satisfy the waves per execution unit requirement 4115ffd83dbSDimitry Andric /// of the subtarget. 4125ffd83dbSDimitry Andric ArrayRef<MCPhysReg> getAllSGPR128(const MachineFunction &MF) const; 4135ffd83dbSDimitry Andric 414e8d8bef9SDimitry Andric /// Return all SGPR64 which satisfy the waves per execution unit requirement 415e8d8bef9SDimitry Andric /// of the subtarget. 416e8d8bef9SDimitry Andric ArrayRef<MCPhysReg> getAllSGPR64(const MachineFunction &MF) const; 417e8d8bef9SDimitry Andric 4185ffd83dbSDimitry Andric /// Return all SGPR32 which satisfy the waves per execution unit requirement 4195ffd83dbSDimitry Andric /// of the subtarget. 4205ffd83dbSDimitry Andric ArrayRef<MCPhysReg> getAllSGPR32(const MachineFunction &MF) const; 4215ffd83dbSDimitry Andric 422fe6060f1SDimitry Andric // Insert spill or restore instructions. 423fe6060f1SDimitry Andric // When lowering spill pseudos, the RegScavenger should be set. 424fe6060f1SDimitry Andric // For creating spill instructions during frame lowering, where no scavenger 425*5f757f3fSDimitry Andric // is available, LiveUnits can be used. 426fe6060f1SDimitry Andric void buildSpillLoadStore(MachineBasicBlock &MBB, 427349cc55cSDimitry Andric MachineBasicBlock::iterator MI, const DebugLoc &DL, 428349cc55cSDimitry Andric unsigned LoadStoreOp, int Index, Register ValueReg, 429349cc55cSDimitry Andric bool ValueIsKill, MCRegister ScratchOffsetReg, 430349cc55cSDimitry Andric int64_t InstrOffset, MachineMemOperand *MMO, 431349cc55cSDimitry Andric RegScavenger *RS, 432*5f757f3fSDimitry Andric LiveRegUnits *LiveUnits = nullptr) const; 43306c3fb27SDimitry Andric 43406c3fb27SDimitry Andric // Return alignment in register file of first register in a register tuple. 43506c3fb27SDimitry Andric unsigned getRegClassAlignmentNumBits(const TargetRegisterClass *RC) const { 43606c3fb27SDimitry Andric return (RC->TSFlags & SIRCFlags::RegTupleAlignUnitsMask) * 32; 43706c3fb27SDimitry Andric } 43806c3fb27SDimitry Andric 43906c3fb27SDimitry Andric // Check if register class RC has required alignment. 44006c3fb27SDimitry Andric bool isRegClassAligned(const TargetRegisterClass *RC, 44106c3fb27SDimitry Andric unsigned AlignNumBits) const { 44206c3fb27SDimitry Andric assert(AlignNumBits != 0); 44306c3fb27SDimitry Andric unsigned RCAlign = getRegClassAlignmentNumBits(RC); 44406c3fb27SDimitry Andric return RCAlign == AlignNumBits || 44506c3fb27SDimitry Andric (RCAlign > AlignNumBits && (RCAlign % AlignNumBits) == 0); 44606c3fb27SDimitry Andric } 44706c3fb27SDimitry Andric 44806c3fb27SDimitry Andric // Return alignment of a SubReg relative to start of a register in RC class. 44906c3fb27SDimitry Andric // No check if the subreg is supported by the current RC is made. 45006c3fb27SDimitry Andric unsigned getSubRegAlignmentNumBits(const TargetRegisterClass *RC, 45106c3fb27SDimitry Andric unsigned SubReg) const; 4520b57cec5SDimitry Andric }; 4530b57cec5SDimitry Andric 454*5f757f3fSDimitry Andric namespace AMDGPU { 455*5f757f3fSDimitry Andric /// Get the size in bits of a register from the register class \p RC. 456*5f757f3fSDimitry Andric unsigned getRegBitWidth(const TargetRegisterClass &RC); 457*5f757f3fSDimitry Andric } // namespace AMDGPU 458*5f757f3fSDimitry Andric 4590b57cec5SDimitry Andric } // End namespace llvm 4600b57cec5SDimitry Andric 4610b57cec5SDimitry Andric #endif 462