R600/SI: Move finding SGPR operand to move to separate function
authorMatt Arsenault <Matthew.Arsenault@amd.com>
Fri, 26 Sep 2014 17:55:06 +0000 (17:55 +0000)
committerMatt Arsenault <Matthew.Arsenault@amd.com>
Fri, 26 Sep 2014 17:55:06 +0000 (17:55 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@218533 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/R600/SIInstrInfo.cpp
lib/Target/R600/SIInstrInfo.h

index c748228f3426266db6416823e3ad8cfa889f1a2f..ed4884f037b72774c0dda76b8f2903dc57319841 100644 (file)
@@ -1389,72 +1389,10 @@ void SIInstrInfo::legalizeOperands(MachineInstr *MI) const {
   // XXX - Do any VOP3 instructions read VCC?
   // Legalize VOP3
   if (isVOP3(MI->getOpcode())) {
-    const MCInstrDesc &Desc = get(MI->getOpcode());
-
     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())
-        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];
-        }
-      }
-    }
+    unsigned SGPRReg = findUsedSGPR(MI, VOP3Idx);
 
     for (unsigned i = 0; i < 3; ++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(
                                    MachineBasicBlock *MBB,
                                    MachineBasicBlock::iterator I,
index 9370384ecb76a5e2af4f5437b39c5aece18d1a27..7454f8d687deeeca31d02791219de30122c14433 100644 (file)
@@ -55,6 +55,8 @@ private:
 
   void addDescImplicitUseDef(const MCInstrDesc &Desc, MachineInstr *MI) const;
 
+  unsigned findUsedSGPR(const MachineInstr *MI, int OpIndices[3]) const;
+
 public:
   explicit SIInstrInfo(const AMDGPUSubtarget &st);