[llvm-commits] [llvm] r156334 - /llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp

Jakob Stoklund Olesen stoklund at 2pi.dk
Mon May 7 15:57:56 PDT 2012


Author: stoklund
Date: Mon May  7 17:57:55 2012
New Revision: 156334

URL: http://llvm.org/viewvc/llvm-project?rev=156334&view=rev
Log:
Coalesce subreg-subreg copies.

At least some of them:

  %vreg1:sub_16bit = COPY %vreg2:sub_16bit; GR64:%vreg1, GR32: %vreg2

Previously, we couldn't figure out that the above copy could be
eliminated by coalescing %vreg2 with %vreg1:sub_32bit.

The new getCommonSuperRegClass() hook makes it possible.

This is not very useful yet since the unmodified part of the destination
register usually interferes with the source register. The coalescer
needs to understand sub-register interference checking first.

Modified:
    llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp

Modified: llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp?rev=156334&r1=156333&r2=156334&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp (original)
+++ llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp Mon May  7 17:57:55 2012
@@ -258,24 +258,35 @@
     }
   } else {
     // Both registers are virtual.
+    const TargetRegisterClass *SrcRC = MRI.getRegClass(Src);
+    const TargetRegisterClass *DstRC = MRI.getRegClass(Dst);
 
     // Both registers have subreg indices.
     if (SrcSub && DstSub) {
-      // For now we only handle the case of identical indices in commensurate
-      // registers: Dreg:ssub_1 + Dreg:ssub_1 -> Dreg
-      // FIXME: Handle Qreg:ssub_3 + Dreg:ssub_1 as QReg:dsub_1 + Dreg.
-      if (SrcSub != DstSub)
+      unsigned SrcPre, DstPre;
+      NewRC = TRI.getCommonSuperRegClass(SrcRC, SrcSub, DstRC, DstSub,
+                                         SrcPre, DstPre);
+      if (!NewRC)
         return false;
-      const TargetRegisterClass *SrcRC = MRI.getRegClass(Src);
-      const TargetRegisterClass *DstRC = MRI.getRegClass(Dst);
-      if (!TRI.getCommonSubClass(DstRC, SrcRC))
+
+      // We cannot handle the case where both Src and Dst would be a
+      // sub-register. Yet.
+      if (SrcPre && DstPre) {
+        DEBUG(dbgs() << "\tCannot handle " << NewRC->getName()
+                     << " with subregs " << TRI.getSubRegIndexName(SrcPre)
+                     << " and " << TRI.getSubRegIndexName(DstPre) << '\n');
         return false;
-      SrcSub = DstSub = 0;
+      }
+
+      // One of these will be 0, so one register is a sub-register of the other.
+      SrcSub = DstPre;
+      DstSub = SrcPre;
     }
 
     // There can be no SrcSub.
     if (SrcSub) {
       std::swap(Src, Dst);
+      std::swap(SrcRC, DstRC);
       DstSub = SrcSub;
       SrcSub = 0;
       assert(!Flipped && "Unexpected flip");
@@ -283,12 +294,12 @@
     }
 
     // Find the new register class.
-    const TargetRegisterClass *SrcRC = MRI.getRegClass(Src);
-    const TargetRegisterClass *DstRC = MRI.getRegClass(Dst);
-    if (DstSub)
-      NewRC = TRI.getMatchingSuperRegClass(DstRC, SrcRC, DstSub);
-    else
-      NewRC = TRI.getCommonSubClass(DstRC, SrcRC);
+    if (!NewRC) {
+      if (DstSub)
+        NewRC = TRI.getMatchingSuperRegClass(DstRC, SrcRC, DstSub);
+      else
+        NewRC = TRI.getCommonSubClass(DstRC, SrcRC);
+    }
     if (!NewRC)
       return false;
     CrossClass = NewRC != DstRC || NewRC != SrcRC;





More information about the llvm-commits mailing list