[llvm-commits] [llvm] r48552 - in /llvm/trunk: lib/Target/PowerPC/PPCISelLowering.cpp lib/Target/PowerPC/PPCISelLowering.h test/CodeGen/PowerPC/multiple-return-values.ll

Dan Gohman gohman at apple.com
Wed Mar 19 14:39:28 PDT 2008


Author: djg
Date: Wed Mar 19 16:39:28 2008
New Revision: 48552

URL: http://llvm.org/viewvc/llvm-project?rev=48552&view=rev
Log:
Add support for multiple return values for the PPC target by
converting call result lowering to use the CallingConvLowering
infastructure.

Added:
    llvm/trunk/test/CodeGen/PowerPC/multiple-return-values.ll
Modified:
    llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
    llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h

Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=48552&r1=48551&r2=48552&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Wed Mar 19 16:39:28 2008
@@ -1747,7 +1747,8 @@
 }
 
 SDOperand PPCTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG,
-                                       const PPCSubtarget &Subtarget) {
+                                       const PPCSubtarget &Subtarget,
+                                       TargetMachine &TM) {
   SDOperand Chain  = Op.getOperand(0);
   bool isVarArg    = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
   SDOperand Callee = Op.getOperand(4);
@@ -2184,155 +2185,30 @@
   if (Op.Val->getValueType(0) != MVT::Other)
     InFlag = Chain.getValue(1);
 
-  SDOperand ResultVals[9];
-  unsigned NumResults = 0;
-  NodeTys.clear();
+  SmallVector<SDOperand, 16> ResultVals;
+  SmallVector<CCValAssign, 16> RVLocs;
+  unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv();
+  CCState CCInfo(CC, isVarArg, TM, RVLocs);
+  CCInfo.AnalyzeCallResult(Op.Val, RetCC_PPC);
   
-  // If the call has results, copy the values out of the ret val registers.
-  switch (Op.Val->getValueType(0)) {
-  default: assert(0 && "Unexpected ret value!");
-  case MVT::Other: break;
-  case MVT::i32:
-    // There are 8 result regs for Complex double, and 4 for Complex long long.
-    if (Op.Val->getNumValues()>=8 && Op.Val->getValueType(7) == MVT::i32) {
-      Chain = DAG.getCopyFromReg(Chain, PPC::R3, MVT::i32, InFlag).getValue(1);
-      ResultVals[0] = Chain.getValue(0);
-      Chain = DAG.getCopyFromReg(Chain, PPC::R4, MVT::i32,
-                                 Chain.getValue(2)).getValue(1);
-      ResultVals[1] = Chain.getValue(0);
-      Chain = DAG.getCopyFromReg(Chain, PPC::R5, MVT::i32,
-                                 Chain.getValue(2)).getValue(1);
-      ResultVals[2] = Chain.getValue(0);
-      Chain = DAG.getCopyFromReg(Chain, PPC::R6, MVT::i32,
-                                 Chain.getValue(2)).getValue(1);
-      ResultVals[3] = Chain.getValue(0);
-      Chain = DAG.getCopyFromReg(Chain, PPC::R7, MVT::i32,
-                                 Chain.getValue(2)).getValue(1);
-      ResultVals[4] = Chain.getValue(0);
-      Chain = DAG.getCopyFromReg(Chain, PPC::R8, MVT::i32,
-                                 Chain.getValue(2)).getValue(1);
-      ResultVals[5] = Chain.getValue(0);
-      Chain = DAG.getCopyFromReg(Chain, PPC::R9, MVT::i32,
-                                 Chain.getValue(2)).getValue(1);
-      ResultVals[6] = Chain.getValue(0);
-      Chain = DAG.getCopyFromReg(Chain, PPC::R10, MVT::i32,
-                                 Chain.getValue(2)).getValue(1);
-      ResultVals[7] = Chain.getValue(0);
-      NumResults = 8;
-      NodeTys.push_back(MVT::i32);
-      NodeTys.push_back(MVT::i32);
-      NodeTys.push_back(MVT::i32);
-      NodeTys.push_back(MVT::i32);
-      NodeTys.push_back(MVT::i32);
-      NodeTys.push_back(MVT::i32);
-      NodeTys.push_back(MVT::i32);
-    } else if (Op.Val->getNumValues()>=4 && 
-               Op.Val->getValueType(3) == MVT::i32) {
-      Chain = DAG.getCopyFromReg(Chain, PPC::R3, MVT::i32, InFlag).getValue(1);
-      ResultVals[0] = Chain.getValue(0);
-      Chain = DAG.getCopyFromReg(Chain, PPC::R4, MVT::i32,
-                                 Chain.getValue(2)).getValue(1);
-      ResultVals[1] = Chain.getValue(0);
-      Chain = DAG.getCopyFromReg(Chain, PPC::R5, MVT::i32,
-                                 Chain.getValue(2)).getValue(1);
-      ResultVals[2] = Chain.getValue(0);
-      Chain = DAG.getCopyFromReg(Chain, PPC::R6, MVT::i32,
-                                 Chain.getValue(2)).getValue(1);
-      ResultVals[3] = Chain.getValue(0);
-      NumResults = 4;
-      NodeTys.push_back(MVT::i32);
-      NodeTys.push_back(MVT::i32);
-      NodeTys.push_back(MVT::i32);
-    } else if (Op.Val->getValueType(1) == MVT::i32) {
-      Chain = DAG.getCopyFromReg(Chain, PPC::R3, MVT::i32, InFlag).getValue(1);
-      ResultVals[0] = Chain.getValue(0);
-      Chain = DAG.getCopyFromReg(Chain, PPC::R4, MVT::i32,
-                                 Chain.getValue(2)).getValue(1);
-      ResultVals[1] = Chain.getValue(0);
-      NumResults = 2;
-      NodeTys.push_back(MVT::i32);
-    } else {
-      Chain = DAG.getCopyFromReg(Chain, PPC::R3, MVT::i32, InFlag).getValue(1);
-      ResultVals[0] = Chain.getValue(0);
-      NumResults = 1;
-    }
-    NodeTys.push_back(MVT::i32);
-    break;
-  case MVT::i64:
-    if (Op.Val->getNumValues()>=4 && 
-        Op.Val->getValueType(3) == MVT::i64) {
-      Chain = DAG.getCopyFromReg(Chain, PPC::X3, MVT::i64, InFlag).getValue(1);
-      ResultVals[0] = Chain.getValue(0);
-      Chain = DAG.getCopyFromReg(Chain, PPC::X4, MVT::i64,
-                                 Chain.getValue(2)).getValue(1);
-      ResultVals[1] = Chain.getValue(0);
-      Chain = DAG.getCopyFromReg(Chain, PPC::X5, MVT::i64,
-                                 Chain.getValue(2)).getValue(1);
-      ResultVals[2] = Chain.getValue(0);
-      Chain = DAG.getCopyFromReg(Chain, PPC::X6, MVT::i64,
-                                 Chain.getValue(2)).getValue(1);
-      ResultVals[3] = Chain.getValue(0);
-      NumResults = 4;
-      NodeTys.push_back(MVT::i64);
-      NodeTys.push_back(MVT::i64);
-      NodeTys.push_back(MVT::i64);
-    } else if (Op.Val->getValueType(1) == MVT::i64) {
-      Chain = DAG.getCopyFromReg(Chain, PPC::X3, MVT::i64, InFlag).getValue(1);
-      ResultVals[0] = Chain.getValue(0);
-      Chain = DAG.getCopyFromReg(Chain, PPC::X4, MVT::i64,
-                                 Chain.getValue(2)).getValue(1);
-      ResultVals[1] = Chain.getValue(0);
-      NumResults = 2;
-      NodeTys.push_back(MVT::i64);
-    } else {
-      Chain = DAG.getCopyFromReg(Chain, PPC::X3, MVT::i64, InFlag).getValue(1);
-      ResultVals[0] = Chain.getValue(0);
-      NumResults = 1;
-    }
-    NodeTys.push_back(MVT::i64);
-    break;
-  case MVT::f64:
-    if (Op.Val->getValueType(1) == MVT::f64) {
-      Chain = DAG.getCopyFromReg(Chain, PPC::F1, MVT::f64, InFlag).getValue(1);
-      ResultVals[0] = Chain.getValue(0);
-      Chain = DAG.getCopyFromReg(Chain, PPC::F2, MVT::f64,
-                                 Chain.getValue(2)).getValue(1);
-      ResultVals[1] = Chain.getValue(0);
-      NumResults = 2;
-      NodeTys.push_back(MVT::f64);
-      NodeTys.push_back(MVT::f64);
-      break;
-    } 
-    // else fall through
-  case MVT::f32:
-    Chain = DAG.getCopyFromReg(Chain, PPC::F1, Op.Val->getValueType(0),
-                               InFlag).getValue(1);
-    ResultVals[0] = Chain.getValue(0);
-    NumResults = 1;
-    NodeTys.push_back(Op.Val->getValueType(0));
-    break;
-  case MVT::v4f32:
-  case MVT::v4i32:
-  case MVT::v8i16:
-  case MVT::v16i8:
-    Chain = DAG.getCopyFromReg(Chain, PPC::V2, Op.Val->getValueType(0),
-                                   InFlag).getValue(1);
-    ResultVals[0] = Chain.getValue(0);
-    NumResults = 1;
-    NodeTys.push_back(Op.Val->getValueType(0));
-    break;
+  // Copy all of the result registers out of their specified physreg.
+  for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) {
+    CCValAssign &VA = RVLocs[i];
+    MVT::ValueType VT = VA.getValVT();
+    assert(VA.isRegLoc() && "Can only return in registers!");
+    Chain = DAG.getCopyFromReg(Chain, VA.getLocReg(), VT, InFlag).getValue(1);
+    ResultVals.push_back(Chain.getValue(0));
+    InFlag = Chain.getValue(2);
   }
-  
-  NodeTys.push_back(MVT::Other);
-  
+
   // If the function returns void, just return the chain.
-  if (NumResults == 0)
+  if (RVLocs.empty())
     return Chain;
   
   // Otherwise, merge everything together with a MERGE_VALUES node.
-  ResultVals[NumResults++] = Chain;
-  SDOperand Res = DAG.getNode(ISD::MERGE_VALUES, NodeTys,
-                              ResultVals, NumResults);
+  ResultVals.push_back(Chain);
+  SDOperand Res = DAG.getNode(ISD::MERGE_VALUES, Op.Val->getVTList(),
+                              &ResultVals[0], ResultVals.size());
   return Res.getValue(Op.ResNo);
 }
 
