| //===-- SIRegisterInfo.h - SI Register Info Interface ----------*- C++ -*--===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| /// \file |
| /// Interface definition for SIRegisterInfo |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLVM_LIB_TARGET_AMDGPU_SIREGISTERINFO_H |
| #define LLVM_LIB_TARGET_AMDGPU_SIREGISTERINFO_H |
| |
| #include "AMDGPURegisterInfo.h" |
| #include "SIDefines.h" |
| #include "llvm/CodeGen/MachineRegisterInfo.h" |
| |
| namespace llvm { |
| |
| class GCNSubtarget; |
| class LiveIntervals; |
| class MachineRegisterInfo; |
| class SIMachineFunctionInfo; |
| |
| class SIRegisterInfo final : public AMDGPURegisterInfo { |
| private: |
| unsigned SGPRSetID; |
| unsigned VGPRSetID; |
| BitVector SGPRPressureSets; |
| BitVector VGPRPressureSets; |
| bool SpillSGPRToVGPR; |
| bool SpillSGPRToSMEM; |
| |
| void classifyPressureSet(unsigned PSetID, unsigned Reg, |
| BitVector &PressureSets) const; |
| public: |
| SIRegisterInfo(const GCNSubtarget &ST); |
| |
| bool spillSGPRToVGPR() const { |
| return SpillSGPRToVGPR; |
| } |
| |
| bool spillSGPRToSMEM() const { |
| return SpillSGPRToSMEM; |
| } |
| |
| /// Return the end register initially reserved for the scratch buffer in case |
| /// spilling is needed. |
| unsigned reservedPrivateSegmentBufferReg(const MachineFunction &MF) const; |
| |
| /// Return the end register initially reserved for the scratch wave offset in |
| /// case spilling is needed. |
| unsigned reservedPrivateSegmentWaveByteOffsetReg( |
| const MachineFunction &MF) const; |
| |
| unsigned reservedStackPtrOffsetReg(const MachineFunction &MF) const; |
| |
| BitVector getReservedRegs(const MachineFunction &MF) const override; |
| |
| const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override; |
| const MCPhysReg *getCalleeSavedRegsViaCopy(const MachineFunction *MF) const; |
| const uint32_t *getCallPreservedMask(const MachineFunction &MF, |
| CallingConv::ID) const override; |
| |
| // Stack access is very expensive. CSRs are also the high registers, and we |
| // want to minimize the number of used registers. |
| unsigned getCSRFirstUseCost() const override { |
| return 100; |
| } |
| |
| unsigned getFrameRegister(const MachineFunction &MF) const override; |
| |
| bool requiresRegisterScavenging(const MachineFunction &Fn) const override; |
| |
| bool requiresFrameIndexScavenging(const MachineFunction &MF) const override; |
| bool requiresFrameIndexReplacementScavenging( |
| const MachineFunction &MF) const override; |
| bool requiresVirtualBaseRegisters(const MachineFunction &Fn) const override; |
| bool trackLivenessAfterRegAlloc(const MachineFunction &MF) const override; |
| |
| int64_t getMUBUFInstrOffset(const MachineInstr *MI) const; |
| |
| int64_t getFrameIndexInstrOffset(const MachineInstr *MI, |
| int Idx) const override; |
| |
| bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override; |
| |
| void materializeFrameBaseRegister(MachineBasicBlock *MBB, |
| unsigned BaseReg, int FrameIdx, |
| int64_t Offset) const override; |
| |
| void resolveFrameIndex(MachineInstr &MI, unsigned BaseReg, |
| int64_t Offset) const override; |
| |
| bool isFrameOffsetLegal(const MachineInstr *MI, unsigned BaseReg, |
| int64_t Offset) const override; |
| |
| const TargetRegisterClass *getPointerRegClass( |
| const MachineFunction &MF, unsigned Kind = 0) const override; |
| |
| /// If \p OnlyToVGPR is true, this will only succeed if this |
| bool spillSGPR(MachineBasicBlock::iterator MI, |
| int FI, RegScavenger *RS, |
| bool OnlyToVGPR = false) const; |
| |
| bool restoreSGPR(MachineBasicBlock::iterator MI, |
| int FI, RegScavenger *RS, |
| bool OnlyToVGPR = false) const; |
| |
| void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, |
| unsigned FIOperandNum, |
| RegScavenger *RS) const override; |
| |
| bool eliminateSGPRToVGPRSpillFrameIndex(MachineBasicBlock::iterator MI, |
| int FI, RegScavenger *RS) const; |
| |
| StringRef getRegAsmName(unsigned Reg) const override; |
| |
| unsigned getHWRegIndex(unsigned Reg) const { |
| return getEncodingValue(Reg) & 0xff; |
| } |
| |
| /// Return the 'base' register class for this register. |
| /// e.g. SGPR0 => SReg_32, VGPR => VGPR_32 SGPR0_SGPR1 -> SReg_32, etc. |
| const TargetRegisterClass *getPhysRegClass(unsigned Reg) const; |
| |
| /// \returns true if this class contains only SGPR registers |
| bool isSGPRClass(const TargetRegisterClass *RC) const { |
| return !hasVGPRs(RC); |
| } |
| |
| /// \returns true if this class ID contains only SGPR registers |
| bool isSGPRClassID(unsigned RCID) const { |
| return isSGPRClass(getRegClass(RCID)); |
| } |
| |
| bool isSGPRReg(const MachineRegisterInfo &MRI, unsigned Reg) const { |
| const TargetRegisterClass *RC; |
| if (TargetRegisterInfo::isVirtualRegister(Reg)) |
| RC = MRI.getRegClass(Reg); |
| else |
| RC = getPhysRegClass(Reg); |
| return isSGPRClass(RC); |
| } |
| |
| /// \returns true if this class contains VGPR registers. |
| bool hasVGPRs(const TargetRegisterClass *RC) const; |
| |
| /// \returns A VGPR reg class with the same width as \p SRC |
| const TargetRegisterClass *getEquivalentVGPRClass( |
| const TargetRegisterClass *SRC) const; |
| |
| /// \returns A SGPR reg class with the same width as \p SRC |
| const TargetRegisterClass *getEquivalentSGPRClass( |
| const TargetRegisterClass *VRC) const; |
| |
| /// \returns The register class that is used for a sub-register of \p RC for |
| /// the given \p SubIdx. If \p SubIdx equals NoSubRegister, \p RC will |
| /// be returned. |
| const TargetRegisterClass *getSubRegClass(const TargetRegisterClass *RC, |
| unsigned SubIdx) const; |
| |
| bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC, |
| unsigned DefSubReg, |
| const TargetRegisterClass *SrcRC, |
| unsigned SrcSubReg) const override; |
| |
| /// \returns True if operands defined with this operand type can accept |
| /// a literal constant (i.e. any 32-bit immediate). |
| bool opCanUseLiteralConstant(unsigned OpType) const { |
| // TODO: 64-bit operands have extending behavior from 32-bit literal. |
| return OpType >= AMDGPU::OPERAND_REG_IMM_FIRST && |
| OpType <= AMDGPU::OPERAND_REG_IMM_LAST; |
| } |
| |
| /// \returns True if operands defined with this operand type can accept |
| /// an inline constant. i.e. An integer value in the range (-16, 64) or |
| /// -4.0f, -2.0f, -1.0f, -0.5f, 0.0f, 0.5f, 1.0f, 2.0f, 4.0f. |
| bool opCanUseInlineConstant(unsigned OpType) const { |
| return OpType >= AMDGPU::OPERAND_SRC_FIRST && |
| OpType <= AMDGPU::OPERAND_SRC_LAST; |
| } |
| |
| unsigned findUnusedRegister(const MachineRegisterInfo &MRI, |
| const TargetRegisterClass *RC, |
| const MachineFunction &MF) const; |
| |
| unsigned getSGPRPressureSet() const { return SGPRSetID; }; |
| unsigned getVGPRPressureSet() const { return VGPRSetID; }; |
| |
| const TargetRegisterClass *getRegClassForReg(const MachineRegisterInfo &MRI, |
| unsigned Reg) const; |
| bool isVGPR(const MachineRegisterInfo &MRI, unsigned Reg) const; |
| |
| bool isSGPRPressureSet(unsigned SetID) const { |
| return SGPRPressureSets.test(SetID) && !VGPRPressureSets.test(SetID); |
| } |
| bool isVGPRPressureSet(unsigned SetID) const { |
| return VGPRPressureSets.test(SetID) && !SGPRPressureSets.test(SetID); |
| } |
| |
| ArrayRef<int16_t> getRegSplitParts(const TargetRegisterClass *RC, |
| unsigned EltSize) const; |
| |
| bool shouldCoalesce(MachineInstr *MI, |
| const TargetRegisterClass *SrcRC, |
| unsigned SubReg, |
| const TargetRegisterClass *DstRC, |
| unsigned DstSubReg, |
| const TargetRegisterClass *NewRC, |
| LiveIntervals &LIS) const override; |
| |
| unsigned getRegPressureLimit(const TargetRegisterClass *RC, |
| MachineFunction &MF) const override; |
| |
| unsigned getRegPressureSetLimit(const MachineFunction &MF, |
| unsigned Idx) const override; |
| |
| const int *getRegUnitPressureSets(unsigned RegUnit) const override; |
| |
| unsigned getReturnAddressReg(const MachineFunction &MF) const; |
| |
| const TargetRegisterClass * |
| getConstrainedRegClassForOperand(const MachineOperand &MO, |
| const MachineRegisterInfo &MRI) const override; |
| |
| private: |
| void buildSpillLoadStore(MachineBasicBlock::iterator MI, |
| unsigned LoadStoreOp, |
| int Index, |
| unsigned ValueReg, |
| bool ValueIsKill, |
| unsigned ScratchRsrcReg, |
| unsigned ScratchOffsetReg, |
| int64_t InstrOffset, |
| MachineMemOperand *MMO, |
| RegScavenger *RS) const; |
| }; |
| |
| } // End namespace llvm |
| |
| #endif |