summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorMatt Arsenault <Matthew.Arsenault@amd.com>2014-09-26 17:55:03 +0000
committerMatt Arsenault <Matthew.Arsenault@amd.com>2014-09-26 17:55:03 +0000
commit6a0919fb9b15c259cf0519d98996f98ff06248fe (patch)
treea3a82228f8640edc57ed3c5563a8bcbb6f245e38 /llvm/lib
parentcb0ac3d1fbe29e6c0be2a24c56c06a3b26ce0e39 (diff)
downloadbcm5719-llvm-6a0919fb9b15c259cf0519d98996f98ff06248fe.tar.gz
bcm5719-llvm-6a0919fb9b15c259cf0519d98996f98ff06248fe.zip
R600/SI Allow same SGPR to be used for multiple operands
Instead of moving the first SGPR that is different than the first, legalize the operand that requires the fewest moves if one SGPR is used for multiple operands. This saves extra moves and is also required for some instructions which require that the same operand be used for multiple operands. llvm-svn: 218532
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/R600/SIInstrInfo.cpp37
1 files changed, 32 insertions, 5 deletions
diff --git a/llvm/lib/Target/R600/SIInstrInfo.cpp b/llvm/lib/Target/R600/SIInstrInfo.cpp
index ed8d9793af7..c748228f342 100644
--- a/llvm/lib/Target/R600/SIInstrInfo.cpp
+++ b/llvm/lib/Target/R600/SIInstrInfo.cpp
@@ -1390,10 +1390,12 @@ void SIInstrInfo::legalizeOperands(MachineInstr *MI) const {
// Legalize VOP3
if (isVOP3(MI->getOpcode())) {
const MCInstrDesc &Desc = get(MI->getOpcode());
- unsigned SGPRReg = AMDGPU::NoRegister;
int VOP3Idx[3] = { Src0Idx, Src1Idx, Src2Idx };
+ // Find the one SGPR operand we are allowed to use.
+ unsigned SGPRReg = AMDGPU::NoRegister;
+
for (const MachineOperand &MO : MI->implicit_operands()) {
// We only care about reads.
if (MO.isDef())
@@ -1410,8 +1412,9 @@ void SIInstrInfo::legalizeOperands(MachineInstr *MI) const {
}
}
-
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.
@@ -1422,9 +1425,33 @@ void SIInstrInfo::legalizeOperands(MachineInstr *MI) const {
if (Idx == -1)
break;
- if (RI.isSGPRClassID(Desc.OpInfo[Idx].RegClass)) {
- SGPRReg = MI->getOperand(Idx).getReg();
- 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];
}
}
}
OpenPOWER on IntegriCloud