31 Reserved.
set(AMDGPU::EXEC);
35 Reserved.
set(AMDGPU::EXEC_LO);
36 Reserved.
set(AMDGPU::EXEC_HI);
38 Reserved.
set(AMDGPU::INDIRECT_BASE_ADDR);
39 Reserved.
set(AMDGPU::FLAT_SCR);
40 Reserved.
set(AMDGPU::FLAT_SCR_LO);
41 Reserved.
set(AMDGPU::FLAT_SCR_HI);
44 Reserved.
set(AMDGPU::VGPR255);
45 Reserved.
set(AMDGPU::VGPR254);
50 unsigned NumSGPRs = AMDGPU::SGPR_32RegClass.getNumRegs();
55 for (
unsigned i = Limit; i < NumSGPRs; ++i) {
56 unsigned Reg = AMDGPU::SGPR_32RegClass.getRegister(i);
76 for (regclass_iterator
I = regclass_begin(), E = regclass_end();
79 unsigned NumSubRegs = std::max((
int)(*I)->getSize() / 4, 1);
83 Limit = SGPRLimit / NumSubRegs;
85 Limit = VGPRLimit / NumSubRegs;
88 const int *Sets = getRegClassPressureSets(*
I);
90 for (
unsigned i = 0; Sets[i] != -1; ++i) {
91 if (Sets[i] == (
int)Idx)
105 case AMDGPU::SI_SPILL_S512_SAVE:
106 case AMDGPU::SI_SPILL_S512_RESTORE:
107 case AMDGPU::SI_SPILL_V512_SAVE:
108 case AMDGPU::SI_SPILL_V512_RESTORE:
110 case AMDGPU::SI_SPILL_S256_SAVE:
111 case AMDGPU::SI_SPILL_S256_RESTORE:
112 case AMDGPU::SI_SPILL_V256_SAVE:
113 case AMDGPU::SI_SPILL_V256_RESTORE:
115 case AMDGPU::SI_SPILL_S128_SAVE:
116 case AMDGPU::SI_SPILL_S128_RESTORE:
117 case AMDGPU::SI_SPILL_V128_SAVE:
118 case AMDGPU::SI_SPILL_V128_RESTORE:
120 case AMDGPU::SI_SPILL_V96_SAVE:
121 case AMDGPU::SI_SPILL_V96_RESTORE:
123 case AMDGPU::SI_SPILL_S64_SAVE:
124 case AMDGPU::SI_SPILL_S64_RESTORE:
125 case AMDGPU::SI_SPILL_V64_SAVE:
126 case AMDGPU::SI_SPILL_V64_RESTORE:
128 case AMDGPU::SI_SPILL_S32_SAVE:
129 case AMDGPU::SI_SPILL_S32_RESTORE:
130 case AMDGPU::SI_SPILL_V32_SAVE:
131 case AMDGPU::SI_SPILL_V32_RESTORE:
138 unsigned LoadStoreOp,
140 unsigned ScratchRsrcReg,
141 unsigned ScratchOffset,
151 bool IsLoad = TII->get(LoadStoreOp).mayLoad();
153 bool RanOutOfSGPRs =
false;
154 unsigned SOffset = ScratchOffset;
157 unsigned Size = NumSubRegs * 4;
159 if (!isUInt<12>(Offset + Size)) {
161 if (SOffset == AMDGPU::NoRegister) {
162 RanOutOfSGPRs =
true;
163 SOffset = AMDGPU::SGPR0;
165 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::S_ADD_U32), SOffset)
166 .addReg(ScratchOffset)
172 Ctx.
emitError(
"Ran out of SGPRs for spilling VGPRS");
174 for (
unsigned i = 0, e = NumSubRegs; i != e; ++i, Offset += 4) {
175 unsigned SubReg = NumSubRegs > 1 ?
178 bool IsKill = (i == e - 1);
180 BuildMI(*MBB, MI, DL, TII->get(LoadStoreOp))
193 int SPAdj,
unsigned FIOperandNum,
204 int Index = MI->getOperand(FIOperandNum).
getIndex();
206 switch (MI->getOpcode()) {
208 case AMDGPU::SI_SPILL_S512_SAVE:
209 case AMDGPU::SI_SPILL_S256_SAVE:
210 case AMDGPU::SI_SPILL_S128_SAVE:
211 case AMDGPU::SI_SPILL_S64_SAVE:
212 case AMDGPU::SI_SPILL_S32_SAVE: {
215 for (
unsigned i = 0, e = NumSubRegs; i < e; ++i) {
217 &AMDGPU::SGPR_32RegClass, i);
221 if (Spill.
VGPR == AMDGPU::NoRegister) {
223 Ctx.
emitError(
"Ran out of VGPRs for spilling SGPR");
238 case AMDGPU::SI_SPILL_S512_RESTORE:
239 case AMDGPU::SI_SPILL_S256_RESTORE:
240 case AMDGPU::SI_SPILL_S128_RESTORE:
241 case AMDGPU::SI_SPILL_S64_RESTORE:
242 case AMDGPU::SI_SPILL_S32_RESTORE: {
245 for (
unsigned i = 0, e = NumSubRegs; i < e; ++i) {
247 &AMDGPU::SGPR_32RegClass, i);
251 if (Spill.
VGPR == AMDGPU::NoRegister) {
253 Ctx.
emitError(
"Ran out of VGPRs for spilling SGPR");
279 MI->eraseFromParent();
284 case AMDGPU::SI_SPILL_V512_SAVE:
285 case AMDGPU::SI_SPILL_V256_SAVE:
286 case AMDGPU::SI_SPILL_V128_SAVE:
287 case AMDGPU::SI_SPILL_V96_SAVE:
288 case AMDGPU::SI_SPILL_V64_SAVE:
289 case AMDGPU::SI_SPILL_V32_SAVE:
290 buildScratchLoadStore(MI, AMDGPU::BUFFER_STORE_DWORD_OFFSET,
294 FrameInfo->getObjectOffset(Index), RS);
295 MI->eraseFromParent();
297 case AMDGPU::SI_SPILL_V32_RESTORE:
298 case AMDGPU::SI_SPILL_V64_RESTORE:
299 case AMDGPU::SI_SPILL_V96_RESTORE:
300 case AMDGPU::SI_SPILL_V128_RESTORE:
301 case AMDGPU::SI_SPILL_V256_RESTORE:
302 case AMDGPU::SI_SPILL_V512_RESTORE: {
303 buildScratchLoadStore(MI, AMDGPU::BUFFER_LOAD_DWORD_OFFSET,
307 FrameInfo->getObjectOffset(Index), RS);
308 MI->eraseFromParent();
313 int64_t Offset = FrameInfo->getObjectOffset(Index);
316 unsigned TmpReg = RS->
scavengeRegister(&AMDGPU::VGPR_32RegClass, MI, SPAdj);
317 BuildMI(*MBB, MI, MI->getDebugLoc(),
318 TII->get(AMDGPU::V_MOV_B32_e32), TmpReg)
330 case MVT::i32:
return &AMDGPU::VGPR_32RegClass;
335 return getEncodingValue(Reg) & 0xff;
342 &AMDGPU::VGPR_32RegClass,
343 &AMDGPU::SReg_32RegClass,
344 &AMDGPU::VReg_64RegClass,
345 &AMDGPU::SReg_64RegClass,
346 &AMDGPU::VReg_96RegClass,
347 &AMDGPU::VReg_128RegClass,
348 &AMDGPU::SReg_128RegClass,
349 &AMDGPU::VReg_256RegClass,
350 &AMDGPU::SReg_256RegClass,
351 &AMDGPU::VReg_512RegClass,
352 &AMDGPU::SReg_512RegClass
364 return getCommonSubClass(&AMDGPU::VGPR_32RegClass, RC) ||
365 getCommonSubClass(&AMDGPU::VReg_64RegClass, RC) ||
366 getCommonSubClass(&AMDGPU::VReg_96RegClass, RC) ||
367 getCommonSubClass(&AMDGPU::VReg_128RegClass, RC) ||
368 getCommonSubClass(&AMDGPU::VReg_256RegClass, RC) ||
369 getCommonSubClass(&AMDGPU::VReg_512RegClass, RC);
376 }
else if (SRC == &AMDGPU::SCCRegRegClass) {
377 return &AMDGPU::VCCRegRegClass;
378 }
else if (getCommonSubClass(SRC, &AMDGPU::SGPR_32RegClass)) {
379 return &AMDGPU::VGPR_32RegClass;
380 }
else if (getCommonSubClass(SRC, &AMDGPU::SGPR_64RegClass)) {
381 return &AMDGPU::VReg_64RegClass;
382 }
else if (getCommonSubClass(SRC, &AMDGPU::SReg_128RegClass)) {
383 return &AMDGPU::VReg_128RegClass;
384 }
else if (getCommonSubClass(SRC, &AMDGPU::SReg_256RegClass)) {
385 return &AMDGPU::VReg_256RegClass;
386 }
else if (getCommonSubClass(SRC, &AMDGPU::SReg_512RegClass)) {
387 return &AMDGPU::VReg_512RegClass;
394 if (SubIdx == AMDGPU::NoSubRegister)
400 return &AMDGPU::SGPR_32RegClass;
402 return &AMDGPU::VGPR_32RegClass;
408 unsigned Channel)
const {
413 case 0:
return AMDGPU::VCC_LO;
414 case 1:
return AMDGPU::VCC_HI;
418 case AMDGPU::FLAT_SCR:
421 return AMDGPU::FLAT_SCR_LO;
423 return AMDGPU::FLAT_SCR_HI;
432 return AMDGPU::EXEC_LO;
434 return AMDGPU::EXEC_HI;
447 assert(Channel == 0);
472 return AMDGPU::SReg_32RegClass.getRegister(MFI->
NumUserSGPRs + 0);
474 return AMDGPU::SReg_32RegClass.getRegister(MFI->
NumUserSGPRs + 1);
476 return AMDGPU::SReg_32RegClass.getRegister(MFI->
NumUserSGPRs + 2);
480 return AMDGPU::SReg_32RegClass.getRegister(MFI->
NumUserSGPRs + 4);
482 return AMDGPU::SGPR2_SGPR3;
484 return AMDGPU::SGPR0_SGPR1;
486 return AMDGPU::VGPR0;
488 return AMDGPU::VGPR1;
490 return AMDGPU::VGPR2;
506 return AMDGPU::NoRegister;
525 unsigned WaveCount)
const {
const MachineFunction * getParent() const
getParent - Return the MachineFunction containing this basic block.
bool opCanUseInlineConstant(unsigned OpType) const
Interface definition for SIRegisterInfo.
unsigned getPhysRegSubReg(unsigned Reg, const TargetRegisterClass *SubRC, unsigned Channel) const
Channel This is the register channel (e.g.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
unsigned getRegister(unsigned i) const
getRegister - Return the specified register in the class.
void ChangeToRegister(unsigned Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isDebug=false)
ChangeToRegister - Replace this operand with a new register operand of the specified value...
unsigned getRegPressureSetLimit(const MachineFunction &MF, unsigned Idx) const override
static bool isVirtualRegister(unsigned Reg)
isVirtualRegister - Return true if the specified register number is in the virtual register namespace...
bool hasVGPRs(const TargetRegisterClass *RC) const
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
const MCPhysReg * iterator
static unsigned getNumSubRegsForSpillOp(unsigned Op)
BitVector getReservedRegs(const MachineFunction &MF) const override
unsigned getSize() const
getSize - Return the size of the register in bytes, which is also the size of a stack slot allocated ...
bool hasSGPRInitBug() const
const TargetRegisterClass * getCFGStructurizerRegClass(MVT VT) const override
get the register class of the specified type to use in the CFGStructurizer
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const HexagonInstrInfo * TII
unsigned getShaderType() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
MachineOperand * getNamedOperand(MachineInstr &MI, unsigned OperandName) const
Returns the operand named Op.
bool isSGPRClass(const TargetRegisterClass *RC) const
iterator begin() const
begin/end - Return all of the registers in this class.
Reg
All possible values of the reg field in the ModR/M byte.
bool requiresRegisterScavenging(const MachineFunction &Fn) const override
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
const MCInstrDesc & getMCOpcodeFromPseudo(unsigned Opcode) const
Return the descriptor of the target-specific machine instruction that corresponds to the specified ps...
const MachineInstrBuilder & addImm(int64_t Val) const
addImm - Add a new immediate operand.
void emitError(unsigned LocCookie, const Twine &ErrorStr)
emitError - Emit an error message to the currently installed error handler with optional location inf...
unsigned getHWRegIndex(unsigned Reg) const override
bool hasStackObjects() const
Return true if there are any stack objects in this function.
bool isImmOperandLegal(const MachineInstr *MI, unsigned OpNo, const MachineOperand &MO) const
Operand with register or inline constant.
Generation getGeneration() const
unsigned getKillRegState(bool B)
void ChangeToImmediate(int64_t ImmVal)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value...
unsigned getDefRegState(bool B)
bundle_iterator< MachineInstr, instr_iterator > iterator
MVT - Machine Value Type.
This is an important class for using LLVM in a threaded context.
unsigned getNumVGPRsAllowed(unsigned WaveCount) const
Give the maximum number of VGPRs that can be used by WaveCount concurrent waves.
unsigned getMaxWavesPerCU() const
unsigned getPreloadedValue(const MachineFunction &MF, enum PreloadedValue Value) const
Returns the physical register that Value is stored in.
MCRegAliasIterator enumerates all registers aliasing Reg.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
unsigned findUnusedRegister(const MachineRegisterInfo &MRI, const TargetRegisterClass *RC) const
Returns a register that is not used at any point in the function.
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
BuildMI - Builder interface.
const TargetRegisterClass * getEquivalentVGPRClass(const TargetRegisterClass *SRC) const
bool opCanUseLiteralConstant(unsigned OpType) const
MachineOperand class - Representation of each machine instruction operand.
SpilledReg getSpilledReg(MachineFunction *MF, unsigned FrameIndex, unsigned SubIdx)
MachineFrameInfo * getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
unsigned getNumSGPRsAllowed(AMDGPUSubtarget::Generation gen, unsigned WaveCount) const
Give the maximum number of SGPRs that can be used by WaveCount concurrent waves.
const TargetRegisterClass * getSubRegClass(const TargetRegisterClass *RC, unsigned SubIdx) const
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
const TargetRegisterClass * getPhysRegClass(unsigned Reg) const
Return the 'base' register class for this register.
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
Interface definition for SIInstrInfo.
unsigned ScratchOffsetReg
Operand with register or 32-bit immediate.
unsigned getReg() const
getReg - Returns the register number.
virtual const TargetInstrInfo * getInstrInfo() const
LLVM Value Representation.
void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, unsigned FIOperandNum, RegScavenger *RS) const override
bool isPhysRegUsed(unsigned Reg) const
isPhysRegUsed - Return true if the specified register is used in this function.
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
addReg - Add a new virtual register operand...
void insertNOPs(MachineBasicBlock::iterator MI, int Count) const
unsigned scavengeRegister(const TargetRegisterClass *RegClass, MachineBasicBlock::iterator I, int SPAdj)
Make a register of the specific register class available and do the appropriate bookkeeping.