From 6a16f6a14f344eb49a218b3fe159858e95d73e94 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 6 Oct 2005 19:07:45 +0000 Subject: [PATCH] Pull out Call, reducing stack frame size from 6032 bytes to 5184 bytes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23650 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/PowerPC/PPCISelDAGToDAG.cpp | 217 +++++++++++++------------ 1 file changed, 111 insertions(+), 106 deletions(-) diff --git a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index ae32f9479e6..10c9b2bba94 100644 --- a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -97,6 +97,7 @@ private: SDOperand SelectADD_PARTS(SDOperand Op); SDOperand SelectSUB_PARTS(SDOperand Op); SDOperand SelectSETCC(SDOperand Op); + SDOperand SelectCALL(SDOperand Op); }; } @@ -884,6 +885,113 @@ SDOperand PPC32DAGToDAGISel::SelectSETCC(SDOperand Op) { return SDOperand(N, 0); } +SDOperand PPC32DAGToDAGISel::SelectCALL(SDOperand Op) { + SDNode *N = Op.Val; + SDOperand Chain = Select(N->getOperand(0)); + + unsigned CallOpcode; + std::vector CallOperands; + + if (GlobalAddressSDNode *GASD = + dyn_cast(N->getOperand(1))) { + CallOpcode = PPC::CALLpcrel; + CallOperands.push_back(CurDAG->getTargetGlobalAddress(GASD->getGlobal(), + MVT::i32)); + } else if (ExternalSymbolSDNode *ESSDN = + dyn_cast(N->getOperand(1))) { + CallOpcode = PPC::CALLpcrel; + CallOperands.push_back(N->getOperand(1)); + } else { + // Copy the callee address into the CTR register. + SDOperand Callee = Select(N->getOperand(1)); + Chain = CurDAG->getTargetNode(PPC::MTCTR, MVT::Other, Callee, Chain); + + // Copy the callee address into R12 on darwin. + SDOperand R12 = CurDAG->getRegister(PPC::R12, MVT::i32); + Chain = CurDAG->getNode(ISD::CopyToReg, MVT::Other, Chain, R12, Callee); + + CallOperands.push_back(getI32Imm(20)); // Information to encode indcall + CallOperands.push_back(getI32Imm(0)); // Information to encode indcall + CallOperands.push_back(R12); + CallOpcode = PPC::CALLindirect; + } + + unsigned GPR_idx = 0, FPR_idx = 0; + static const unsigned GPR[] = { + PPC::R3, PPC::R4, PPC::R5, PPC::R6, + PPC::R7, PPC::R8, PPC::R9, PPC::R10, + }; + static const unsigned FPR[] = { + PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7, + PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13 + }; + + SDOperand InFlag; // Null incoming flag value. + + for (unsigned i = 2, e = N->getNumOperands(); i != e; ++i) { + unsigned DestReg = 0; + MVT::ValueType RegTy = N->getOperand(i).getValueType(); + if (RegTy == MVT::i32) { + assert(GPR_idx < 8 && "Too many int args"); + DestReg = GPR[GPR_idx++]; + } else { + assert(MVT::isFloatingPoint(N->getOperand(i).getValueType()) && + "Unpromoted integer arg?"); + assert(FPR_idx < 13 && "Too many fp args"); + DestReg = FPR[FPR_idx++]; + } + + if (N->getOperand(i).getOpcode() != ISD::UNDEF) { + SDOperand Val = Select(N->getOperand(i)); + Chain = CurDAG->getCopyToReg(Chain, DestReg, Val, InFlag); + InFlag = Chain.getValue(1); + CallOperands.push_back(CurDAG->getRegister(DestReg, RegTy)); + } + } + + // Finally, once everything is in registers to pass to the call, emit the + // call itself. + if (InFlag.Val) + CallOperands.push_back(InFlag); // Strong dep on register copies. + else + CallOperands.push_back(Chain); // Weak dep on whatever occurs before + Chain = CurDAG->getTargetNode(CallOpcode, MVT::Other, MVT::Flag, + CallOperands); + + std::vector CallResults; + + // If the call has results, copy the values out of the ret val registers. + switch (N->getValueType(0)) { + default: assert(0 && "Unexpected ret value!"); + case MVT::Other: break; + case MVT::i32: + if (N->getValueType(1) == MVT::i32) { + Chain = CurDAG->getCopyFromReg(Chain, PPC::R4, MVT::i32, + Chain.getValue(1)).getValue(1); + CallResults.push_back(Chain.getValue(0)); + Chain = CurDAG->getCopyFromReg(Chain, PPC::R3, MVT::i32, + Chain.getValue(2)).getValue(1); + CallResults.push_back(Chain.getValue(0)); + } else { + Chain = CurDAG->getCopyFromReg(Chain, PPC::R3, MVT::i32, + Chain.getValue(1)).getValue(1); + CallResults.push_back(Chain.getValue(0)); + } + break; + case MVT::f32: + case MVT::f64: + Chain = CurDAG->getCopyFromReg(Chain, PPC::F1, N->getValueType(0), + Chain.getValue(1)).getValue(1); + CallResults.push_back(Chain.getValue(0)); + break; + } + + CallResults.push_back(Chain); + for (unsigned i = 0, e = CallResults.size(); i != e; ++i) + CodeGenMap[Op.getValue(i)] = CallResults[i]; + return CallResults[Op.ResNo]; +} + // Select - Convert the specified operand from a target-independent to a // target-specific node if it hasn't already been changed. SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) { @@ -902,6 +1010,9 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) { case ISD::ADD_PARTS: return SelectADD_PARTS(Op); case ISD::SUB_PARTS: return SelectSUB_PARTS(Op); case ISD::SETCC: return SelectSETCC(Op); + case ISD::CALL: return SelectCALL(Op); + case ISD::TAILCALL: return SelectCALL(Op); + case ISD::TokenFactor: { SDOperand New; if (N->getNumOperands() == 2) { @@ -1362,112 +1473,6 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) { getI32Imm(Amt), Select(N->getOperand(0))); return SDOperand(N, 0); } - case ISD::CALL: - case ISD::TAILCALL: { - SDOperand Chain = Select(N->getOperand(0)); - - unsigned CallOpcode; - std::vector CallOperands; - - if (GlobalAddressSDNode *GASD = - dyn_cast(N->getOperand(1))) { - CallOpcode = PPC::CALLpcrel; - CallOperands.push_back(CurDAG->getTargetGlobalAddress(GASD->getGlobal(), - MVT::i32)); - } else if (ExternalSymbolSDNode *ESSDN = - dyn_cast(N->getOperand(1))) { - CallOpcode = PPC::CALLpcrel; - CallOperands.push_back(N->getOperand(1)); - } else { - // Copy the callee address into the CTR register. - SDOperand Callee = Select(N->getOperand(1)); - Chain = CurDAG->getTargetNode(PPC::MTCTR, MVT::Other, Callee, Chain); - - // Copy the callee address into R12 on darwin. - SDOperand R12 = CurDAG->getRegister(PPC::R12, MVT::i32); - Chain = CurDAG->getNode(ISD::CopyToReg, MVT::Other, Chain, R12, Callee); - - CallOperands.push_back(getI32Imm(20)); // Information to encode indcall - CallOperands.push_back(getI32Imm(0)); // Information to encode indcall - CallOperands.push_back(R12); - CallOpcode = PPC::CALLindirect; - } - - unsigned GPR_idx = 0, FPR_idx = 0; - static const unsigned GPR[] = { - PPC::R3, PPC::R4, PPC::R5, PPC::R6, - PPC::R7, PPC::R8, PPC::R9, PPC::R10, - }; - static const unsigned FPR[] = { - PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7, - PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13 - }; - - SDOperand InFlag; // Null incoming flag value. - - for (unsigned i = 2, e = N->getNumOperands(); i != e; ++i) { - unsigned DestReg = 0; - MVT::ValueType RegTy = N->getOperand(i).getValueType(); - if (RegTy == MVT::i32) { - assert(GPR_idx < 8 && "Too many int args"); - DestReg = GPR[GPR_idx++]; - } else { - assert(MVT::isFloatingPoint(N->getOperand(i).getValueType()) && - "Unpromoted integer arg?"); - assert(FPR_idx < 13 && "Too many fp args"); - DestReg = FPR[FPR_idx++]; - } - - if (N->getOperand(i).getOpcode() != ISD::UNDEF) { - SDOperand Val = Select(N->getOperand(i)); - Chain = CurDAG->getCopyToReg(Chain, DestReg, Val, InFlag); - InFlag = Chain.getValue(1); - CallOperands.push_back(CurDAG->getRegister(DestReg, RegTy)); - } - } - - // Finally, once everything is in registers to pass to the call, emit the - // call itself. - if (InFlag.Val) - CallOperands.push_back(InFlag); // Strong dep on register copies. - else - CallOperands.push_back(Chain); // Weak dep on whatever occurs before - Chain = CurDAG->getTargetNode(CallOpcode, MVT::Other, MVT::Flag, - CallOperands); - - std::vector CallResults; - - // If the call has results, copy the values out of the ret val registers. - switch (N->getValueType(0)) { - default: assert(0 && "Unexpected ret value!"); - case MVT::Other: break; - case MVT::i32: - if (N->getValueType(1) == MVT::i32) { - Chain = CurDAG->getCopyFromReg(Chain, PPC::R4, MVT::i32, - Chain.getValue(1)).getValue(1); - CallResults.push_back(Chain.getValue(0)); - Chain = CurDAG->getCopyFromReg(Chain, PPC::R3, MVT::i32, - Chain.getValue(2)).getValue(1); - CallResults.push_back(Chain.getValue(0)); - } else { - Chain = CurDAG->getCopyFromReg(Chain, PPC::R3, MVT::i32, - Chain.getValue(1)).getValue(1); - CallResults.push_back(Chain.getValue(0)); - } - break; - case MVT::f32: - case MVT::f64: - Chain = CurDAG->getCopyFromReg(Chain, PPC::F1, N->getValueType(0), - Chain.getValue(1)).getValue(1); - CallResults.push_back(Chain.getValue(0)); - break; - } - - CallResults.push_back(Chain); - for (unsigned i = 0, e = CallResults.size(); i != e; ++i) - CodeGenMap[Op.getValue(i)] = CallResults[i]; - return CallResults[Op.ResNo]; - } case ISD::RET: { SDOperand Chain = Select(N->getOperand(0)); // Token chain. -- 2.34.1