1*9880d681SAndroid Build Coastguard Worker //===-- SIRegisterInfo.h - SI Register Info Interface ----------*- C++ -*--===// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker // 10*9880d681SAndroid Build Coastguard Worker /// \file 11*9880d681SAndroid Build Coastguard Worker /// \brief Interface definition for SIRegisterInfo 12*9880d681SAndroid Build Coastguard Worker // 13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 14*9880d681SAndroid Build Coastguard Worker 15*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_LIB_TARGET_AMDGPU_SIREGISTERINFO_H 16*9880d681SAndroid Build Coastguard Worker #define LLVM_LIB_TARGET_AMDGPU_SIREGISTERINFO_H 17*9880d681SAndroid Build Coastguard Worker 18*9880d681SAndroid Build Coastguard Worker #include "AMDGPURegisterInfo.h" 19*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h" 20*9880d681SAndroid Build Coastguard Worker 21*9880d681SAndroid Build Coastguard Worker namespace llvm { 22*9880d681SAndroid Build Coastguard Worker 23*9880d681SAndroid Build Coastguard Worker class SISubtarget; 24*9880d681SAndroid Build Coastguard Worker class MachineRegisterInfo; 25*9880d681SAndroid Build Coastguard Worker 26*9880d681SAndroid Build Coastguard Worker struct SIRegisterInfo final : public AMDGPURegisterInfo { 27*9880d681SAndroid Build Coastguard Worker private: 28*9880d681SAndroid Build Coastguard Worker unsigned SGPR32SetID; 29*9880d681SAndroid Build Coastguard Worker unsigned VGPR32SetID; 30*9880d681SAndroid Build Coastguard Worker BitVector SGPRPressureSets; 31*9880d681SAndroid Build Coastguard Worker BitVector VGPRPressureSets; 32*9880d681SAndroid Build Coastguard Worker 33*9880d681SAndroid Build Coastguard Worker void reserveRegisterTuples(BitVector &, unsigned Reg) const; 34*9880d681SAndroid Build Coastguard Worker void classifyPressureSet(unsigned PSetID, unsigned Reg, 35*9880d681SAndroid Build Coastguard Worker BitVector &PressureSets) const; 36*9880d681SAndroid Build Coastguard Worker 37*9880d681SAndroid Build Coastguard Worker public: 38*9880d681SAndroid Build Coastguard Worker SIRegisterInfo(); 39*9880d681SAndroid Build Coastguard Worker 40*9880d681SAndroid Build Coastguard Worker /// Return the end register initially reserved for the scratch buffer in case 41*9880d681SAndroid Build Coastguard Worker /// spilling is needed. 42*9880d681SAndroid Build Coastguard Worker unsigned reservedPrivateSegmentBufferReg(const MachineFunction &MF) const; 43*9880d681SAndroid Build Coastguard Worker 44*9880d681SAndroid Build Coastguard Worker /// Return the end register initially reserved for the scratch wave offset in 45*9880d681SAndroid Build Coastguard Worker /// case spilling is needed. 46*9880d681SAndroid Build Coastguard Worker unsigned reservedPrivateSegmentWaveByteOffsetReg( 47*9880d681SAndroid Build Coastguard Worker const MachineFunction &MF) const; 48*9880d681SAndroid Build Coastguard Worker 49*9880d681SAndroid Build Coastguard Worker BitVector getReservedRegs(const MachineFunction &MF) const override; 50*9880d681SAndroid Build Coastguard Worker 51*9880d681SAndroid Build Coastguard Worker unsigned getRegPressureSetLimit(const MachineFunction &MF, 52*9880d681SAndroid Build Coastguard Worker unsigned Idx) const override; 53*9880d681SAndroid Build Coastguard Worker 54*9880d681SAndroid Build Coastguard Worker 55*9880d681SAndroid Build Coastguard Worker bool requiresRegisterScavenging(const MachineFunction &Fn) const override; 56*9880d681SAndroid Build Coastguard Worker 57*9880d681SAndroid Build Coastguard Worker 58*9880d681SAndroid Build Coastguard Worker bool requiresFrameIndexScavenging(const MachineFunction &MF) const override; 59*9880d681SAndroid Build Coastguard Worker bool requiresVirtualBaseRegisters(const MachineFunction &Fn) const override; 60*9880d681SAndroid Build Coastguard Worker bool trackLivenessAfterRegAlloc(const MachineFunction &MF) const override; 61*9880d681SAndroid Build Coastguard Worker 62*9880d681SAndroid Build Coastguard Worker int64_t getFrameIndexInstrOffset(const MachineInstr *MI, 63*9880d681SAndroid Build Coastguard Worker int Idx) const override; 64*9880d681SAndroid Build Coastguard Worker 65*9880d681SAndroid Build Coastguard Worker bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override; 66*9880d681SAndroid Build Coastguard Worker 67*9880d681SAndroid Build Coastguard Worker void materializeFrameBaseRegister(MachineBasicBlock *MBB, 68*9880d681SAndroid Build Coastguard Worker unsigned BaseReg, int FrameIdx, 69*9880d681SAndroid Build Coastguard Worker int64_t Offset) const override; 70*9880d681SAndroid Build Coastguard Worker 71*9880d681SAndroid Build Coastguard Worker void resolveFrameIndex(MachineInstr &MI, unsigned BaseReg, 72*9880d681SAndroid Build Coastguard Worker int64_t Offset) const override; 73*9880d681SAndroid Build Coastguard Worker 74*9880d681SAndroid Build Coastguard Worker bool isFrameOffsetLegal(const MachineInstr *MI, unsigned BaseReg, 75*9880d681SAndroid Build Coastguard Worker int64_t Offset) const override; 76*9880d681SAndroid Build Coastguard Worker 77*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *getPointerRegClass( 78*9880d681SAndroid Build Coastguard Worker const MachineFunction &MF, unsigned Kind = 0) const override; 79*9880d681SAndroid Build Coastguard Worker 80*9880d681SAndroid Build Coastguard Worker void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, 81*9880d681SAndroid Build Coastguard Worker unsigned FIOperandNum, 82*9880d681SAndroid Build Coastguard Worker RegScavenger *RS) const override; 83*9880d681SAndroid Build Coastguard Worker getHWRegIndexfinal84*9880d681SAndroid Build Coastguard Worker unsigned getHWRegIndex(unsigned Reg) const { 85*9880d681SAndroid Build Coastguard Worker return getEncodingValue(Reg) & 0xff; 86*9880d681SAndroid Build Coastguard Worker } 87*9880d681SAndroid Build Coastguard Worker 88*9880d681SAndroid Build Coastguard Worker /// \brief Return the 'base' register class for this register. 89*9880d681SAndroid Build Coastguard Worker /// e.g. SGPR0 => SReg_32, VGPR => VGPR_32 SGPR0_SGPR1 -> SReg_32, etc. 90*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *getPhysRegClass(unsigned Reg) const; 91*9880d681SAndroid Build Coastguard Worker 92*9880d681SAndroid Build Coastguard Worker /// \returns true if this class contains only SGPR registers isSGPRClassfinal93*9880d681SAndroid Build Coastguard Worker bool isSGPRClass(const TargetRegisterClass *RC) const { 94*9880d681SAndroid Build Coastguard Worker return !hasVGPRs(RC); 95*9880d681SAndroid Build Coastguard Worker } 96*9880d681SAndroid Build Coastguard Worker 97*9880d681SAndroid Build Coastguard Worker /// \returns true if this class ID contains only SGPR registers isSGPRClassIDfinal98*9880d681SAndroid Build Coastguard Worker bool isSGPRClassID(unsigned RCID) const { 99*9880d681SAndroid Build Coastguard Worker return isSGPRClass(getRegClass(RCID)); 100*9880d681SAndroid Build Coastguard Worker } 101*9880d681SAndroid Build Coastguard Worker isSGPRRegfinal102*9880d681SAndroid Build Coastguard Worker bool isSGPRReg(const MachineRegisterInfo &MRI, unsigned Reg) const { 103*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC; 104*9880d681SAndroid Build Coastguard Worker if (TargetRegisterInfo::isVirtualRegister(Reg)) 105*9880d681SAndroid Build Coastguard Worker RC = MRI.getRegClass(Reg); 106*9880d681SAndroid Build Coastguard Worker else 107*9880d681SAndroid Build Coastguard Worker RC = getPhysRegClass(Reg); 108*9880d681SAndroid Build Coastguard Worker return isSGPRClass(RC); 109*9880d681SAndroid Build Coastguard Worker } 110*9880d681SAndroid Build Coastguard Worker 111*9880d681SAndroid Build Coastguard Worker /// \returns true if this class contains VGPR registers. 112*9880d681SAndroid Build Coastguard Worker bool hasVGPRs(const TargetRegisterClass *RC) const; 113*9880d681SAndroid Build Coastguard Worker 114*9880d681SAndroid Build Coastguard Worker /// returns true if this is a pseudoregister class combination of VGPRs and 115*9880d681SAndroid Build Coastguard Worker /// SGPRs for operand modeling. FIXME: We should set isAllocatable = 0 on 116*9880d681SAndroid Build Coastguard Worker /// them. isPseudoRegClassfinal117*9880d681SAndroid Build Coastguard Worker static bool isPseudoRegClass(const TargetRegisterClass *RC) { 118*9880d681SAndroid Build Coastguard Worker return RC == &AMDGPU::VS_32RegClass || RC == &AMDGPU::VS_64RegClass; 119*9880d681SAndroid Build Coastguard Worker } 120*9880d681SAndroid Build Coastguard Worker 121*9880d681SAndroid Build Coastguard Worker /// \returns A VGPR reg class with the same width as \p SRC 122*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *getEquivalentVGPRClass( 123*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *SRC) const; 124*9880d681SAndroid Build Coastguard Worker 125*9880d681SAndroid Build Coastguard Worker /// \returns A SGPR reg class with the same width as \p SRC 126*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *getEquivalentSGPRClass( 127*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *VRC) const; 128*9880d681SAndroid Build Coastguard Worker 129*9880d681SAndroid Build Coastguard Worker /// \returns The register class that is used for a sub-register of \p RC for 130*9880d681SAndroid Build Coastguard Worker /// the given \p SubIdx. If \p SubIdx equals NoSubRegister, \p RC will 131*9880d681SAndroid Build Coastguard Worker /// be returned. 132*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *getSubRegClass(const TargetRegisterClass *RC, 133*9880d681SAndroid Build Coastguard Worker unsigned SubIdx) const; 134*9880d681SAndroid Build Coastguard Worker 135*9880d681SAndroid Build Coastguard Worker bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC, 136*9880d681SAndroid Build Coastguard Worker unsigned DefSubReg, 137*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *SrcRC, 138*9880d681SAndroid Build Coastguard Worker unsigned SrcSubReg) const override; 139*9880d681SAndroid Build Coastguard Worker 140*9880d681SAndroid Build Coastguard Worker /// \p Channel This is the register channel (e.g. a value from 0-16), not the 141*9880d681SAndroid Build Coastguard Worker /// SubReg index. 142*9880d681SAndroid Build Coastguard Worker /// \returns The sub-register of Reg that is in Channel. 143*9880d681SAndroid Build Coastguard Worker unsigned getPhysRegSubReg(unsigned Reg, const TargetRegisterClass *SubRC, 144*9880d681SAndroid Build Coastguard Worker unsigned Channel) const; 145*9880d681SAndroid Build Coastguard Worker 146*9880d681SAndroid Build Coastguard Worker /// \returns True if operands defined with this operand type can accept 147*9880d681SAndroid Build Coastguard Worker /// a literal constant (i.e. any 32-bit immediate). 148*9880d681SAndroid Build Coastguard Worker bool opCanUseLiteralConstant(unsigned OpType) const; 149*9880d681SAndroid Build Coastguard Worker 150*9880d681SAndroid Build Coastguard Worker /// \returns True if operands defined with this operand type can accept 151*9880d681SAndroid Build Coastguard Worker /// an inline constant. i.e. An integer value in the range (-16, 64) or 152*9880d681SAndroid Build Coastguard Worker /// -4.0f, -2.0f, -1.0f, -0.5f, 0.0f, 0.5f, 1.0f, 2.0f, 4.0f. 153*9880d681SAndroid Build Coastguard Worker bool opCanUseInlineConstant(unsigned OpType) const; 154*9880d681SAndroid Build Coastguard Worker 155*9880d681SAndroid Build Coastguard Worker enum PreloadedValue { 156*9880d681SAndroid Build Coastguard Worker // SGPRS: 157*9880d681SAndroid Build Coastguard Worker PRIVATE_SEGMENT_BUFFER = 0, 158*9880d681SAndroid Build Coastguard Worker DISPATCH_PTR = 1, 159*9880d681SAndroid Build Coastguard Worker QUEUE_PTR = 2, 160*9880d681SAndroid Build Coastguard Worker KERNARG_SEGMENT_PTR = 3, 161*9880d681SAndroid Build Coastguard Worker DISPATCH_ID = 4, 162*9880d681SAndroid Build Coastguard Worker FLAT_SCRATCH_INIT = 5, 163*9880d681SAndroid Build Coastguard Worker WORKGROUP_ID_X = 10, 164*9880d681SAndroid Build Coastguard Worker WORKGROUP_ID_Y = 11, 165*9880d681SAndroid Build Coastguard Worker WORKGROUP_ID_Z = 12, 166*9880d681SAndroid Build Coastguard Worker PRIVATE_SEGMENT_WAVE_BYTE_OFFSET = 14, 167*9880d681SAndroid Build Coastguard Worker 168*9880d681SAndroid Build Coastguard Worker // VGPRS: 169*9880d681SAndroid Build Coastguard Worker FIRST_VGPR_VALUE = 15, 170*9880d681SAndroid Build Coastguard Worker WORKITEM_ID_X = FIRST_VGPR_VALUE, 171*9880d681SAndroid Build Coastguard Worker WORKITEM_ID_Y = 16, 172*9880d681SAndroid Build Coastguard Worker WORKITEM_ID_Z = 17 173*9880d681SAndroid Build Coastguard Worker }; 174*9880d681SAndroid Build Coastguard Worker 175*9880d681SAndroid Build Coastguard Worker /// \brief Returns the physical register that \p Value is stored in. 176*9880d681SAndroid Build Coastguard Worker unsigned getPreloadedValue(const MachineFunction &MF, 177*9880d681SAndroid Build Coastguard Worker enum PreloadedValue Value) const; 178*9880d681SAndroid Build Coastguard Worker 179*9880d681SAndroid Build Coastguard Worker /// \brief Give the maximum number of VGPRs that can be used by \p WaveCount 180*9880d681SAndroid Build Coastguard Worker /// concurrent waves. 181*9880d681SAndroid Build Coastguard Worker unsigned getNumVGPRsAllowed(unsigned WaveCount) const; 182*9880d681SAndroid Build Coastguard Worker 183*9880d681SAndroid Build Coastguard Worker /// \brief Give the maximum number of SGPRs that can be used by \p WaveCount 184*9880d681SAndroid Build Coastguard Worker /// concurrent waves. 185*9880d681SAndroid Build Coastguard Worker unsigned getNumSGPRsAllowed(const SISubtarget &ST, unsigned WaveCount) const; 186*9880d681SAndroid Build Coastguard Worker 187*9880d681SAndroid Build Coastguard Worker unsigned findUnusedRegister(const MachineRegisterInfo &MRI, 188*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC) const; 189*9880d681SAndroid Build Coastguard Worker getSGPR32PressureSetfinal190*9880d681SAndroid Build Coastguard Worker unsigned getSGPR32PressureSet() const { return SGPR32SetID; }; getVGPR32PressureSetfinal191*9880d681SAndroid Build Coastguard Worker unsigned getVGPR32PressureSet() const { return VGPR32SetID; }; 192*9880d681SAndroid Build Coastguard Worker 193*9880d681SAndroid Build Coastguard Worker bool isVGPR(const MachineRegisterInfo &MRI, unsigned Reg) const; 194*9880d681SAndroid Build Coastguard Worker 195*9880d681SAndroid Build Coastguard Worker private: 196*9880d681SAndroid Build Coastguard Worker void buildScratchLoadStore(MachineBasicBlock::iterator MI, 197*9880d681SAndroid Build Coastguard Worker unsigned LoadStoreOp, const MachineOperand *SrcDst, 198*9880d681SAndroid Build Coastguard Worker unsigned ScratchRsrcReg, unsigned ScratchOffset, 199*9880d681SAndroid Build Coastguard Worker int64_t Offset, 200*9880d681SAndroid Build Coastguard Worker RegScavenger *RS) const; 201*9880d681SAndroid Build Coastguard Worker }; 202*9880d681SAndroid Build Coastguard Worker 203*9880d681SAndroid Build Coastguard Worker } // End namespace llvm 204*9880d681SAndroid Build Coastguard Worker 205*9880d681SAndroid Build Coastguard Worker #endif 206