Implement CopyFromReg, TokenFactor, and fix a bug in CopyToReg. This allows
authorChris Lattner <sabre@nondot.org>
Fri, 19 Aug 2005 21:43:53 +0000 (21:43 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 19 Aug 2005 21:43:53 +0000 (21:43 +0000)
us to compile stuff like this:

double %test(double %A, double %B, double %C, double %E) {
        %F = mul double %A, %A
        %G = add double %F, %B
        %H = sub double -0.0, %G
        %I = mul double %H, %C
        %J = add double %I, %E
        ret double %J
}

to:

_test:
        fnmadd f0, f1, f1, f2
        fmadd f1, f0, f3, f4
        blr

woot!

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

lib/CodeGen/SelectionDAG/ScheduleDAG.cpp

index d77578e28666c8d881e020adde4c2ce02cb9e615..e7827a8acf6f57c74b0a46cf79288d5a406be6a5 100644 (file)
@@ -131,13 +131,43 @@ unsigned SimpleSched::Emit(SDOperand Op) {
       Op.Val->dump(); 
       assert(0 && "This target-independent node should have been selected!");
     case ISD::EntryToken: break;
+    case ISD::TokenFactor:
+      for (unsigned i = 0, e = Op.getNumOperands(); i != e; ++i)
+        Emit(Op.getOperand(i));
+      break;
     case ISD::CopyToReg: {
+      Emit(Op.getOperand(0));   // Emit the chain.
       unsigned Val = Emit(Op.getOperand(2));
       MRI.copyRegToReg(*BB, BB->end(),
                        cast<RegisterSDNode>(Op.getOperand(1))->getReg(), Val,
                        RegMap->getRegClass(Val));
       break;
     }
+    case ISD::CopyFromReg: {
+      Emit(Op.getOperand(0));   // Emit the chain.
+      unsigned SrcReg = cast<RegisterSDNode>(Op.getOperand(1))->getReg();
+      
+      // Figure out the register class to create for the destreg.
+      const TargetRegisterClass *TRC;
+      if (MRegisterInfo::isVirtualRegister(SrcReg)) {
+        TRC = RegMap->getRegClass(SrcReg);
+      } else {
+        // FIXME: we don't know what register class to generate this for.  Do
+        // a brute force search and pick the first match. :(
+        for (MRegisterInfo::regclass_iterator I = MRI.regclass_begin(),
+               E = MRI.regclass_end(); I != E; ++I)
+          if ((*I)->contains(SrcReg)) {
+            TRC = *I;
+            break;
+          }
+        assert(TRC && "Couldn't find register class for reg copy!");
+      }
+      
+      // Create the reg, emit the copy.
+      ResultReg = RegMap->createVirtualRegister(TRC);
+      MRI.copyRegToReg(*BB, BB->end(), ResultReg, SrcReg, TRC);
+      break;
+    }
     }
   }