OSDN Git Service

Make X86's copyRegToReg able to handle copies to and from subclasses.
authorDan Gohman <gohman@apple.com>
Mon, 20 Apr 2009 22:54:34 +0000 (22:54 +0000)
committerDan Gohman <gohman@apple.com>
Mon, 20 Apr 2009 22:54:34 +0000 (22:54 +0000)
This makes the extra copyRegToReg calls in ScheduleDAGSDNodesEmit.cpp
unnecessary. Derived from a patch by Jakob Stoklund Olesen.

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

lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp
lib/Target/X86/X86InstrInfo.cpp

index 42fe1f5..eddf44f 100644 (file)
@@ -131,12 +131,6 @@ void ScheduleDAGSDNodes::EmitCopyFromReg(SDNode *Node, unsigned ResNo,
     VRBase = MRI.createVirtualRegister(DstRC);
     bool Emitted = TII->copyRegToReg(*BB, InsertPos, VRBase, SrcReg,
                                      DstRC, SrcRC);
-    // If the target didn't handle the copy with different register
-    // classes and the destination is a subset of the source,
-    // try a normal same-RC copy.
-    if (!Emitted && DstRC->hasSuperClass(SrcRC))
-      Emitted = TII->copyRegToReg(*BB, InsertPos, VRBase, SrcReg,
-                                  SrcRC, SrcRC);
 
     assert(Emitted && "Unable to issue a copy instruction!\n");
   }
@@ -273,12 +267,6 @@ ScheduleDAGSDNodes::AddRegisterOperand(MachineInstr *MI, SDValue Op,
       unsigned NewVReg = MRI.createVirtualRegister(DstRC);
       bool Emitted = TII->copyRegToReg(*BB, InsertPos, NewVReg, VReg,
                                        DstRC, SrcRC);
-      // If the target didn't handle the copy with different register
-      // classes and the destination is a subset of the source,
-      // try a normal same-RC copy.
-      if (!Emitted && DstRC->hasSuperClass(SrcRC))
-        Emitted = TII->copyRegToReg(*BB, InsertPos, NewVReg, VReg,
-                                    SrcRC, SrcRC);
       assert(Emitted && "Unable to issue a copy instruction!\n");
       VReg = NewVReg;
     }
