When converting a CopyFromReg to a copy instruction, use the register class of its...
authorEvan Cheng <evan.cheng@apple.com>
Tue, 16 Sep 2008 23:12:11 +0000 (23:12 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Tue, 16 Sep 2008 23:12:11 +0000 (23:12 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@56258 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp

index 156905a708a98d8f18b6c7799cf6688e719172e9..4ea29063ab58eb1163aed05427129d42dd3fb6db 100644 (file)
@@ -65,6 +65,7 @@ void ScheduleDAG::EmitCopyFromReg(SDNode *Node, unsigned ResNo,
   // If the node is only used by a CopyToReg and the dest reg is a vreg, use
   // the CopyToReg'd destination register instead of creating a new vreg.
   bool MatchReg = true;
+  const TargetRegisterClass *UseRC = NULL;
   for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end();
        UI != E; ++UI) {
     SDNode *User = *UI;
@@ -84,8 +85,19 @@ void ScheduleDAG::EmitCopyFromReg(SDNode *Node, unsigned ResNo,
         if (Op.getNode() != Node || Op.getResNo() != ResNo)
           continue;
         MVT VT = Node->getValueType(Op.getResNo());
-        if (VT != MVT::Other && VT != MVT::Flag)
-          Match = false;
+        if (VT == MVT::Other || VT == MVT::Flag)
+          continue;
+        Match = false;
+        if (User->isMachineOpcode()) {
+          const TargetInstrDesc &II = TII->get(User->getMachineOpcode());
+          const TargetRegisterClass *RC =
+            getInstrOperandRegClass(TRI,TII,II,i+II.getNumDefs());
+          if (!UseRC)
+            UseRC = RC;
+          else if (RC)
+            assert(UseRC == RC &&
+                   "Multiple uses expecting different register classes!");
+        }
       }
     }
     MatchReg &= Match;
@@ -93,14 +105,18 @@ void ScheduleDAG::EmitCopyFromReg(SDNode *Node, unsigned ResNo,
       break;
   }
 
+  MVT VT = Node->getValueType(ResNo);
   const TargetRegisterClass *SrcRC = 0, *DstRC = 0;
-  SrcRC = TRI->getPhysicalRegisterRegClass(SrcReg, Node->getValueType(ResNo));
+  SrcRC = TRI->getPhysicalRegisterRegClass(SrcReg, VT);
   
   // Figure out the register class to create for the destreg.
   if (VRBase) {
     DstRC = MRI.getRegClass(VRBase);
+  } else if (UseRC) {
+    assert(UseRC->hasType(VT) && "Incompatible phys register def and uses!");
+    DstRC = UseRC;
   } else {
-    DstRC = TLI->getRegClassFor(Node->getValueType(ResNo));
+    DstRC = TLI->getRegClassFor(VT);
   }
     
   // If all uses are reading from the src physical register and copying the
@@ -110,7 +126,10 @@ void ScheduleDAG::EmitCopyFromReg(SDNode *Node, unsigned ResNo,
   } else {
     // Create the reg, emit the copy.
     VRBase = MRI.createVirtualRegister(DstRC);
-    TII->copyRegToReg(*BB, BB->end(), VRBase, SrcReg, DstRC, SrcRC);
+    bool Emitted =
+      TII->copyRegToReg(*BB, BB->end(), VRBase, SrcReg, DstRC, SrcRC);
+    Emitted = Emitted; // Silence compiler warning.
+    assert(Emitted && "Unable to issue a copy instruction!");
   }
 
   SDValue Op(Node, ResNo);