[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