@@ -480,12 +468,6 @@ ScheduleDAGSDNodes::EmitCopyToRegClassNode(SDNode *Node,
   unsigned NewVReg = MRI.createVirtualRegister(DstRC);
   bool Emitted = TII->copyRegToReg(*BB, InsertPos, NewVReg, VReg,
                                    DstRC, SrcRC);
-  // If the target didn't handle the copy with different register
-  // classes and the destination is a subset of the source,
-  // try a normal same-RC copy.
-  if (!Emitted && SrcRC->hasSubClass(DstRC))
-    Emitted = TII->copyRegToReg(*BB, InsertPos, NewVReg, VReg,
-                                SrcRC, SrcRC);
   assert(Emitted &&
          "Unable to issue a copy instruction for a COPY_TO_REGCLASS node!\n");
 
@@ -610,13 +592,6 @@ void ScheduleDAGSDNodes::EmitNode(SDNode *Node, bool IsClone, bool IsCloned,
 
     bool Emitted = TII->copyRegToReg(*BB, InsertPos, DestReg, SrcReg,
                                      DstTRC, SrcTRC);
-    // If the target didn't handle the copy with different register
-    // classes and the destination is a subset of the source,
-    // try a normal same-RC copy.
-    if (!Emitted && DstTRC->hasSubClass(SrcTRC))
-      Emitted = TII->copyRegToReg(*BB, InsertPos, DestReg, SrcReg,
-                                  DstTRC, DstTRC);
-
     assert(Emitted && "Unable to issue a copy instruction!\n");
     break;
   }
index 4b13868..d8c0833 100644 (file)
@@ -1656,15 +1656,24 @@ bool X86InstrInfo::copyRegToReg(MachineBasicBlock &MBB,
   DebugLoc DL = DebugLoc::getUnknownLoc();
   if (MI != MBB.end()) DL = MI->getDebugLoc();
 
-  if (DestRC == SrcRC) {
+  // Determine if DstRC and SrcRC have a common superclass in common.
+  const TargetRegisterClass *CommonRC = DestRC;
+  if (DestRC == SrcRC)
+    /* Source and destination have the same register class. */;
+  else if (CommonRC->hasSuperClass(SrcRC))
+    CommonRC = SrcRC;
+  else if (!DestRC->hasSubClass(SrcRC))
+    CommonRC = 0;
+
+  if (CommonRC) {
     unsigned Opc;
-    if (DestRC == &X86::GR64RegClass) {
+    if (CommonRC == &X86::GR64RegClass) {
       Opc = X86::MOV64rr;
-    } else if (DestRC == &X86::GR32RegClass) {
+    } else if (CommonRC == &X86::GR32RegClass) {
       Opc = X86::MOV32rr;
-    } else if (DestRC == &X86::GR16RegClass) {
+    } else if (CommonRC == &X86::GR16RegClass) {
       Opc = X86::MOV16rr;
-    } else if (DestRC == &X86::GR8RegClass) {
+    } else if (CommonRC == &X86::GR8RegClass) {
       // Copying two or from a physical H register on x86-64 requires a NOREX
       // move.  Otherwise use a normal move.
       if ((isHReg(DestReg) || isHReg(SrcReg)) &&
@@ -1672,35 +1681,35 @@ bool X86InstrInfo::copyRegToReg(MachineBasicBlock &MBB,
         Opc = X86::MOV8rr_NOREX;
       else
         Opc = X86::MOV8rr;
-    } else if (DestRC == &X86::GR64_RegClass) {
+    } else if (CommonRC == &X86::GR64_RegClass) {
       Opc = X86::MOV64rr;
-    } else if (DestRC == &X86::GR32_RegClass) {
+    } else if (CommonRC == &X86::GR32_RegClass) {
       Opc = X86::MOV32rr;
-    } else if (DestRC == &X86::GR16_RegClass) {
+    } else if (CommonRC == &X86::GR16_RegClass) {
       Opc = X86::MOV16rr;
-    } else if (DestRC == &X86::GR8_RegClass) {
+    } else if (CommonRC == &X86::GR8_RegClass) {
       Opc = X86::MOV8rr;
-    } else if (DestRC == &X86::GR64_NOREXRegClass) {
+    } else if (CommonRC == &X86::GR64_NOREXRegClass) {
       Opc = X86::MOV64rr;
-    } else if (DestRC == &X86::GR32_NOREXRegClass) {
+    } else if (CommonRC == &X86::GR32_NOREXRegClass) {
       Opc = X86::MOV32rr;
-    } else if (DestRC == &X86::GR16_NOREXRegClass) {
+    } else if (CommonRC == &X86::GR16_NOREXRegClass) {
       Opc = X86::MOV16rr;
-    } else if (DestRC == &X86::GR8_NOREXRegClass) {
+    } else if (CommonRC == &X86::GR8_NOREXRegClass) {
       Opc = X86::MOV8rr;
-    } else if (DestRC == &X86::RFP32RegClass) {
+    } else if (CommonRC == &X86::RFP32RegClass) {
       Opc = X86::MOV_Fp3232;
-    } else if (DestRC == &X86::RFP64RegClass || DestRC == &X86::RSTRegClass) {
+    } else if (CommonRC == &X86::RFP64RegClass || CommonRC == &X86::RSTRegClass) {
       Opc = X86::MOV_Fp6464;
-    } else if (DestRC == &X86::RFP80RegClass) {
+    } else if (CommonRC == &X86::RFP80RegClass) {
       Opc = X86::MOV_Fp8080;
-    } else if (DestRC == &X86::FR32RegClass) {
+    } else if (CommonRC == &X86::FR32RegClass) {
       Opc = X86::FsMOVAPSrr;
-    } else if (DestRC == &X86::FR64RegClass) {
+    } else if (CommonRC == &X86::FR64RegClass) {
       Opc = X86::FsMOVAPDrr;
-    } else if (DestRC == &X86::VR128RegClass) {
+    } else if (CommonRC == &X86::VR128RegClass) {
       Opc = X86::MOVAPSrr;
-    } else if (DestRC == &X86::VR64RegClass) {
+    } else if (CommonRC == &X86::VR64RegClass) {
       Opc = X86::MMX_MOVQ64rr;
     } else {
       return false;