R600/SI: Move finding SGPR operand to move to separate function

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@218533 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Matt Arsenault 2014-09-26 17:55:06 +00:00
parent d991d2217b
commit 508b8db287
2 changed files with 71 additions and 63 deletions

View File

@ -1389,72 +1389,10 @@ void SIInstrInfo::legalizeOperands(MachineInstr *MI) const {
// XXX - Do any VOP3 instructions read VCC? // XXX - Do any VOP3 instructions read VCC?
// Legalize VOP3 // Legalize VOP3
if (isVOP3(MI->getOpcode())) { if (isVOP3(MI->getOpcode())) {
const MCInstrDesc &Desc = get(MI->getOpcode());
int VOP3Idx[3] = { Src0Idx, Src1Idx, Src2Idx }; int VOP3Idx[3] = { Src0Idx, Src1Idx, Src2Idx };
// Find the one SGPR operand we are allowed to use. // Find the one SGPR operand we are allowed to use.
unsigned SGPRReg = AMDGPU::NoRegister; unsigned SGPRReg = findUsedSGPR(MI, VOP3Idx);
for (const MachineOperand &MO : MI->implicit_operands()) {
// We only care about reads.
if (MO.isDef())
continue;
if (MO.getReg() == AMDGPU::VCC) {
SGPRReg = AMDGPU::VCC;
break;
}
if (MO.getReg() == AMDGPU::FLAT_SCR) {
SGPRReg = AMDGPU::FLAT_SCR;
break;
}
}
if (SGPRReg == AMDGPU::NoRegister) {
unsigned UsedSGPRs[3] = { AMDGPU::NoRegister };
// First we need to consider the instruction's operand requirements before
// legalizing. Some operands are required to be SGPRs, but we are still
// bound by the constant bus requirement to only use one.
//
// If the operand's class is an SGPR, we can never move it.
for (unsigned i = 0; i < 3; ++i) {
int Idx = VOP3Idx[i];
if (Idx == -1)
break;
const MachineOperand &MO = MI->getOperand(Idx);
if (RI.isSGPRClassID(Desc.OpInfo[Idx].RegClass))
SGPRReg = MO.getReg();
if (MO.isReg() && RI.isSGPRClass(MRI.getRegClass(MO.getReg())))
UsedSGPRs[i] = MO.getReg();
}
if (SGPRReg == AMDGPU::NoRegister) {
// We don't have a required SGPR operand, so we have a bit more freedom in
// selecting operands to move.
// Try to select the most used SGPR. If an SGPR is equal to one of the
// others, we choose that.
//
// e.g.
// V_FMA_F32 v0, s0, s0, s0 -> No moves
// V_FMA_F32 v0, s0, s1, s0 -> Move s1
if (UsedSGPRs[0] != AMDGPU::NoRegister) {
if (UsedSGPRs[0] == UsedSGPRs[1] || UsedSGPRs[0] == UsedSGPRs[2])
SGPRReg = UsedSGPRs[0];
}
if (SGPRReg == AMDGPU::NoRegister && UsedSGPRs[1] != AMDGPU::NoRegister) {
if (UsedSGPRs[1] == UsedSGPRs[2])
SGPRReg = UsedSGPRs[1];
}
}
}
for (unsigned i = 0; i < 3; ++i) { for (unsigned i = 0; i < 3; ++i) {
int Idx = VOP3Idx[i]; int Idx = VOP3Idx[i];
@ -2215,6 +2153,74 @@ void SIInstrInfo::addDescImplicitUseDef(const MCInstrDesc &NewDesc,
} }
} }
unsigned SIInstrInfo::findUsedSGPR(const MachineInstr *MI,
int OpIndices[3]) const {
const MCInstrDesc &Desc = get(MI->getOpcode());
// Find the one SGPR operand we are allowed to use.
unsigned SGPRReg = AMDGPU::NoRegister;
// First we need to consider the instruction's operand requirements before
// legalizing. Some operands are required to be SGPRs, such as implicit uses
// of VCC, but we are still bound by the constant bus requirement to only use
// one.
//
// If the operand's class is an SGPR, we can never move it.
for (const MachineOperand &MO : MI->implicit_operands()) {
// We only care about reads.
if (MO.isDef())
continue;
if (MO.getReg() == AMDGPU::VCC)
return AMDGPU::VCC;
if (MO.getReg() == AMDGPU::FLAT_SCR)
return AMDGPU::FLAT_SCR;
}
unsigned UsedSGPRs[3] = { AMDGPU::NoRegister };
const MachineRegisterInfo &MRI = MI->getParent()->getParent()->getRegInfo();
for (unsigned i = 0; i < 3; ++i) {
int Idx = OpIndices[i];
if (Idx == -1)
break;
const MachineOperand &MO = MI->getOperand(Idx);
if (RI.isSGPRClassID(Desc.OpInfo[Idx].RegClass))
SGPRReg = MO.getReg();
if (MO.isReg() && RI.isSGPRClass(MRI.getRegClass(MO.getReg())))
UsedSGPRs[i] = MO.getReg();
}
if (SGPRReg != AMDGPU::NoRegister)
return SGPRReg;
// We don't have a required SGPR operand, so we have a bit more freedom in
// selecting operands to move.
// Try to select the most used SGPR. If an SGPR is equal to one of the
// others, we choose that.
//
// e.g.
// V_FMA_F32 v0, s0, s0, s0 -> No moves
// V_FMA_F32 v0, s0, s1, s0 -> Move s1
if (UsedSGPRs[0] != AMDGPU::NoRegister) {
if (UsedSGPRs[0] == UsedSGPRs[1] || UsedSGPRs[0] == UsedSGPRs[2])
SGPRReg = UsedSGPRs[0];
}
if (SGPRReg == AMDGPU::NoRegister && UsedSGPRs[1] != AMDGPU::NoRegister) {
if (UsedSGPRs[1] == UsedSGPRs[2])
SGPRReg = UsedSGPRs[1];
}
return SGPRReg;
}
MachineInstrBuilder SIInstrInfo::buildIndirectWrite( MachineInstrBuilder SIInstrInfo::buildIndirectWrite(
MachineBasicBlock *MBB, MachineBasicBlock *MBB,
MachineBasicBlock::iterator I, MachineBasicBlock::iterator I,

View File

@ -55,6 +55,8 @@ private:
void addDescImplicitUseDef(const MCInstrDesc &Desc, MachineInstr *MI) const; void addDescImplicitUseDef(const MCInstrDesc &Desc, MachineInstr *MI) const;
unsigned findUsedSGPR(const MachineInstr *MI, int OpIndices[3]) const;
public: public:
explicit SIInstrInfo(const AMDGPUSubtarget &st); explicit SIInstrInfo(const AMDGPUSubtarget &st);