AMDGPU: Refactor isVGPRToSGPRCopy
authorMatt Arsenault <Matthew.Arsenault@amd.com>
Tue, 13 Oct 2015 00:07:54 +0000 (00:07 +0000)
committerMatt Arsenault <Matthew.Arsenault@amd.com>
Tue, 13 Oct 2015 00:07:54 +0000 (00:07 +0000)
It should now correctly handle physical registers and make
it easier to identify the other direction.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@250132 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/AMDGPU/SIFixSGPRCopies.cpp

index 8aa6abf7ca7bba32f6168a17bd50e32ecd4f1ce3..b6941c1cc759133803a9ff04bf40e92297acdd35 100644 (file)
@@ -85,8 +85,18 @@ class SIFixSGPRCopies : public MachineFunctionPass {
 
 private:
   static char ID;
-  bool isVGPRToSGPRCopy(const MachineInstr &Copy, const SIRegisterInfo *TRI,
-                        const MachineRegisterInfo &MRI) const;
+  std::pair<const TargetRegisterClass *, const TargetRegisterClass *>
+  getCopyRegClasses(const MachineInstr &Copy,
+                    const SIRegisterInfo &TRI,
+                    const MachineRegisterInfo &MRI) const;
+
+  bool isVGPRToSGPRCopy(const TargetRegisterClass *SrcRC,
+                        const TargetRegisterClass *DstRC,
+                        const SIRegisterInfo &TRI) const;
+
+  bool isSGPRToVGPRCopy(const TargetRegisterClass *SrcRC,
+                        const TargetRegisterClass *DstRC,
+                        const SIRegisterInfo &TRI) const;
 
 public:
   SIFixSGPRCopies(TargetMachine &tm) : MachineFunctionPass(ID) { }
@@ -124,27 +134,39 @@ static bool hasVGPROperands(const MachineInstr &MI, const SIRegisterInfo *TRI) {
   return false;
 }
 
-bool SIFixSGPRCopies::isVGPRToSGPRCopy(const MachineInstr &Copy,
-                                      const SIRegisterInfo *TRI,
-                                      const MachineRegisterInfo &MRI) const {
-
+std::pair<const TargetRegisterClass *, const TargetRegisterClass *>
+SIFixSGPRCopies::getCopyRegClasses(const MachineInstr &Copy,
+                                   const SIRegisterInfo &TRI,
+                                   const MachineRegisterInfo &MRI) const {
   unsigned DstReg = Copy.getOperand(0).getReg();
   unsigned SrcReg = Copy.getOperand(1).getReg();
-  unsigned SrcSubReg = Copy.getOperand(1).getSubReg();
 
-  if (!TargetRegisterInfo::isVirtualRegister(DstReg)) {
-    // If the destination register is a physical register there isn't really
-    // much we can do to fix this.
-    return false;
-  }
+  const TargetRegisterClass *SrcRC =
+    TargetRegisterInfo::isVirtualRegister(SrcReg) ?
+    MRI.getRegClass(SrcReg) :
+    TRI.getPhysRegClass(SrcReg);
+
+  // We don't really care about the subregister here.
+  // SrcRC = TRI.getSubRegClass(SrcRC, Copy.getOperand(1).getSubReg());
 
-  if (!TargetRegisterInfo::isVirtualRegister(SrcReg))
-    return false;
+  const TargetRegisterClass *DstRC =
+    TargetRegisterInfo::isVirtualRegister(DstReg) ?
+    MRI.getRegClass(DstReg) :
+    TRI.getPhysRegClass(DstReg);
 
-  const TargetRegisterClass *DstRC = MRI.getRegClass(DstReg);
-  const TargetRegisterClass *SrcRC
-    = TRI->getSubRegClass(MRI.getRegClass(SrcReg), SrcSubReg);
-  return TRI->isSGPRClass(DstRC) && TRI->hasVGPRs(SrcRC);
+  return std::make_pair(SrcRC, DstRC);
+}
+
+bool SIFixSGPRCopies::isVGPRToSGPRCopy(const TargetRegisterClass *SrcRC,
+                                       const TargetRegisterClass *DstRC,
+                                       const SIRegisterInfo &TRI) const {
+  return TRI.isSGPRClass(DstRC) && TRI.hasVGPRs(SrcRC);
+}
+
+bool SIFixSGPRCopies::isSGPRToVGPRCopy(const TargetRegisterClass *SrcRC,
+                                       const TargetRegisterClass *DstRC,
+                                       const SIRegisterInfo &TRI) const {
+  return TRI.isSGPRClass(SrcRC) && TRI.hasVGPRs(DstRC);
 }
 
 bool SIFixSGPRCopies::runOnMachineFunction(MachineFunction &MF) {
@@ -165,7 +187,14 @@ bool SIFixSGPRCopies::runOnMachineFunction(MachineFunction &MF) {
       default:
         continue;
       case AMDGPU::COPY: {
-        if (isVGPRToSGPRCopy(MI, TRI, MRI)) {
+        // If the destination register is a physical register there isn't really
+        // much we can do to fix this.
+        if (!TargetRegisterInfo::isVirtualRegister(MI.getOperand(0).getReg()))
+          continue;
+
+        const TargetRegisterClass *SrcRC, *DstRC;
+        std::tie(SrcRC, DstRC) = getCopyRegClasses(MI, *TRI, MRI);
+        if (isVGPRToSGPRCopy(SrcRC, DstRC, *TRI)) {
           DEBUG(dbgs() << "Fixing VGPR -> SGPR copy: " << MI);
           TII->moveToVALU(MI);
         }