From 095cc29f321382e1f7d295e262a28197f92c5491 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Sat, 13 Sep 2008 01:54:27 +0000 Subject: Define CallSDNode, an SDNode subclass for use with ISD::CALL. Currently it just holds the calling convention and flags for isVarArgs and isTailCall. And it has several utility methods, which eliminate magic 5+2*i and similar index computations in several places. CallSDNodes are not CSE'd. Teach UpdateNodeOperands to handle nodes that are not CSE'd gracefully. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@56183 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/CallingConvLower.cpp | 15 ++--- lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 39 +++++++++--- lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp | 11 ++-- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 61 ++++++++---------- lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp | 6 ++ lib/Target/ARM/ARMISelLowering.cpp | 24 +++---- lib/Target/CellSPU/SPUISelLowering.cpp | 23 +++---- lib/Target/Mips/MipsISelLowering.cpp | 20 +++--- lib/Target/Mips/MipsISelLowering.h | 2 +- lib/Target/PowerPC/PPCISelLowering.cpp | 63 +++++++++--------- lib/Target/PowerPC/PPCISelLowering.h | 2 +- lib/Target/Sparc/SparcISelLowering.cpp | 23 +++---- lib/Target/X86/X86ISelLowering.cpp | 81 +++++++++++------------- lib/Target/X86/X86ISelLowering.h | 12 ++-- 14 files changed, 194 insertions(+), 188 deletions(-) (limited to 'lib') diff --git a/lib/CodeGen/SelectionDAG/CallingConvLower.cpp b/lib/CodeGen/SelectionDAG/CallingConvLower.cpp index 5987e0cdd5..a6f52dd024 100644 --- a/lib/CodeGen/SelectionDAG/CallingConvLower.cpp +++ b/lib/CodeGen/SelectionDAG/CallingConvLower.cpp @@ -91,12 +91,11 @@ void CCState::AnalyzeReturn(SDNode *TheRet, CCAssignFn Fn) { /// AnalyzeCallOperands - Analyze an ISD::CALL node, incorporating info /// about the passed values into this state. -void CCState::AnalyzeCallOperands(SDNode *TheCall, CCAssignFn Fn) { - unsigned NumOps = (TheCall->getNumOperands() - 5) / 2; +void CCState::AnalyzeCallOperands(CallSDNode *TheCall, CCAssignFn Fn) { + unsigned NumOps = TheCall->getNumArgs(); for (unsigned i = 0; i != NumOps; ++i) { - MVT ArgVT = TheCall->getOperand(5+2*i).getValueType(); - ISD::ArgFlagsTy ArgFlags = - cast(TheCall->getOperand(5+2*i+1))->getArgFlags(); + MVT ArgVT = TheCall->getArg(i).getValueType(); + ISD::ArgFlagsTy ArgFlags = TheCall->getArgFlags(i); if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, *this)) { cerr << "Call operand #" << i << " has unhandled type " << ArgVT.getMVTString() << "\n"; @@ -124,9 +123,9 @@ void CCState::AnalyzeCallOperands(SmallVectorImpl &ArgVTs, /// AnalyzeCallResult - Analyze the return values of an ISD::CALL node, /// incorporating info about the passed values into this state. -void CCState::AnalyzeCallResult(SDNode *TheCall, CCAssignFn Fn) { - for (unsigned i = 0, e = TheCall->getNumValues() - 1; i != e; ++i) { - MVT VT = TheCall->getValueType(i); +void CCState::AnalyzeCallResult(CallSDNode *TheCall, CCAssignFn Fn) { + for (unsigned i = 0, e = TheCall->getNumRetVals(); i != e; ++i) { + MVT VT = TheCall->getRetValType(i); if (Fn(i, VT, VT, CCValAssign::Full, ISD::ArgFlagsTy(), *this)) { cerr << "Call result #" << i << " has unhandled type " << VT.getMVTString() << "\n"; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 6ebd514999..921d7b060b 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -595,13 +595,13 @@ void SelectionDAG::DeleteNodeNotInCSEMaps(SDNode *N) { /// correspond to it. This is useful when we're about to delete or repurpose /// the node. We don't want future request for structurally identical nodes /// to return N anymore. -void SelectionDAG::RemoveNodeFromCSEMaps(SDNode *N) { +bool SelectionDAG::RemoveNodeFromCSEMaps(SDNode *N) { bool Erased = false; switch (N->getOpcode()) { case ISD::EntryToken: assert(0 && "EntryToken should not be in CSEMaps!"); - return; - case ISD::HANDLENODE: return; // noop. + return false; + case ISD::HANDLENODE: return false; // noop. case ISD::CONDCODE: assert(CondCodeNodes[cast(N)->get()] && "Cond code doesn't exist!"); @@ -635,7 +635,8 @@ void SelectionDAG::RemoveNodeFromCSEMaps(SDNode *N) { // flag result (which cannot be CSE'd) or is one of the special cases that are // not subject to CSE. if (!Erased && N->getValueType(N->getNumValues()-1) != MVT::Flag && - !N->isTargetOpcode() && + !N->isMachineOpcode() && + N->getOpcode() != ISD::CALL && N->getOpcode() != ISD::DBG_LABEL && N->getOpcode() != ISD::DBG_STOPPOINT && N->getOpcode() != ISD::EH_LABEL && @@ -645,6 +646,7 @@ void SelectionDAG::RemoveNodeFromCSEMaps(SDNode *N) { assert(0 && "Node is not in map!"); } #endif + return Erased; } /// AddNonLeafNodeToCSEMaps - Add the specified node back to the CSE maps. It @@ -660,6 +662,7 @@ SDNode *SelectionDAG::AddNonLeafNodeToCSEMaps(SDNode *N) { switch (N->getOpcode()) { default: break; + case ISD::CALL: case ISD::HANDLENODE: case ISD::DBG_LABEL: case ISD::DBG_STOPPOINT: @@ -3303,6 +3306,21 @@ SDValue SelectionDAG::getMergeValues(const SDValue *Ops, unsigned NumOps, return getNode(ISD::MERGE_VALUES, getVTList(&VTs[0], NumOps), Ops, NumOps); } +SDValue +SelectionDAG::getCall(unsigned CallingConv, bool IsVarArgs, bool IsTailCall, + SDVTList VTs, + const SDValue *Operands, unsigned NumOperands) { + // Do not CSE calls. Note that in addition to being a compile-time + // optimization (since attempting CSE of calls is unlikely to be + // meaningful), we actually depend on this behavior. CallSDNode can + // be mutated, which is only safe if calls are not CSE'd. + SDNode *N = NodeAllocator.Allocate(); + new (N) CallSDNode(CallingConv, IsVarArgs, IsTailCall, + VTs, Operands, NumOperands); + AllNodes.push_back(N); + return SDValue(N, 0); +} + SDValue SelectionDAG::getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType, MVT VT, SDValue Chain, @@ -3761,7 +3779,8 @@ SDValue SelectionDAG::UpdateNodeOperands(SDValue InN, SDValue Op) { // Nope it doesn't. Remove the node from its current place in the maps. if (InsertPos) - RemoveNodeFromCSEMaps(N); + if (!RemoveNodeFromCSEMaps(N)) + InsertPos = 0; // Now we update the operands. N->OperandList[0].getVal()->removeUser(0, N); @@ -3790,7 +3809,8 @@ UpdateNodeOperands(SDValue InN, SDValue Op1, SDValue Op2) { // Nope it doesn't. Remove the node from its current place in the maps. if (InsertPos) - RemoveNodeFromCSEMaps(N); + if (!RemoveNodeFromCSEMaps(N)) + InsertPos = 0; // Now we update the operands. if (N->OperandList[0] != Op1) { @@ -3856,7 +3876,8 @@ UpdateNodeOperands(SDValue InN, const SDValue *Ops, unsigned NumOps) { // Nope it doesn't. Remove the node from its current place in the maps. if (InsertPos) - RemoveNodeFromCSEMaps(N); + if (!RemoveNodeFromCSEMaps(N)) + InsertPos = 0; // Now we update the operands. for (unsigned i = 0; i != NumOps; ++i) { @@ -4079,7 +4100,8 @@ SDNode *SelectionDAG::MorphNodeTo(SDNode *N, unsigned Opc, return ON; } - RemoveNodeFromCSEMaps(N); + if (!RemoveNodeFromCSEMaps(N)) + IP = 0; // Start the morphing. N->NodeType = Opc; @@ -4582,6 +4604,7 @@ void MemSDNode::ANCHOR() {} void LoadSDNode::ANCHOR() {} void StoreSDNode::ANCHOR() {} void AtomicSDNode::ANCHOR() {} +void CallSDNode::ANCHOR() {} HandleSDNode::~HandleSDNode() { DropOperands(); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp index a95a50bea7..599f0dd82c 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp @@ -5325,9 +5325,6 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy, ArgListTy &Args, SelectionDAG &DAG) { SmallVector Ops; Ops.push_back(Chain); // Op#0 - Chain - Ops.push_back(DAG.getConstant(CallingConv, getPointerTy())); // Op#1 - CC - Ops.push_back(DAG.getConstant(isVarArg, getPointerTy())); // Op#2 - VarArg - Ops.push_back(DAG.getConstant(isTailCall, getPointerTy())); // Op#3 - Tail Ops.push_back(Callee); // Handle all of the outgoing arguments. @@ -5412,10 +5409,10 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy, LoweredRetTys.push_back(MVT::Other); // Always has a chain. // Create the CALL node. - SDValue Res = DAG.getNode(ISD::CALL, - DAG.getVTList(&LoweredRetTys[0], - LoweredRetTys.size()), - &Ops[0], Ops.size()); + SDValue Res = DAG.getCall(CallingConv, isVarArg, isTailCall, + DAG.getVTList(&LoweredRetTys[0], + LoweredRetTys.size()), + &Ops[0], Ops.size()); Chain = Res.getValue(LoweredRetTys.size() - 1); // Gather up the call result into a single value. diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 3159db4c21..fa175109e9 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -402,56 +402,45 @@ static void CheckDAGForTailCallsAndFixThem(SelectionDAG &DAG, for (SelectionDAG::allnodes_iterator BE = DAG.allnodes_begin(), BI = DAG.allnodes_end(); BI != BE; ) { --BI; - if (BI->getOpcode() == ISD::CALL) { + if (CallSDNode *TheCall = dyn_cast(BI)) { SDValue OpRet(Ret, 0); SDValue OpCall(BI, 0); - bool isMarkedTailCall = - cast(OpCall.getOperand(3))->getZExtValue() != 0; + bool isMarkedTailCall = TheCall->isTailCall(); // If CALL node has tail call attribute set to true and the call is not // eligible (no RET or the target rejects) the attribute is fixed to // false. The TargetLowering::IsEligibleForTailCallOptimization function // must correctly identify tail call optimizable calls. if (!isMarkedTailCall) continue; if (Ret==NULL || - !TLI.IsEligibleForTailCallOptimization(OpCall, OpRet, DAG)) { - // Not eligible. Mark CALL node as non tail call. - SmallVector Ops; - unsigned idx=0; - for(SDNode::op_iterator I =OpCall.getNode()->op_begin(), - E = OpCall.getNode()->op_end(); I != E; I++, idx++) { - if (idx!=3) - Ops.push_back(*I); - else - Ops.push_back(DAG.getConstant(false, TLI.getPointerTy())); - } - DAG.UpdateNodeOperands(OpCall, Ops.begin(), Ops.size()); + !TLI.IsEligibleForTailCallOptimization(TheCall, OpRet, DAG)) { + // Not eligible. Mark CALL node as non tail call. Note that we + // can modify the call node in place since calls are not CSE'd. + TheCall->setNotTailCall(); } else { // Look for tail call clobbered arguments. Emit a series of // copyto/copyfrom virtual register nodes to protect them. SmallVector Ops; - SDValue Chain = OpCall.getOperand(0), InFlag; - unsigned idx=0; - for(SDNode::op_iterator I = OpCall.getNode()->op_begin(), - E = OpCall.getNode()->op_end(); I != E; I++, idx++) { - SDValue Arg = *I; - if (idx > 4 && (idx % 2)) { - bool isByVal = cast(OpCall.getOperand(idx+1))-> - getArgFlags().isByVal(); - MachineFunction &MF = DAG.getMachineFunction(); - MachineFrameInfo *MFI = MF.getFrameInfo(); - if (!isByVal && - IsPossiblyOverwrittenArgumentOfTailCall(Arg, MFI)) { - MVT VT = Arg.getValueType(); - unsigned VReg = MF.getRegInfo(). - createVirtualRegister(TLI.getRegClassFor(VT)); - Chain = DAG.getCopyToReg(Chain, VReg, Arg, InFlag); - InFlag = Chain.getValue(1); - Arg = DAG.getCopyFromReg(Chain, VReg, VT, InFlag); - Chain = Arg.getValue(1); - InFlag = Arg.getValue(2); - } + SDValue Chain = TheCall->getChain(), InFlag; + Ops.push_back(Chain); + Ops.push_back(TheCall->getCallee()); + for (unsigned i = 0, e = TheCall->getNumArgs(); i != e; ++i) { + SDValue Arg = TheCall->getArg(i); + bool isByVal = TheCall->getArgFlags(i).isByVal(); + MachineFunction &MF = DAG.getMachineFunction(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + if (!isByVal && + IsPossiblyOverwrittenArgumentOfTailCall(Arg, MFI)) { + MVT VT = Arg.getValueType(); + unsigned VReg = MF.getRegInfo(). + createVirtualRegister(TLI.getRegClassFor(VT)); + Chain = DAG.getCopyToReg(Chain, VReg, Arg, InFlag); + InFlag = Chain.getValue(1); + Arg = DAG.getCopyFromReg(Chain, VReg, VT, InFlag); + Chain = Arg.getValue(1); + InFlag = Arg.getValue(2); } Ops.push_back(Arg); + Ops.push_back(TheCall->getArgFlagsVal(i)); } // Link in chain of CopyTo/CopyFromReg. Ops[0] = Chain; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp index f2cd3c1b7a..570caa9701 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp @@ -179,6 +179,12 @@ std::string DOTGraphTraits::getNodeLabel(const SDNode *Node, Op += ":" + utostr(D->getColumn()); } else if (const LabelSDNode *L = dyn_cast(Node)) { Op += ": LabelID=" + utostr(L->getLabelID()); + } else if (const CallSDNode *C = dyn_cast(Node)) { + Op += ": CallingConv=" + utostr(C->getCallingConv()); + if (C->isVarArg()) + Op += ", isVarArg"; + if (C->isTailCall()) + Op += ", isTailCall"; } else if (const ExternalSymbolSDNode *ES = dyn_cast(Node)) { Op += "'" + std::string(ES->getSymbol()) + "'"; diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index cb0fa8e872..2202177e18 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -410,13 +410,14 @@ HowToPassArgument(MVT ObjectVT, unsigned NumGPRs, /// ARMISD:CALL <- callseq_end chain. Also add input and output parameter /// nodes. SDValue ARMTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { - MVT RetVT= Op.getNode()->getValueType(0); - SDValue Chain = Op.getOperand(0); - unsigned CallConv = cast(Op.getOperand(1))->getZExtValue(); + CallSDNode *TheCall = cast(Op.getNode()); + MVT RetVT = TheCall->getRetValType(0); + SDValue Chain = TheCall->getChain(); + unsigned CallConv = TheCall->getCallingConv(); assert((CallConv == CallingConv::C || CallConv == CallingConv::Fast) && "unknown calling convention"); - SDValue Callee = Op.getOperand(4); - unsigned NumOps = (Op.getNumOperands() - 5) / 2; + SDValue Callee = TheCall->getCallee(); + unsigned NumOps = TheCall->getNumArgs(); unsigned ArgOffset = 0; // Frame mechanisms handle retaddr slot unsigned NumGPRs = 0; // GPRs used for parameter passing. @@ -429,9 +430,8 @@ SDValue ARMTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { unsigned ObjGPRs; unsigned StackPad; unsigned GPRPad; - MVT ObjectVT = Op.getOperand(5+2*i).getValueType(); - ISD::ArgFlagsTy Flags = - cast(Op.getOperand(5+2*i+1))->getArgFlags(); + MVT ObjectVT = TheCall->getArg(i).getValueType(); + ISD::ArgFlagsTy Flags = TheCall->getArgFlags(i); HowToPassArgument(ObjectVT, NumGPRs, NumBytes, ObjGPRs, ObjSize, GPRPad, StackPad, Flags); NumBytes += ObjSize + StackPad; @@ -453,9 +453,8 @@ SDValue ARMTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { std::vector > RegsToPass; std::vector MemOpChains; for (unsigned i = 0; i != NumOps; ++i) { - SDValue Arg = Op.getOperand(5+2*i); - ISD::ArgFlagsTy Flags = - cast(Op.getOperand(5+2*i+1))->getArgFlags(); + SDValue Arg = TheCall->getArg(i); + ISD::ArgFlagsTy Flags = TheCall->getArgFlags(i); MVT ArgVT = Arg.getValueType(); unsigned ObjSize; @@ -631,7 +630,8 @@ SDValue ARMTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { case MVT::i32: Chain = DAG.getCopyFromReg(Chain, ARM::R0, MVT::i32, InFlag).getValue(1); ResultVals.push_back(Chain.getValue(0)); - if (Op.getNode()->getValueType(1) == MVT::i32) { + if (TheCall->getNumRetVals() > 1 && + TheCall->getRetValType(1) == MVT::i32) { // Returns a i64 value. Chain = DAG.getCopyFromReg(Chain, ARM::R1, MVT::i32, Chain.getValue(2)).getValue(1); diff --git a/lib/Target/CellSPU/SPUISelLowering.cpp b/lib/Target/CellSPU/SPUISelLowering.cpp index eec428bbab..384755d665 100644 --- a/lib/Target/CellSPU/SPUISelLowering.cpp +++ b/lib/Target/CellSPU/SPUISelLowering.cpp @@ -1101,13 +1101,14 @@ static SDNode *isLSAAddress(SDValue Op, SelectionDAG &DAG) { static SDValue LowerCALL(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) { - SDValue Chain = Op.getOperand(0); + CallSDNode *TheCall = cast(Op.getNode()); + SDValue Chain = TheCall->getChain(); #if 0 - bool isVarArg = cast(Op.getOperand(2))->getZExtValue() != 0; - bool isTailCall = cast(Op.getOperand(3))->getZExtValue() != 0; + bool isVarArg = TheCall->isVarArg(); + bool isTailCall = TheCall->isTailCall(); #endif - SDValue Callee = Op.getOperand(4); - unsigned NumOps = (Op.getNumOperands() - 5) / 2; + SDValue Callee = TheCall->getCallee(); + unsigned NumOps = TheCall->getNumArgs(); unsigned StackSlotSize = SPUFrameInfo::stackSlotSize(); const unsigned *ArgRegs = SPURegisterInfo::getArgRegs(); const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs(); @@ -1136,7 +1137,7 @@ LowerCALL(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) { SmallVector MemOpChains; for (unsigned i = 0; i != NumOps; ++i) { - SDValue Arg = Op.getOperand(5+2*i); + SDValue Arg = TheCall->getArg(i); // PtrOff will be used to store the current argument to the stack if a // register cannot be found for it. @@ -1256,18 +1257,18 @@ LowerCALL(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) { DAG.getConstant(NumStackBytes, PtrVT), DAG.getConstant(0, PtrVT), InFlag); - if (Op.getNode()->getValueType(0) != MVT::Other) + if (TheCall->getValueType(0) != MVT::Other) InFlag = Chain.getValue(1); SDValue ResultVals[3]; unsigned NumResults = 0; // If the call has results, copy the values out of the ret val registers. - switch (Op.getNode()->getValueType(0).getSimpleVT()) { + switch (TheCall->getValueType(0).getSimpleVT()) { default: assert(0 && "Unexpected ret value!"); case MVT::Other: break; case MVT::i32: - if (Op.getNode()->getValueType(1) == MVT::i32) { + if (TheCall->getValueType(1) == MVT::i32) { Chain = DAG.getCopyFromReg(Chain, SPU::R4, MVT::i32, InFlag).getValue(1); ResultVals[0] = Chain.getValue(0); Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i32, @@ -1287,7 +1288,7 @@ LowerCALL(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) { break; case MVT::f32: case MVT::f64: - Chain = DAG.getCopyFromReg(Chain, SPU::R3, Op.getNode()->getValueType(0), + Chain = DAG.getCopyFromReg(Chain, SPU::R3, TheCall->getValueType(0), InFlag).getValue(1); ResultVals[0] = Chain.getValue(0); NumResults = 1; @@ -1297,7 +1298,7 @@ LowerCALL(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) { case MVT::v4i32: case MVT::v8i16: case MVT::v16i8: - Chain = DAG.getCopyFromReg(Chain, SPU::R3, Op.getNode()->getValueType(0), + Chain = DAG.getCopyFromReg(Chain, SPU::R3, TheCall->getValueType(0), InFlag).getValue(1); ResultVals[0] = Chain.getValue(0); NumResults = 1; diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 1f77b13021..557a1050c6 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -585,10 +585,11 @@ LowerCALL(SDValue Op, SelectionDAG &DAG) { MachineFunction &MF = DAG.getMachineFunction(); - SDValue Chain = Op.getOperand(0); - SDValue Callee = Op.getOperand(4); - bool isVarArg = cast(Op.getOperand(2))->getZExtValue() != 0; - unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv(); + CallSDNode *TheCall = cast(Op.getNode()); + SDValue Chain = TheCall->getChain(); + SDValue Callee = TheCall->getCallee(); + bool isVarArg = TheCall->isVarArg(); + unsigned CC = TheCall->getCallingConv(); MachineFrameInfo *MFI = MF.getFrameInfo(); @@ -603,7 +604,7 @@ LowerCALL(SDValue Op, SelectionDAG &DAG) MFI->CreateFixedObject(VTsize, (VTsize*3)); } - CCInfo.AnalyzeCallOperands(Op.getNode(), CC_Mips); + CCInfo.AnalyzeCallOperands(TheCall, CC_Mips); // Get a count of how many bytes are to be pushed on the stack. unsigned NumBytes = CCInfo.getNextStackOffset(); @@ -624,7 +625,7 @@ LowerCALL(SDValue Op, SelectionDAG &DAG) CCValAssign &VA = ArgLocs[i]; // Arguments start after the 5 first operands of ISD::CALL - SDValue Arg = Op.getOperand(5+2*VA.getValNo()); + SDValue Arg = TheCall->getArg(i); // Promote the value if needed. switch (VA.getLocInfo()) { @@ -751,7 +752,7 @@ LowerCALL(SDValue Op, SelectionDAG &DAG) // Handle result values, copying them out of physregs into vregs that we // return. - return SDValue(LowerCallResult(Chain, InFlag, Op.getNode(), CC, DAG), Op.getResNo()); + return SDValue(LowerCallResult(Chain, InFlag, TheCall, CC, DAG), Op.getResNo()); } /// LowerCallResult - Lower the result values of an ISD::CALL into the @@ -760,11 +761,10 @@ LowerCALL(SDValue Op, SelectionDAG &DAG) /// being lowered. Returns a SDNode with the same number of values as the /// ISD::CALL. SDNode *MipsTargetLowering:: -LowerCallResult(SDValue Chain, SDValue InFlag, SDNode *TheCall, +LowerCallResult(SDValue Chain, SDValue InFlag, CallSDNode *TheCall, unsigned CallingConv, SelectionDAG &DAG) { - bool isVarArg = - cast(TheCall->getOperand(2))->getZExtValue() != 0; + bool isVarArg = TheCall->isVarArg(); // Assign locations to each value returned by this call. SmallVector RVLocs; diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h index 9d8a756e76..fd595c9464 100644 --- a/lib/Target/Mips/MipsISelLowering.h +++ b/lib/Target/Mips/MipsISelLowering.h @@ -86,7 +86,7 @@ namespace llvm { const MipsSubtarget *Subtarget; // Lower Operand helpers - SDNode *LowerCallResult(SDValue Chain, SDValue InFlag, SDNode*TheCall, + SDNode *LowerCallResult(SDValue Chain, SDValue InFlag, CallSDNode *TheCall, unsigned CallingConv, SelectionDAG &DAG); bool IsGlobalInSmallSection(GlobalValue *GV); bool IsInSmallSection(unsigned Size); diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index edac162427..1a891d93f5 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -1328,10 +1328,9 @@ static const unsigned *GetFPR(const PPCSubtarget &Subtarget) { /// CalculateStackSlotSize - Calculates the size reserved for this argument on /// the stack. -static unsigned CalculateStackSlotSize(SDValue Arg, SDValue Flag, +static unsigned CalculateStackSlotSize(SDValue Arg, ISD::ArgFlagsTy Flags, bool isVarArg, unsigned PtrByteSize) { MVT ArgVT = Arg.getValueType(); - ISD::ArgFlagsTy Flags = cast(Flag)->getArgFlags(); unsigned ArgSize =ArgVT.getSizeInBits()/8; if (Flags.isByVal()) ArgSize = Flags.getByValSize(); @@ -1475,14 +1474,14 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, if (isVarArg || isPPC64) { MinReservedArea = ((MinReservedArea+15)/16)*16; MinReservedArea += CalculateStackSlotSize(Op.getValue(ArgNo), - Op.getOperand(ArgNo+3), + Flags, isVarArg, PtrByteSize); } else nAltivecParamsAtEnd++; } else // Calculate min reserved area. MinReservedArea += CalculateStackSlotSize(Op.getValue(ArgNo), - Op.getOperand(ArgNo+3), + Flags, isVarArg, PtrByteSize); @@ -1794,13 +1793,13 @@ CalculateParameterAndLinkageAreaSize(SelectionDAG &DAG, bool isMachoABI, bool isVarArg, unsigned CC, - SDValue Call, + CallSDNode *TheCall, unsigned &nAltivecParamsAtEnd) { // Count how many bytes are to be pushed on the stack, including the linkage // area, and parameter passing area. We start with 24/48 bytes, which is // prereserved space for [SP][CR][LR][3 x unused]. unsigned NumBytes = PPCFrameInfo::getLinkageSize(isPPC64, isMachoABI); - unsigned NumOps = (Call.getNumOperands() - 5) / 2; + unsigned NumOps = TheCall->getNumArgs(); unsigned PtrByteSize = isPPC64 ? 8 : 4; // Add up all the space actually used. @@ -1811,8 +1810,8 @@ CalculateParameterAndLinkageAreaSize(SelectionDAG &DAG, // 16-byte aligned. nAltivecParamsAtEnd = 0; for (unsigned i = 0; i != NumOps; ++i) { - SDValue Arg = Call.getOperand(5+2*i); - SDValue Flag = Call.getOperand(5+2*i+1); + SDValue Arg = TheCall->getArg(i); + ISD::ArgFlagsTy Flags = TheCall->getArgFlags(i); MVT ArgVT = Arg.getValueType(); // Varargs Altivec parameters are padded to a 16 byte boundary. if (ArgVT==MVT::v4f32 || ArgVT==MVT::v4i32 || @@ -1826,7 +1825,7 @@ CalculateParameterAndLinkageAreaSize(SelectionDAG &DAG, // Varargs and 64-bit Altivec parameters are padded to 16 byte boundary. NumBytes = ((NumBytes+15)/16)*16; } - NumBytes += CalculateStackSlotSize(Arg, Flag, isVarArg, PtrByteSize); + NumBytes += CalculateStackSlotSize(Arg, Flags, isVarArg, PtrByteSize); } // Allow for Altivec parameters at the end, if needed. @@ -1876,27 +1875,25 @@ static int CalculateTailCallSPDiff(SelectionDAG& DAG, bool IsTailCall, /// calling conventions match, currently only fastcc supports tail calls, and /// the function CALL is immediatly followed by a RET. bool -PPCTargetLowering::IsEligibleForTailCallOptimization(SDValue Call, +PPCTargetLowering::IsEligibleForTailCallOptimization(CallSDNode *TheCall, SDValue Ret, SelectionDAG& DAG) const { // Variable argument functions are not supported. - if (!PerformTailCallOpt || - cast(Call.getOperand(2))->getZExtValue() != 0) + if (!PerformTailCallOpt || TheCall->isVarArg()) return false; - if (CheckTailCallReturnConstraints(Call, Ret)) { + if (CheckTailCallReturnConstraints(TheCall, Ret)) { MachineFunction &MF = DAG.getMachineFunction(); unsigned CallerCC = MF.getFunction()->getCallingConv(); - unsigned CalleeCC= cast(Call.getOperand(1))->getZExtValue(); + unsigned CalleeCC = TheCall->getCallingConv(); if (CalleeCC == CallingConv::Fast && CallerCC == CalleeCC) { // Functions containing by val parameters are not supported. - for (unsigned i = 0; i != ((Call.getNumOperands()-5)/2); i++) { - ISD::ArgFlagsTy Flags = cast(Call.getOperand(5+2*i+1)) - ->getArgFlags(); + for (unsigned i = 0; i != TheCall->getNumArgs(); i++) { + ISD::ArgFlagsTy Flags = TheCall->getArgFlags(i); if (Flags.isByVal()) return false; } - SDValue Callee = Call.getOperand(4); + SDValue Callee = TheCall->getCallee(); // Non PIC/GOT tail calls are supported. if (getTargetMachine().getRelocationModel() != Reloc::PIC_) return true; @@ -2070,13 +2067,14 @@ LowerMemOpCallTo(SelectionDAG &DAG, MachineFunction &MF, SDValue Chain, SDValue PPCTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG, const PPCSubtarget &Subtarget, TargetMachine &TM) { - SDValue Chain = Op.getOperand(0); - bool isVarArg = cast(Op.getOperand(2))->getZExtValue() != 0; - unsigned CC = cast(Op.getOperand(1))->getZExtValue(); - bool isTailCall = cast(Op.getOperand(3))->getZExtValue() != 0 + CallSDNode *TheCall = cast(Op.getNode()); + SDValue Chain = TheCall->getChain(); + bool isVarArg = TheCall->isVarArg(); + unsigned CC = TheCall->getCallingConv(); + bool isTailCall = TheCall->isTailCall() && CC == CallingConv::Fast && PerformTailCallOpt; - SDValue Callee = Op.getOperand(4); - unsigned NumOps = (Op.getNumOperands() - 5) / 2; + SDValue Callee = TheCall->getCallee(); + unsigned NumOps = TheCall->getNumArgs(); bool isMachoABI = Subtarget.isMachoABI(); bool isELF32_ABI = Subtarget.isELF32_ABI(); @@ -2106,7 +2104,7 @@ SDValue PPCTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG, // prereserved space for [SP][CR][LR][3 x unused]. unsigned NumBytes = CalculateParameterAndLinkageAreaSize(DAG, isPPC64, isMachoABI, isVarArg, CC, - Op, nAltivecParamsAtEnd); + TheCall, nAltivecParamsAtEnd); // Calculate by how many bytes the stack has to be adjusted in case of tail // call optimization. @@ -2165,9 +2163,8 @@ SDValue PPCTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG, SmallVector MemOpChains; for (unsigned i = 0; i != NumOps; ++i) { bool inMem = false; - SDValue Arg = Op.getOperand(5+2*i); - ISD::ArgFlagsTy Flags = - cast(Op.getOperand(5+2*i+1))->getArgFlags(); + SDValue Arg = TheCall->getArg(i); + ISD::ArgFlagsTy Flags = TheCall->getArgFlags(i); // See if next argument requires stack alignment in ELF bool Align = Flags.isSplit(); @@ -2391,7 +2388,7 @@ SDValue PPCTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG, ArgOffset = ((ArgOffset+15)/16)*16; ArgOffset += 12*16; for (unsigned i = 0; i != NumOps; ++i) { - SDValue Arg = Op.getOperand(5+2*i); + SDValue Arg = TheCall->getArg(i); MVT ArgType = Arg.getValueType(); if (ArgType==MVT::v4f32 || ArgType==MVT::v4i32 || ArgType==MVT::v8i16 || ArgType==MVT::v16i8) { @@ -2530,7 +2527,7 @@ SDValue PPCTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG, assert(InFlag.getNode() && "Flag must be set. Depend on flag being set in LowerRET"); Chain = DAG.getNode(PPCISD::TAILCALL, - Op.getNode()->getVTList(), &Ops[0], Ops.size()); + TheCall->getVTList(), &Ops[0], Ops.size()); return SDValue(Chain.getNode(), Op.getResNo()); } @@ -2541,14 +2538,14 @@ SDValue PPCTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG, DAG.getConstant(NumBytes, PtrVT), DAG.getConstant(BytesCalleePops, PtrVT), InFlag); - if (Op.getNode()->getValueType(0) != MVT::Other) + if (TheCall->getValueType(0) != MVT::Other) InFlag = Chain.getValue(1); SmallVector ResultVals; SmallVector RVLocs; unsigned CallerCC = DAG.getMachineFunction().getFunction()->getCallingConv(); CCState CCInfo(CallerCC, isVarArg, TM, RVLocs); - CCInfo.AnalyzeCallResult(Op.getNode(), RetCC_PPC); + CCInfo.AnalyzeCallResult(TheCall, RetCC_PPC); // Copy all of the result registers out of their specified physreg. for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) { @@ -2566,7 +2563,7 @@ SDValue PPCTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG, // Otherwise, merge everything together with a MERGE_VALUES node. ResultVals.push_back(Chain); - SDValue Res = DAG.getMergeValues(Op.getNode()->getVTList(), &ResultVals[0], + SDValue Res = DAG.getMergeValues(TheCall->getVTList(), &ResultVals[0], ResultVals.size()); return Res.getValue(Op.getResNo()); } diff --git a/lib/Target/PowerPC/PPCISelLowering.h b/lib/Target/PowerPC/PPCISelLowering.h index ff969d2f5d..72e00f64ab 100644 --- a/lib/Target/PowerPC/PPCISelLowering.h +++ b/lib/Target/PowerPC/PPCISelLowering.h @@ -322,7 +322,7 @@ namespace llvm { /// IsEligibleForTailCallOptimization - Check whether the call is eligible /// for tail call optimization. Target which want to do tail call /// optimization should implement this function. - virtual bool IsEligibleForTailCallOptimization(SDValue Call, + virtual bool IsEligibleForTailCallOptimization(CallSDNode *TheCall, SDValue Ret, SelectionDAG &DAG) const; diff --git a/lib/Target/Sparc/SparcISelLowering.cpp b/lib/Target/Sparc/SparcISelLowering.cpp index 07b108ddd1..d89b6d44ff 100644 --- a/lib/Target/Sparc/SparcISelLowering.cpp +++ b/lib/Target/Sparc/SparcISelLowering.cpp @@ -224,10 +224,11 @@ SparcTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG, } static SDValue LowerCALL(SDValue Op, SelectionDAG &DAG) { - unsigned CallingConv = cast(Op.getOperand(1))->getZExtValue(); - SDValue Chain = Op.getOperand(0); - SDValue Callee = Op.getOperand(4); - bool isVarArg = cast(Op.getOperand(2))->getZExtValue() != 0; + CallSDNode *TheCall = cast(Op.getNode()); + unsigned CallingConv = TheCall->getCallingConv(); + SDValue Chain = TheCall->getChain(); + SDValue Callee = TheCall->getCallee(); + bool isVarArg = TheCall->isVarArg(); #if 0 // Analyze operands of the call, assigning locations to each operand. @@ -243,8 +244,8 @@ static SDValue LowerCALL(SDValue Op, SelectionDAG &DAG) { // Count the size of the outgoing arguments. unsigned ArgsSize = 0; - for (unsigned i = 5, e = Op.getNumOperands(); i != e; i += 2) { - switch (Op.getOperand(i).getValueType().getSimpleVT()) { + for (unsigned i = 0, e = TheCall->getNumArgs(); i != e; ++i) { + switch (TheCall->getArg(i).getValueType().getSimpleVT()) { default: assert(0 && "Unknown value type!"); case MVT::i1: case MVT::i8: @@ -279,7 +280,7 @@ static SDValue LowerCALL(SDValue Op, SelectionDAG &DAG) { CCValAssign &VA = ArgLocs[i]; // Arguments start after the 5 first operands of ISD::CALL - SDValue Arg = Op.getOperand(5+2*VA.getValNo()); + SDValue Arg = TheCall->getArg(i); // Promote the value if needed. switch (VA.getLocInfo()) { @@ -319,8 +320,8 @@ static SDValue LowerCALL(SDValue Op, SelectionDAG &DAG) { }; unsigned ArgOffset = 68; - for (unsigned i = 5, e = Op.getNumOperands(); i != e; i += 2) { - SDValue Val = Op.getOperand(i); + for (unsigned i = 0, e = TheCall->getNumArgs(); i != e; ++i) { + SDValue Val = TheCall->getArg(i); MVT ObjectVT = Val.getValueType(); SDValue ValToStore(0, 0); unsigned ObjSize; @@ -428,7 +429,7 @@ static SDValue LowerCALL(SDValue Op, SelectionDAG &DAG) { SmallVector RVLocs; CCState RVInfo(CallingConv, isVarArg, DAG.getTarget(), RVLocs); - RVInfo.AnalyzeCallResult(Op.getNode(), RetCC_Sparc32); + RVInfo.AnalyzeCallResult(TheCall, RetCC_Sparc32); SmallVector ResultVals; // Copy all of the result registers out of their specified physreg. @@ -448,7 +449,7 @@ static SDValue LowerCALL(SDValue Op, SelectionDAG &DAG) { ResultVals.push_back(Chain); // Merge everything together with a MERGE_VALUES node. - return DAG.getMergeValues(Op.getNode()->getVTList(), &ResultVals[0], + return DAG.getMergeValues(TheCall->getVTList(), &ResultVals[0], ResultVals.size()); } diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index d8fbb5146a..4a9fd5162e 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -977,13 +977,12 @@ SDValue X86TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) { /// being lowered. The returns a SDNode with the same number of values as the /// ISD::CALL. SDNode *X86TargetLowering:: -LowerCallResult(SDValue Chain, SDValue InFlag, SDNode *TheCall, +LowerCallResult(SDValue Chain, SDValue InFlag, CallSDNode *TheCall, unsigned CallingConv, SelectionDAG &DAG) { // Assign locations to each value returned by this call. SmallVector RVLocs; - bool isVarArg = - cast(TheCall->getOperand(2))->getZExtValue() != 0; + bool isVarArg = TheCall->isVarArg(); CCState CCInfo(CallingConv, isVarArg, getTargetMachine(), RVLocs); CCInfo.AnalyzeCallResult(TheCall, RetCC_X86); @@ -1048,12 +1047,12 @@ static unsigned AddLiveIn(MachineFunction &MF, unsigned PReg, /// CallIsStructReturn - Determines whether a CALL node uses struct return /// semantics. -static bool CallIsStructReturn(SDValue Op) { - unsigned NumOps = (Op.getNumOperands() - 5) / 2; +static bool CallIsStructReturn(CallSDNode *TheCall) { + unsigned NumOps = TheCall->getNumArgs(); if (!NumOps) return false; - return cast(Op.getOperand(6))->getArgFlags().isSRet(); + return TheCall->getArgFlags(0).isSRet(); } /// ArgsAreStructReturn - Determines whether a FORMAL_ARGUMENTS node uses struct @@ -1069,12 +1068,11 @@ static bool ArgsAreStructReturn(SDValue Op) { /// IsCalleePop - Determines whether a CALL or FORMAL_ARGUMENTS node requires /// the callee to pop its own arguments. Callee pop is necessary to support tail /// calls. -bool X86TargetLowering::IsCalleePop(SDValue Op) { - bool IsVarArg = cast(Op.getOperand(2))->getZExtValue() != 0; +bool X86TargetLowering::IsCalleePop(bool IsVarArg, unsigned CallingConv) { if (IsVarArg) return false; - switch (cast(Op.getOperand(1))->getZExtValue()) { + switch (CallingConv) { default: return false; case CallingConv::X86_StdCall: @@ -1086,11 +1084,9 @@ bool X86TargetLowering::IsCalleePop(SDValue Op) { } } -/// CCAssignFnForNode - Selects the correct CCAssignFn for a CALL or -/// FORMAL_ARGUMENTS node. -CCAssignFn *X86TargetLowering::CCAssignFnForNode(SDValue Op) const { - unsigned CC = cast(Op.getOperand(1))->getZExtValue(); - +/// CCAssignFnForNode - Selects the correct CCAssignFn for a the +/// given CallingConvention value. +CCAssignFn *X86TargetLowering::CCAssignFnForNode(unsigned CC) const { if (Subtarget->is64Bit()) { if (Subtarget->isTargetWin64()) return CC_X86_Win64_C; @@ -1203,7 +1199,7 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) { // Assign locations to all of the incoming arguments. SmallVector ArgLocs; CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs); - CCInfo.AnalyzeFormalArguments(Op.getNode(), CCAssignFnForNode(Op)); + CCInfo.AnalyzeFormalArguments(Op.getNode(), CCAssignFnForNode(CC)); SmallVector ArgValues; unsigned LastVal = ~0U; @@ -1388,7 +1384,7 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) { ArgValues.push_back(Root); // Some CCs need callee pop. - if (IsCalleePop(Op)) { + if (IsCalleePop(isVarArg, CC)) { BytesToPopOnReturn = StackSize; // Callee pops everything. BytesCallerReserves = 0; } else { @@ -1413,16 +1409,14 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) { } SDValue -X86TargetLowering::LowerMemOpCallTo(SDValue Op, SelectionDAG &DAG, +X86TargetLowering::LowerMemOpCallTo(CallSDNode *TheCall, SelectionDAG &DAG, const SDValue &StackPtr, const CCValAssign &VA, SDValue Chain, - SDValue Arg) { + SDValue Arg, ISD::ArgFlagsTy Flags) { unsigned LocMemOffset = VA.getLocMemOffset(); SDValue PtrOff = DAG.getIntPtrConstant(LocMemOffset); PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff); - ISD::ArgFlagsTy Flags = - cast(Op.getOperand(6+2*VA.getValNo()))->getArgFlags(); if (Flags.isByVal()) { return CreateCopyOfByValArgument(Arg, PtrOff, Chain, Flags, DAG); } @@ -1470,14 +1464,15 @@ EmitTailCallStoreRetAddr(SelectionDAG & DAG, MachineFunction &MF, SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { MachineFunction &MF = DAG.getMachineFunction(); - SDValue Chain = Op.getOperand(0); - unsigned CC = cast(Op.getOperand(1))->getZExtValue(); - bool isVarArg = cast(Op.getOperand(2))->getZExtValue() != 0; - bool IsTailCall = cast(Op.getOperand(3))->getZExtValue() != 0 - && CC == CallingConv::Fast && PerformTailCallOpt; - SDValue Callee = Op.getOperand(4); + CallSDNode *TheCall = cast(Op.getNode()); + SDValue Chain = TheCall->getChain(); + unsigned CC = TheCall->getCallingConv(); + bool isVarArg = TheCall->isVarArg(); + bool IsTailCall = TheCall->isTailCall() && + CC == CallingConv::Fast && PerformTailCallOpt; + SDValue Callee = TheCall->getCallee(); bool Is64Bit = Subtarget->is64Bit(); - bool IsStructRet = CallIsStructReturn(Op); + bool IsStructRet = CallIsStructReturn(TheCall); assert(!(isVarArg && CC == CallingConv::Fast) && "Var args not supported with calling convention fastcc"); @@ -1485,7 +1480,7 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { // Analyze operands of the call, assigning locations to each operand. SmallVector ArgLocs; CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs); - CCInfo.AnalyzeCallOperands(Op.getNode(), CCAssignFnForNode(Op)); + CCInfo.AnalyzeCallOperands(TheCall, CCAssignFnForNode(CC)); // Get a count of how many bytes are to be pushed on the stack. unsigned NumBytes = CCInfo.getNextStackOffset(); @@ -1520,9 +1515,9 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { // of tail call optimization arguments are handle later. for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { CCValAssign &VA = ArgLocs[i]; - SDValue Arg = Op.getOperand(5+2*VA.getValNo()); - bool isByVal = cast(Op.getOperand(6+2*VA.getValNo()))-> - getArgFlags().isByVal(); + SDValue Arg = TheCall->getArg(i); + ISD::ArgFlagsTy Flags = TheCall->getArgFlags(i); + bool isByVal = Flags.isByVal(); // Promote the value if needed. switch (VA.getLocInfo()) { @@ -1571,8 +1566,8 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { if (StackPtr.getNode() == 0) StackPtr = DAG.getCopyFromReg(Chain, X86StackPtr, getPointerTy()); - MemOpChains.push_back(LowerMemOpCallTo(Op, DAG, StackPtr, VA, Chain, - Arg)); + MemOpChains.push_back(LowerMemOpCallTo(TheCall, DAG, StackPtr, VA, + Chain, Arg, Flags)); } } } @@ -1651,10 +1646,8 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { CCValAssign &VA = ArgLocs[i]; if (!VA.isRegLoc()) { assert(VA.isMemLoc()); - SDValue Arg = Op.getOperand(5+2*VA.getValNo()); - SDValue FlagsOp = Op.getOperand(6+2*VA.getValNo()); - ISD::ArgFlagsTy Flags = - cast(FlagsOp)->getArgFlags(); + SDValue Arg = TheCall->getArg(i); + ISD::ArgFlagsTy Flags = TheCall->getArgFlags(i); // Create frame index. int32_t Offset = VA.getLocMemOffset()+FPDiff; uint32_t OpSize = (VA.getLocVT().getSizeInBits()+7)/8; @@ -1764,7 +1757,7 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { assert(InFlag.getNode() && "Flag must be set. Depend on flag being set in LowerRET"); Chain = DAG.getNode(X86ISD::TAILCALL, - Op.getNode()->getVTList(), &Ops[0], Ops.size()); + TheCall->getVTList(), &Ops[0], Ops.size()); return SDValue(Chain.getNode(), Op.getResNo()); } @@ -1774,7 +1767,7 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { // Create the CALLSEQ_END node. unsigned NumBytesForCalleeToPush; - if (IsCalleePop(Op)) + if (IsCalleePop(isVarArg, CC)) NumBytesForCalleeToPush = NumBytes; // Callee pops everything else if (!Is64Bit && CC != CallingConv::Fast && IsStructRet) // If this is is a call to a struct-return function, the callee @@ -1793,7 +1786,7 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { // Handle result values, copying them out of physregs into vregs that we // return. - return SDValue(LowerCallResult(Chain, InFlag, Op.getNode(), CC, DAG), + return SDValue(LowerCallResult(Chain, InFlag, TheCall, CC, DAG), Op.getResNo()); } @@ -1855,18 +1848,18 @@ unsigned X86TargetLowering::GetAlignedArgumentStackSize(unsigned StackSize, /// following the call is a return. A function is eligible if caller/callee /// calling conventions match, currently only fastcc supports tail calls, and /// the function CALL is immediatly followed by a RET. -bool X86TargetLowering::IsEligibleForTailCallOptimization(SDValue Call, +bool X86TargetLowering::IsEligibleForTailCallOptimization(CallSDNode *TheCall, SDValue Ret, SelectionDAG& DAG) const { if (!PerformTailCallOpt) return false; - if (CheckTailCallReturnConstraints(Call, Ret)) { + if (CheckTailCallReturnConstraints(TheCall, Ret)) { MachineFunction &MF = DAG.getMachineFunction(); unsigned CallerCC = MF.getFunction()->getCallingConv(); - unsigned CalleeCC= cast(Call.getOperand(1))->getZExtValue(); + unsigned CalleeCC= TheCall->getCallingConv(); if (CalleeCC == CallingConv::Fast && CallerCC == CalleeCC) { - SDValue Callee = Call.getOperand(4); + SDValue Callee = TheCall->getCallee(); // On x86/32Bit PIC/GOT tail calls are supported. if (getTargetMachine().getRelocationModel() != Reloc::PIC_ || !Subtarget->isPICStyleGOT()|| !Subtarget->is64Bit()) diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h index e5fc8ed4b7..221276743a 100644 --- a/lib/Target/X86/X86ISelLowering.h +++ b/lib/Target/X86/X86ISelLowering.h @@ -453,7 +453,7 @@ namespace llvm { /// IsEligibleForTailCallOptimization - Check whether the call is eligible /// for tail call optimization. Target which want to do tail call /// optimization should implement this function. - virtual bool IsEligibleForTailCallOptimization(SDValue Call, + virtual bool IsEligibleForTailCallOptimization(CallSDNode *TheCall, SDValue Ret, SelectionDAG &DAG) const; @@ -493,27 +493,27 @@ namespace llvm { bool X86ScalarSSEf32; bool X86ScalarSSEf64; - SDNode *LowerCallResult(SDValue Chain, SDValue InFlag, SDNode*TheCall, + SDNode *LowerCallResult(SDValue Chain, SDValue InFlag, CallSDNode *TheCall, unsigned CallingConv, SelectionDAG &DAG); SDValue LowerMemArgument(SDValue Op, SelectionDAG &DAG, const CCValAssign &VA, MachineFrameInfo *MFI, unsigned CC, SDValue Root, unsigned i); - SDValue LowerMemOpCallTo(SDValue Op, SelectionDAG &DAG, + SDValue LowerMemOpCallTo(CallSDNode *TheCall, SelectionDAG &DAG, const SDValue &StackPtr, const CCValAssign &VA, SDValue Chain, - SDValue Arg); + SDValue Arg, ISD::ArgFlagsTy Flags); // Call lowering helpers. - bool IsCalleePop(SDValue Op); + bool IsCalleePop(bool isVarArg, unsigned CallingConv); bool CallRequiresGOTPtrInReg(bool Is64Bit, bool IsTailCall); bool CallRequiresFnAddressInReg(bool Is64Bit, bool IsTailCall); SDValue EmitTailCallLoadRetAddr(SelectionDAG &DAG, SDValue &OutRetAddr, SDValue Chain, bool IsTailCall, bool Is64Bit, int FPDiff); - CCAssignFn *CCAssignFnForNode(SDValue Op) const; + CCAssignFn *CCAssignFnForNode(unsigned CallingConv) const; NameDecorationStyle NameDecorationForFORMAL_ARGUMENTS(SDValue Op); unsigned GetAlignedArgumentStackSize(unsigned StackSize, SelectionDAG &DAG); -- cgit v1.2.3