Implement bottom-up fast-isel. This has the advantage of not requiring
a separate DCE pass over MachineInstrs.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@107804 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp
index 594ca4b..8300715 100644
--- a/lib/Target/X86/X86FastISel.cpp
+++ b/lib/Target/X86/X86FastISel.cpp
@@ -108,6 +108,7 @@
   bool X86SelectCall(const Instruction *I);
 
   CCAssignFn *CCAssignFnForCall(CallingConv::ID CC, bool isTailCall = false);
+  CCAssignFn *CCAssignFnForRet(CallingConv::ID CC, bool isTailCall = false);
 
   const X86InstrInfo *getInstrInfo() const {
     return getTargetMachine()->getInstrInfo();
@@ -181,6 +182,20 @@
     return CC_X86_32_C;
 }
 
+/// CCAssignFnForRet - Selects the correct CCAssignFn for a given calling
+/// convention.
+CCAssignFn *X86FastISel::CCAssignFnForRet(CallingConv::ID CC,
+                                          bool isTaillCall) {
+  if (Subtarget->is64Bit()) {
+    if (Subtarget->isTargetWin64())
+      return RetCC_X86_Win64_C;
+    else
+      return RetCC_X86_64_C;
+  }
+
+  return RetCC_X86_32_C;
+}
+
 /// X86FastEmitLoad - Emit a machine instruction to load a value of type VT.
 /// The address is either pre-computed, i.e. Ptr, or a GlobalAddress, i.e. GV.
 /// Return true and the result register by reference if it is possible.
@@ -689,34 +704,39 @@
   if (F.isVarArg())
     return false;
 
-  SmallVector<ISD::OutputArg, 4> Outs;
-  GetReturnInfo(F.getReturnType(), F.getAttributes().getRetAttributes(),
-                Outs, TLI);
+  if (Ret->getNumOperands() > 0) {
+    SmallVector<ISD::OutputArg, 4> Outs;
+    GetReturnInfo(F.getReturnType(), F.getAttributes().getRetAttributes(),
+                  Outs, TLI);
 
-  // Analyze operands of the call, assigning locations to each operand.
-  SmallVector<CCValAssign, 16> ValLocs;
-  CCState CCInfo(CC, F.isVarArg(), TM, ValLocs, I->getContext());
-  CCInfo.AnalyzeReturn(Outs, CCAssignFnForCall(CC));
+    // Analyze operands of the call, assigning locations to each operand.
+    SmallVector<CCValAssign, 16> ValLocs;
+    CCState CCInfo(CC, F.isVarArg(), TM, ValLocs, I->getContext());
+    CCInfo.AnalyzeReturn(Outs, CCAssignFnForRet(CC));
 
-  // Copy the return value into registers.
-  for (unsigned i = 0, e = ValLocs.size(); i != e; ++i) {
-    CCValAssign &VA = ValLocs[i];
-  
-    // Don't bother handling odd stuff for now.
-    if (VA.getLocInfo() != CCValAssign::Full)
-      return false;
-    if (!VA.isRegLoc())
-      return false;
-
-    const Value *RV = Ret->getOperand(VA.getValNo());
+    const Value *RV = Ret->getOperand(0);
     unsigned Reg = getRegForValue(RV);
+    if (Reg == 0)
+      return false;
 
-    TargetRegisterClass* RC = TLI.getRegClassFor(VA.getValVT());
-    bool Emitted = TII.copyRegToReg(*FuncInfo.MBB, FuncInfo.InsertPt,
-                                    VA.getLocReg(), Reg, RC, RC, DL);
-    assert(Emitted && "Failed to emit a copy instruction!"); Emitted=Emitted;
+    // Copy the return value into registers.
+    for (unsigned i = 0, e = ValLocs.size(); i != e; ++i) {
+      CCValAssign &VA = ValLocs[i];
+  
+      // Don't bother handling odd stuff for now.
+      if (VA.getLocInfo() != CCValAssign::Full)
+        return false;
+      if (!VA.isRegLoc())
+        return false;
 
-    MRI.addLiveOut(X86::XMM0);
+      TargetRegisterClass* RC = TLI.getRegClassFor(VA.getValVT());
+      bool Emitted = TII.copyRegToReg(*FuncInfo.MBB, FuncInfo.InsertPt,
+                                      VA.getLocReg(), Reg + VA.getValNo(),
+                                      RC, RC, DL);
+      assert(Emitted && "Failed to emit a copy instruction!"); Emitted=Emitted;
+
+      MRI.addLiveOut(VA.getLocReg());
+    }
   }
 
   // Now emit the RET.