@@ -3537,7 +3413,8 @@
                                  VarArgsStackOffset, VarArgsNumGPR,
                                  VarArgsNumFPR, PPCSubTarget);
 
-  case ISD::CALL:               return LowerCALL(Op, DAG, PPCSubTarget);
+  case ISD::CALL:               return LowerCALL(Op, DAG, PPCSubTarget,
+                                                 getTargetMachine());
   case ISD::RET:                return LowerRET(Op, DAG, getTargetMachine());
   case ISD::STACKRESTORE:       return LowerSTACKRESTORE(Op, DAG, PPCSubTarget);
   case ISD::DYNAMIC_STACKALLOC:

Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h?rev=48552&r1=48551&r2=48552&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h Wed Mar 19 16:39:28 2008
@@ -317,7 +317,7 @@
                                     unsigned &VarArgsNumFPR,
                                     const PPCSubtarget &Subtarget);
     SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG,
-                        const PPCSubtarget &Subtarget);
+                        const PPCSubtarget &Subtarget, TargetMachine &TM);
     SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG, TargetMachine &TM);
     SDOperand LowerSTACKRESTORE(SDOperand Op, SelectionDAG &DAG,
                                 const PPCSubtarget &Subtarget);

Added: llvm/trunk/test/CodeGen/PowerPC/multiple-return-values.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/multiple-return-values.ll?rev=48552&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/multiple-return-values.ll (added)
+++ llvm/trunk/test/CodeGen/PowerPC/multiple-return-values.ll Wed Mar 19 16:39:28 2008
@@ -0,0 +1,17 @@
+; RUN: llvm-as < %s | llc -march=ppc32
+; RUN: llvm-as < %s | llc -march=ppc64
+
+define {i64, float} @bar(i64 %a, float %b) {
+        %y = add i64 %a, 7
+        %z = add float %b, 7.0
+	ret i64 %y, float %z
+}
+
+define i64 @foo() {
+	%M = call {i64, float} @bar(i64 21, float 21.0)
+        %N = getresult {i64, float} %M, 0
+        %O = getresult {i64, float} %M, 1
+        %P = fptosi float %O to i64
+        %Q = add i64 %P, %N
+	ret i64 %Q
+}





More information about the llvm-commits mailing list