diff options
author | Dan Gohman <gohman@apple.com> | 2009-08-05 01:29:28 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2009-08-05 01:29:28 +0000 |
commit | 9178de1d2b1e0787539b83ed54ad505ff13169e8 (patch) | |
tree | 8c4b03205992cfc18f04ca67d586796b5d0dd344 /lib/Target | |
parent | 32e5ec2ca24e5a8582db12f6fa88fec2e7a6657b (diff) | |
download | external_llvm-9178de1d2b1e0787539b83ed54ad505ff13169e8.zip external_llvm-9178de1d2b1e0787539b83ed54ad505ff13169e8.tar.gz external_llvm-9178de1d2b1e0787539b83ed54ad505ff13169e8.tar.bz2 |
Major calling convention code refactoring.
Instead of awkwardly encoding calling-convention information with ISD::CALL,
ISD::FORMAL_ARGUMENTS, ISD::RET, and ISD::ARG_FLAGS nodes, TargetLowering
provides three virtual functions for targets to override:
LowerFormalArguments, LowerCall, and LowerRet, which replace the custom
lowering done on the special nodes. They provide the same information, but
in a more immediately usable format.
This also reworks much of the target-independent tail call logic. The
decision of whether or not to perform a tail call is now cleanly split
between target-independent portions, and the target dependent portion
in IsEligibleForTailCallOptimization.
This also synchronizes all in-tree targets, to help enable future
refactoring and feature work.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78142 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
32 files changed, 1562 insertions, 1523 deletions
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 987fc7f..af18c27 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -295,7 +295,6 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) setOperationAction(ISD::DBG_STOPPOINT, MVT::Other, Expand); setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); - setOperationAction(ISD::RET, MVT::Other, Custom); setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); setOperationAction(ISD::ConstantPool, MVT::i32, Custom); setOperationAction(ISD::GLOBAL_OFFSET_TABLE, MVT::i32, Custom); @@ -531,13 +530,6 @@ static bool FPCCToARMCC(ISD::CondCode CC, ARMCC::CondCodes &CondCode, //===----------------------------------------------------------------------===// // Calling Convention Implementation -// -// The lower operations present on calling convention works on this order: -// LowerCALL (virt regs --> phys regs, virt regs --> stack) -// LowerFORMAL_ARGUMENTS (phys --> virt regs, stack --> virt regs) -// LowerRET (virt regs --> phys regs) -// LowerCALL (phys regs --> virt regs) -// //===----------------------------------------------------------------------===// #include "ARMGenCallingConv.inc" @@ -694,25 +686,21 @@ CCAssignFn *ARMTargetLowering::CCAssignFnForNode(unsigned CC, } } -/// LowerCallResult - Lower the result values of an ISD::CALL into the -/// appropriate copies out of appropriate physical registers. This assumes that -/// Chain/InFlag are the input chain/flag to use, and that TheCall is the call -/// being lowered. The returns a SDNode with the same number of values as the -/// ISD::CALL. -SDNode *ARMTargetLowering:: -LowerCallResult(SDValue Chain, SDValue InFlag, CallSDNode *TheCall, - unsigned CallingConv, SelectionDAG &DAG) { +/// LowerCallResult - Lower the result values of a call into the +/// appropriate copies out of appropriate physical registers. +SDValue +ARMTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { - DebugLoc dl = TheCall->getDebugLoc(); // Assign locations to each value returned by this call. SmallVector<CCValAssign, 16> RVLocs; - bool isVarArg = TheCall->isVarArg(); - CCState CCInfo(CallingConv, isVarArg, getTargetMachine(), + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), RVLocs, *DAG.getContext()); - CCInfo.AnalyzeCallResult(TheCall, - CCAssignFnForNode(CallingConv, /* Return*/ true)); - - SmallVector<SDValue, 8> ResultVals; + CCInfo.AnalyzeCallResult(Ins, + CCAssignFnForNode(CallConv, /* Return*/ true)); // Copy all of the result registers out of their specified physreg. for (unsigned i = 0; i != RVLocs.size(); ++i) { @@ -764,13 +752,10 @@ LowerCallResult(SDValue Chain, SDValue InFlag, CallSDNode *TheCall, break; } - ResultVals.push_back(Val); + InVals.push_back(Val); } - // Merge everything together with a MERGE_VALUES node. - ResultVals.push_back(Chain); - return DAG.getNode(ISD::MERGE_VALUES, dl, TheCall->getVTList(), - &ResultVals[0], ResultVals.size()).getNode(); + return Chain; } /// CreateCopyOfByValArgument - Make a copy of an aggregate at address specified @@ -790,11 +775,11 @@ CreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain, /// LowerMemOpCallTo - Store the argument to the stack. SDValue -ARMTargetLowering::LowerMemOpCallTo(CallSDNode *TheCall, SelectionDAG &DAG, - const SDValue &StackPtr, - const CCValAssign &VA, SDValue Chain, - SDValue Arg, ISD::ArgFlagsTy Flags) { - DebugLoc dl = TheCall->getDebugLoc(); +ARMTargetLowering::LowerMemOpCallTo(SDValue Chain, + SDValue StackPtr, SDValue Arg, + DebugLoc dl, SelectionDAG &DAG, + const CCValAssign &VA, + ISD::ArgFlagsTy Flags) { unsigned LocMemOffset = VA.getLocMemOffset(); SDValue PtrOff = DAG.getIntPtrConstant(LocMemOffset); PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(), StackPtr, PtrOff); @@ -805,14 +790,13 @@ ARMTargetLowering::LowerMemOpCallTo(CallSDNode *TheCall, SelectionDAG &DAG, PseudoSourceValue::getStack(), LocMemOffset); } -void ARMTargetLowering::PassF64ArgInRegs(CallSDNode *TheCall, SelectionDAG &DAG, +void ARMTargetLowering::PassF64ArgInRegs(DebugLoc dl, SelectionDAG &DAG, SDValue Chain, SDValue &Arg, RegsToPassVector &RegsToPass, CCValAssign &VA, CCValAssign &NextVA, SDValue &StackPtr, SmallVector<SDValue, 8> &MemOpChains, ISD::ArgFlagsTy Flags) { - DebugLoc dl = TheCall->getDebugLoc(); SDValue fmrrd = DAG.getNode(ARMISD::FMRRD, dl, DAG.getVTList(MVT::i32, MVT::i32), Arg); @@ -825,27 +809,30 @@ void ARMTargetLowering::PassF64ArgInRegs(CallSDNode *TheCall, SelectionDAG &DAG, if (StackPtr.getNode() == 0) StackPtr = DAG.getCopyFromReg(Chain, dl, ARM::SP, getPointerTy()); - MemOpChains.push_back(LowerMemOpCallTo(TheCall, DAG, StackPtr, NextVA, - Chain, fmrrd.getValue(1), Flags)); + MemOpChains.push_back(LowerMemOpCallTo(Chain, StackPtr, fmrrd.getValue(1), + dl, DAG, NextVA, + Flags)); } } -/// LowerCALL - Lowering a ISD::CALL node into a callseq_start <- +/// LowerCall - Lowering a call into a callseq_start <- /// ARMISD:CALL <- callseq_end chain. Also add input and output parameter /// nodes. -SDValue ARMTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { - CallSDNode *TheCall = cast<CallSDNode>(Op.getNode()); - MVT RetVT = TheCall->getRetValType(0); - SDValue Chain = TheCall->getChain(); - unsigned CC = TheCall->getCallingConv(); - bool isVarArg = TheCall->isVarArg(); - SDValue Callee = TheCall->getCallee(); - DebugLoc dl = TheCall->getDebugLoc(); +SDValue +ARMTargetLowering::LowerCall(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, + bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { // Analyze operands of the call, assigning locations to each operand. SmallVector<CCValAssign, 16> ArgLocs; - CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs, *DAG.getContext()); - CCInfo.AnalyzeCallOperands(TheCall, CCAssignFnForNode(CC, /* Return*/ false)); + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), ArgLocs, + *DAG.getContext()); + CCInfo.AnalyzeCallOperands(Outs, + CCAssignFnForNode(CallConv, /* Return*/ false)); // Get a count of how many bytes are to be pushed on the stack. unsigned NumBytes = CCInfo.getNextStackOffset(); @@ -865,8 +852,8 @@ SDValue ARMTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { i != e; ++i, ++realArgIdx) { CCValAssign &VA = ArgLocs[i]; - SDValue Arg = TheCall->getArg(realArgIdx); - ISD::ArgFlagsTy Flags = TheCall->getArgFlags(realArgIdx); + SDValue Arg = Outs[realArgIdx].Val; + ISD::ArgFlagsTy Flags = Outs[realArgIdx].Flags; // Promote the value if needed. switch (VA.getLocInfo()) { @@ -894,23 +881,23 @@ SDValue ARMTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { SDValue Op1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Arg, DAG.getConstant(1, MVT::i32)); - PassF64ArgInRegs(TheCall, DAG, Chain, Op0, RegsToPass, + PassF64ArgInRegs(dl, DAG, Chain, Op0, RegsToPass, VA, ArgLocs[++i], StackPtr, MemOpChains, Flags); VA = ArgLocs[++i]; // skip ahead to next loc if (VA.isRegLoc()) { - PassF64ArgInRegs(TheCall, DAG, Chain, Op1, RegsToPass, + PassF64ArgInRegs(dl, DAG, Chain, Op1, RegsToPass, VA, ArgLocs[++i], StackPtr, MemOpChains, Flags); } else { assert(VA.isMemLoc()); if (StackPtr.getNode() == 0) StackPtr = DAG.getCopyFromReg(Chain, dl, ARM::SP, getPointerTy()); - MemOpChains.push_back(LowerMemOpCallTo(TheCall, DAG, StackPtr, VA, - Chain, Op1, Flags)); + MemOpChains.push_back(LowerMemOpCallTo(Chain, StackPtr, Op1, + dl, DAG, VA, Flags)); } } else { - PassF64ArgInRegs(TheCall, DAG, Chain, Arg, RegsToPass, VA, ArgLocs[++i], + PassF64ArgInRegs(dl, DAG, Chain, Arg, RegsToPass, VA, ArgLocs[++i], StackPtr, MemOpChains, Flags); } } else if (VA.isRegLoc()) { @@ -920,8 +907,8 @@ SDValue ARMTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { if (StackPtr.getNode() == 0) StackPtr = DAG.getCopyFromReg(Chain, dl, ARM::SP, getPointerTy()); - MemOpChains.push_back(LowerMemOpCallTo(TheCall, DAG, StackPtr, VA, - Chain, Arg, Flags)); + MemOpChains.push_back(LowerMemOpCallTo(Chain, StackPtr, Arg, + dl, DAG, VA, Flags)); } } @@ -1024,30 +1011,30 @@ SDValue ARMTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumBytes, true), DAG.getIntPtrConstant(0, true), InFlag); - if (RetVT != MVT::Other) + if (!Ins.empty()) InFlag = Chain.getValue(1); // Handle result values, copying them out of physregs into vregs that we // return. - return SDValue(LowerCallResult(Chain, InFlag, TheCall, CC, DAG), - Op.getResNo()); + return LowerCallResult(Chain, InFlag, CallConv, isVarArg, Ins, + dl, DAG, InVals); } -SDValue ARMTargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) { - // The chain is always operand #0 - SDValue Chain = Op.getOperand(0); - DebugLoc dl = Op.getDebugLoc(); +SDValue +ARMTargetLowering::LowerReturn(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG) { // CCValAssign - represent the assignment of the return value to a location. SmallVector<CCValAssign, 16> RVLocs; - unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv(); - bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg(); // CCState - Info about the registers and stack slots. - CCState CCInfo(CC, isVarArg, getTargetMachine(), RVLocs, *DAG.getContext()); + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), RVLocs, + *DAG.getContext()); - // Analyze return values of ISD::RET. - CCInfo.AnalyzeReturn(Op.getNode(), CCAssignFnForNode(CC, /* Return */ true)); + // Analyze outgoing return values. + CCInfo.AnalyzeReturn(Outs, CCAssignFnForNode(CallConv, /* Return */ true)); // If this is the first return lowered for this function, add // the regs to the liveout set for the function. @@ -1066,9 +1053,7 @@ SDValue ARMTargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) { CCValAssign &VA = RVLocs[i]; assert(VA.isRegLoc() && "Can only return in registers!"); - // ISD::RET => ret chain, (regnum1,val1), ... - // So i*2+1 index only the regnums - SDValue Arg = Op.getOperand(realRVLocIdx*2+1); + SDValue Arg = Outs[realRVLocIdx].Val; switch (VA.getLocInfo()) { default: llvm_unreachable("Unknown loc info!"); @@ -1172,7 +1157,7 @@ ARMTargetLowering::LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA, // FIXME: is there useful debug info available here? std::pair<SDValue, SDValue> CallResult = LowerCallTo(Chain, (const Type *) Type::Int32Ty, false, false, false, false, - 0, CallingConv::C, false, + 0, CallingConv::C, false, /*isReturnValueUsed=*/true, DAG.getExternalSymbol("__tls_get_addr", PtrVT), Args, DAG, dl); return CallResult.first; } @@ -1420,21 +1405,24 @@ ARMTargetLowering::GetF64FormalArgument(CCValAssign &VA, CCValAssign &NextVA, } SDValue -ARMTargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) { +ARMTargetLowering::LowerFormalArguments(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> + &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); - SDValue Root = Op.getOperand(0); - DebugLoc dl = Op.getDebugLoc(); - bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0; - unsigned CC = MF.getFunction()->getCallingConv(); ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); // Assign locations to all of the incoming arguments. SmallVector<CCValAssign, 16> ArgLocs; - CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs, *DAG.getContext()); - CCInfo.AnalyzeFormalArguments(Op.getNode(), - CCAssignFnForNode(CC, /* Return*/ false)); + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), ArgLocs, + *DAG.getContext()); + CCInfo.AnalyzeFormalArguments(Ins, + CCAssignFnForNode(CallConv, /* Return*/ false)); SmallVector<SDValue, 16> ArgValues; @@ -1453,17 +1441,17 @@ ARMTargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) { if (VA.getLocVT() == MVT::v2f64) { SDValue ArgValue1 = GetF64FormalArgument(VA, ArgLocs[++i], - Root, DAG, dl); + Chain, DAG, dl); VA = ArgLocs[++i]; // skip ahead to next loc SDValue ArgValue2 = GetF64FormalArgument(VA, ArgLocs[++i], - Root, DAG, dl); + Chain, DAG, dl); ArgValue = DAG.getNode(ISD::UNDEF, dl, MVT::v2f64); ArgValue = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, ArgValue, ArgValue1, DAG.getIntPtrConstant(0)); ArgValue = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, ArgValue, ArgValue2, DAG.getIntPtrConstant(1)); } else - ArgValue = GetF64FormalArgument(VA, ArgLocs[++i], Root, DAG, dl); + ArgValue = GetF64FormalArgument(VA, ArgLocs[++i], Chain, DAG, dl); } else { TargetRegisterClass *RC; @@ -1478,11 +1466,11 @@ ARMTargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) { assert((RegVT == MVT::i32 || RegVT == MVT::f32 || (FloatABIType == FloatABI::Hard && RegVT == MVT::f64)) && - "RegVT not supported by FORMAL_ARGUMENTS Lowering"); + "RegVT not supported by formal arguments Lowering"); // Transform the arguments in physical registers into virtual ones. unsigned Reg = MF.addLiveIn(VA.getLocReg(), RC); - ArgValue = DAG.getCopyFromReg(Root, dl, Reg, RegVT); + ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, RegVT); } // If this is an 8 or 16-bit value, it is really passed promoted @@ -1506,7 +1494,7 @@ ARMTargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) { break; } - ArgValues.push_back(ArgValue); + InVals.push_back(ArgValue); } else { // VA.isRegLoc() @@ -1519,7 +1507,7 @@ ARMTargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) { // Create load nodes to retrieve arguments from the stack. SDValue FIN = DAG.getFrameIndex(FI, getPointerTy()); - ArgValues.push_back(DAG.getLoad(VA.getValVT(), dl, Root, FIN, NULL, 0)); + InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN, NULL, 0)); } } @@ -1555,25 +1543,21 @@ ARMTargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) { RC = ARM::GPRRegisterClass; unsigned VReg = MF.addLiveIn(GPRArgRegs[NumGPRs], RC); - SDValue Val = DAG.getCopyFromReg(Root, dl, VReg, MVT::i32); + SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32); SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0); MemOps.push_back(Store); FIN = DAG.getNode(ISD::ADD, dl, getPointerTy(), FIN, DAG.getConstant(4, getPointerTy())); } if (!MemOps.empty()) - Root = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, - &MemOps[0], MemOps.size()); + Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, + &MemOps[0], MemOps.size()); } else // This will point to the next argument passed via stack. VarArgsFrameIndex = MFI->CreateFixedObject(4, ArgOffset); } - ArgValues.push_back(Root); - - // Return the new list of results. - return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getNode()->getVTList(), - &ArgValues[0], ArgValues.size()).getValue(Op.getResNo()); + return Chain; } /// isFloatingPointZero - Return true if this is +0.0. @@ -2380,8 +2364,6 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { return Subtarget->isTargetDarwin() ? LowerGlobalAddressDarwin(Op, DAG) : LowerGlobalAddressELF(Op, DAG); case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG); - case ISD::CALL: return LowerCALL(Op, DAG); - case ISD::RET: return LowerRET(Op, DAG); case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG, Subtarget); case ISD::BR_CC: return LowerBR_CC(Op, DAG, Subtarget); case ISD::BR_JT: return LowerBR_JT(Op, DAG); @@ -2391,7 +2373,6 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { case ISD::FP_TO_SINT: case ISD::FP_TO_UINT: return LowerFP_TO_INT(Op, DAG); case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG); - case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG); case ISD::RETURNADDR: break; case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); case ISD::GLOBAL_OFFSET_TABLE: return LowerGLOBAL_OFFSET_TABLE(Op, DAG); diff --git a/lib/Target/ARM/ARMISelLowering.h b/lib/Target/ARM/ARMISelLowering.h index f32db3f..4e05d45 100644 --- a/lib/Target/ARM/ARMISelLowering.h +++ b/lib/Target/ARM/ARMISelLowering.h @@ -225,7 +225,7 @@ namespace llvm { void addQRTypeForNEON(MVT VT); typedef SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPassVector; - void PassF64ArgInRegs(CallSDNode *TheCall, SelectionDAG &DAG, + void PassF64ArgInRegs(DebugLoc dl, SelectionDAG &DAG, SDValue Chain, SDValue &Arg, RegsToPassVector &RegsToPass, CCValAssign &VA, CCValAssign &NextVA, @@ -236,15 +236,12 @@ namespace llvm { SDValue &Root, SelectionDAG &DAG, DebugLoc dl); CCAssignFn *CCAssignFnForNode(unsigned CC, bool Return) const; - SDValue LowerMemOpCallTo(CallSDNode *TheCall, SelectionDAG &DAG, - const SDValue &StackPtr, const CCValAssign &VA, - SDValue Chain, SDValue Arg, ISD::ArgFlagsTy Flags); - SDNode *LowerCallResult(SDValue Chain, SDValue InFlag, CallSDNode *TheCall, - unsigned CallingConv, SelectionDAG &DAG); - SDValue LowerCALL(SDValue Op, SelectionDAG &DAG); + SDValue LowerMemOpCallTo(SDValue Chain, SDValue StackPtr, SDValue Arg, + DebugLoc dl, SelectionDAG &DAG, + const CCValAssign &VA, + ISD::ArgFlagsTy Flags); SDValue LowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG); SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG); - SDValue LowerRET(SDValue Op, SelectionDAG &DAG); SDValue LowerGlobalAddressDarwin(SDValue Op, SelectionDAG &DAG); SDValue LowerGlobalAddressELF(SDValue Op, SelectionDAG &DAG); SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG); @@ -253,7 +250,6 @@ namespace llvm { SDValue LowerToTLSExecModels(GlobalAddressSDNode *GA, SelectionDAG &DAG); SDValue LowerGLOBAL_OFFSET_TABLE(SDValue Op, SelectionDAG &DAG); - SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG); SDValue LowerBR_JT(SDValue Op, SelectionDAG &DAG); SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG); @@ -264,6 +260,33 @@ namespace llvm { bool AlwaysInline, const Value *DstSV, uint64_t DstSVOff, const Value *SrcSV, uint64_t SrcSVOff); + SDValue LowerCallResult(SDValue Chain, SDValue InFlag, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + virtual SDValue + LowerFormalArguments(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + virtual SDValue + LowerCall(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, + bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + virtual SDValue + LowerReturn(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG); }; } diff --git a/lib/Target/Alpha/AlphaISelLowering.cpp b/lib/Target/Alpha/AlphaISelLowering.cpp index a17209e..a5eeca7 100644 --- a/lib/Target/Alpha/AlphaISelLowering.cpp +++ b/lib/Target/Alpha/AlphaISelLowering.cpp @@ -166,8 +166,6 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) setOperationAction(ISD::VAARG, MVT::Other, Custom); setOperationAction(ISD::VAARG, MVT::i32, Custom); - setOperationAction(ISD::RET, MVT::Other, Custom); - setOperationAction(ISD::JumpTable, MVT::i64, Custom); setOperationAction(ISD::JumpTable, MVT::i32, Custom); @@ -246,20 +244,21 @@ static SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) { #include "AlphaGenCallingConv.inc" -SDValue AlphaTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { - CallSDNode *TheCall = cast<CallSDNode>(Op.getNode()); - SDValue Chain = TheCall->getChain(); - SDValue Callee = TheCall->getCallee(); - bool isVarArg = TheCall->isVarArg(); - DebugLoc dl = Op.getDebugLoc(); - MachineFunction &MF = DAG.getMachineFunction(); - unsigned CC = MF.getFunction()->getCallingConv(); +SDValue +AlphaTargetLowering::LowerCall(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, + bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { // Analyze operands of the call, assigning locations to each operand. SmallVector<CCValAssign, 16> ArgLocs; - CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs, *DAG.getContext()); + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), + ArgLocs, *DAG.getContext()); - CCInfo.AnalyzeCallOperands(TheCall, CC_Alpha); + CCInfo.AnalyzeCallOperands(Outs, CC_Alpha); // Get a count of how many bytes are to be pushed on the stack. unsigned NumBytes = CCInfo.getNextStackOffset(); @@ -275,8 +274,7 @@ SDValue AlphaTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { CCValAssign &VA = ArgLocs[i]; - // Arguments start after the 5 first operands of ISD::CALL - SDValue Arg = TheCall->getArg(i); + SDValue Arg = Outs[i].Val; // Promote the value if needed. switch (VA.getLocInfo()) { @@ -355,30 +353,26 @@ SDValue AlphaTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { // Handle result values, copying them out of physregs into vregs that we // return. - return SDValue(LowerCallResult(Chain, InFlag, TheCall, CC, DAG), - Op.getResNo()); + return LowerCallResult(Chain, InFlag, CallConv, isVarArg, + Ins, dl, DAG, InVals); } -/// LowerCallResult - Lower the result values of an ISD::CALL into the -/// appropriate copies out of appropriate physical registers. This assumes that -/// Chain/InFlag are the input chain/flag to use, and that TheCall is the call -/// being lowered. Returns a SDNode with the same number of values as the -/// ISD::CALL. -SDNode* +/// LowerCallResult - Lower the result values of a call into the +/// appropriate copies out of appropriate physical registers. +/// +SDValue AlphaTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, - CallSDNode *TheCall, - unsigned CallingConv, - SelectionDAG &DAG) { - bool isVarArg = TheCall->isVarArg(); - DebugLoc dl = TheCall->getDebugLoc(); + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { // Assign locations to each value returned by this call. SmallVector<CCValAssign, 16> RVLocs; - CCState CCInfo(CallingConv, isVarArg, getTargetMachine(), RVLocs, + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), RVLocs, *DAG.getContext()); - CCInfo.AnalyzeCallResult(TheCall, RetCC_Alpha); - SmallVector<SDValue, 8> ResultVals; + CCInfo.AnalyzeCallResult(Ins, RetCC_Alpha); // Copy all of the result registers out of their specified physreg. for (unsigned i = 0; i != RVLocs.size(); ++i) { @@ -402,33 +396,31 @@ AlphaTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, if (VA.getLocInfo() != CCValAssign::Full) RetValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), RetValue); - ResultVals.push_back(RetValue); + InVals.push_back(RetValue); } - ResultVals.push_back(Chain); - - // Merge everything together with a MERGE_VALUES node. - return DAG.getNode(ISD::MERGE_VALUES, dl, TheCall->getVTList(), - &ResultVals[0], ResultVals.size()).getNode(); + return Chain; } -static SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG, - int &VarArgsBase, - int &VarArgsOffset) { +SDValue +AlphaTargetLowering::LowerFormalArguments(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> + &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); - std::vector<SDValue> ArgValues; - SDValue Root = Op.getOperand(0); - DebugLoc dl = Op.getDebugLoc(); unsigned args_int[] = { Alpha::R16, Alpha::R17, Alpha::R18, Alpha::R19, Alpha::R20, Alpha::R21}; unsigned args_float[] = { Alpha::F16, Alpha::F17, Alpha::F18, Alpha::F19, Alpha::F20, Alpha::F21}; - for (unsigned ArgNo = 0, e = Op.getNode()->getNumValues()-1; ArgNo != e; ++ArgNo) { + for (unsigned ArgNo = 0, e = Ins.size(); ArgNo != e; ++ArgNo) { SDValue argt; - MVT ObjectVT = Op.getValue(ArgNo).getValueType(); + MVT ObjectVT = Ins[ArgNo].VT; SDValue ArgVal; if (ArgNo < 6) { @@ -438,17 +430,17 @@ static SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG, case MVT::f64: args_float[ArgNo] = AddLiveIn(MF, args_float[ArgNo], &Alpha::F8RCRegClass); - ArgVal = DAG.getCopyFromReg(Root, dl, args_float[ArgNo], ObjectVT); + ArgVal = DAG.getCopyFromReg(Chain, dl, args_float[ArgNo], ObjectVT); break; case MVT::f32: args_float[ArgNo] = AddLiveIn(MF, args_float[ArgNo], &Alpha::F4RCRegClass); - ArgVal = DAG.getCopyFromReg(Root, dl, args_float[ArgNo], ObjectVT); + ArgVal = DAG.getCopyFromReg(Chain, dl, args_float[ArgNo], ObjectVT); break; case MVT::i64: args_int[ArgNo] = AddLiveIn(MF, args_int[ArgNo], &Alpha::GPRCRegClass); - ArgVal = DAG.getCopyFromReg(Root, dl, args_int[ArgNo], MVT::i64); + ArgVal = DAG.getCopyFromReg(Chain, dl, args_int[ArgNo], MVT::i64); break; } } else { //more args @@ -458,59 +450,58 @@ static SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG, // Create the SelectionDAG nodes corresponding to a load //from this parameter SDValue FIN = DAG.getFrameIndex(FI, MVT::i64); - ArgVal = DAG.getLoad(ObjectVT, dl, Root, FIN, NULL, 0); + ArgVal = DAG.getLoad(ObjectVT, dl, Chain, FIN, NULL, 0); } - ArgValues.push_back(ArgVal); + InVals.push_back(ArgVal); } // If the functions takes variable number of arguments, copy all regs to stack - bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0; if (isVarArg) { - VarArgsOffset = (Op.getNode()->getNumValues()-1) * 8; + VarArgsOffset = Ins.size() * 8; std::vector<SDValue> LS; for (int i = 0; i < 6; ++i) { if (TargetRegisterInfo::isPhysicalRegister(args_int[i])) args_int[i] = AddLiveIn(MF, args_int[i], &Alpha::GPRCRegClass); - SDValue argt = DAG.getCopyFromReg(Root, dl, args_int[i], MVT::i64); + SDValue argt = DAG.getCopyFromReg(Chain, dl, args_int[i], MVT::i64); int FI = MFI->CreateFixedObject(8, -8 * (6 - i)); if (i == 0) VarArgsBase = FI; SDValue SDFI = DAG.getFrameIndex(FI, MVT::i64); - LS.push_back(DAG.getStore(Root, dl, argt, SDFI, NULL, 0)); + LS.push_back(DAG.getStore(Chain, dl, argt, SDFI, NULL, 0)); if (TargetRegisterInfo::isPhysicalRegister(args_float[i])) args_float[i] = AddLiveIn(MF, args_float[i], &Alpha::F8RCRegClass); - argt = DAG.getCopyFromReg(Root, dl, args_float[i], MVT::f64); + argt = DAG.getCopyFromReg(Chain, dl, args_float[i], MVT::f64); FI = MFI->CreateFixedObject(8, - 8 * (12 - i)); SDFI = DAG.getFrameIndex(FI, MVT::i64); - LS.push_back(DAG.getStore(Root, dl, argt, SDFI, NULL, 0)); + LS.push_back(DAG.getStore(Chain, dl, argt, SDFI, NULL, 0)); } //Set up a token factor with all the stack traffic - Root = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &LS[0], LS.size()); + Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &LS[0], LS.size()); } - ArgValues.push_back(Root); - - // Return the new list of results. - return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getNode()->getVTList(), - &ArgValues[0], ArgValues.size()); + return Chain; } -static SDValue LowerRET(SDValue Op, SelectionDAG &DAG) { - DebugLoc dl = Op.getDebugLoc(); - SDValue Copy = DAG.getCopyToReg(Op.getOperand(0), dl, Alpha::R26, - DAG.getNode(AlphaISD::GlobalRetAddr, - DebugLoc::getUnknownLoc(), - MVT::i64), - SDValue()); - switch (Op.getNumOperands()) { +SDValue +AlphaTargetLowering::LowerReturn(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG) { + + SDValue Copy = DAG.getCopyToReg(Chain, dl, Alpha::R26, + DAG.getNode(AlphaISD::GlobalRetAddr, + DebugLoc::getUnknownLoc(), + MVT::i64), + SDValue()); + switch (Outs.size()) { default: llvm_unreachable("Do not know how to return this many arguments!"); - case 1: + case 0: break; //return SDValue(); // ret void is legal - case 3: { - MVT ArgVT = Op.getOperand(1).getValueType(); + case 1: { + MVT ArgVT = Outs[0].Val.getValueType(); unsigned ArgReg; if (ArgVT.isInteger()) ArgReg = Alpha::R0; @@ -519,13 +510,13 @@ static SDValue LowerRET(SDValue Op, SelectionDAG &DAG) { ArgReg = Alpha::F0; } Copy = DAG.getCopyToReg(Copy, dl, ArgReg, - Op.getOperand(1), Copy.getValue(1)); + Outs[0].Val, Copy.getValue(1)); if (DAG.getMachineFunction().getRegInfo().liveout_empty()) DAG.getMachineFunction().getRegInfo().addLiveOut(ArgReg); break; } - case 5: { - MVT ArgVT = Op.getOperand(1).getValueType(); + case 2: { + MVT ArgVT = Outs[0].Val.getValueType(); unsigned ArgReg1, ArgReg2; if (ArgVT.isInteger()) { ArgReg1 = Alpha::R0; @@ -536,13 +527,13 @@ static SDValue LowerRET(SDValue Op, SelectionDAG &DAG) { ArgReg2 = Alpha::F1; } Copy = DAG.getCopyToReg(Copy, dl, ArgReg1, - Op.getOperand(1), Copy.getValue(1)); + Outs[0].Val, Copy.getValue(1)); if (std::find(DAG.getMachineFunction().getRegInfo().liveout_begin(), DAG.getMachineFunction().getRegInfo().liveout_end(), ArgReg1) == DAG.getMachineFunction().getRegInfo().liveout_end()) DAG.getMachineFunction().getRegInfo().addLiveOut(ArgReg1); Copy = DAG.getCopyToReg(Copy, dl, ArgReg2, - Op.getOperand(3), Copy.getValue(1)); + Outs[1].Val, Copy.getValue(1)); if (std::find(DAG.getMachineFunction().getRegInfo().liveout_begin(), DAG.getMachineFunction().getRegInfo().liveout_end(), ArgReg2) == DAG.getMachineFunction().getRegInfo().liveout_end()) @@ -589,11 +580,6 @@ SDValue AlphaTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { DebugLoc dl = Op.getDebugLoc(); switch (Op.getOpcode()) { default: llvm_unreachable("Wasn't expecting to be able to lower this!"); - case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG, - VarArgsBase, - VarArgsOffset); - case ISD::CALL: return LowerCALL(Op, DAG); - case ISD::RET: return LowerRET(Op,DAG); case ISD::JumpTable: return LowerJumpTable(Op, DAG); case ISD::INTRINSIC_WO_CHAIN: { diff --git a/lib/Target/Alpha/AlphaISelLowering.h b/lib/Target/Alpha/AlphaISelLowering.h index 098c33f..889a2c6 100644 --- a/lib/Target/Alpha/AlphaISelLowering.h +++ b/lib/Target/Alpha/AlphaISelLowering.h @@ -82,9 +82,11 @@ namespace llvm { // Friendly names for dumps const char *getTargetNodeName(unsigned Opcode) const; - SDValue LowerCALL(SDValue Op, SelectionDAG &DAG); - SDNode *LowerCallResult(SDValue Chain, SDValue InFlag, CallSDNode *TheCall, - unsigned CallingConv, SelectionDAG &DAG); + SDValue LowerCallResult(SDValue Chain, SDValue InFlag, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); ConstraintType getConstraintType(const std::string &Constraint) const; @@ -107,6 +109,26 @@ namespace llvm { void LowerVAARG(SDNode *N, SDValue &Chain, SDValue &DataPtr, SelectionDAG &DAG); + virtual SDValue + LowerFormalArguments(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + virtual SDValue + LowerCall(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + virtual SDValue + LowerReturn(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG); }; } diff --git a/lib/Target/Blackfin/BlackfinISelLowering.cpp b/lib/Target/Blackfin/BlackfinISelLowering.cpp index cb68a59..ebfd61c 100644 --- a/lib/Target/Blackfin/BlackfinISelLowering.cpp +++ b/lib/Target/Blackfin/BlackfinISelLowering.cpp @@ -123,9 +123,6 @@ BlackfinTargetLowering::BlackfinTargetLowering(TargetMachine &TM) setOperationAction(ISD::VAEND, MVT::Other, Expand); setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); - - // RET must be custom lowered, to meet ABI requirements - setOperationAction(ISD::RET, MVT::Other, Custom); } const char *BlackfinTargetLowering::getTargetNodeName(unsigned Opcode) const { @@ -160,27 +157,23 @@ SDValue BlackfinTargetLowering::LowerJumpTable(SDValue Op, SelectionDAG &DAG) { return DAG.getNode(BFISD::Wrapper, DL, MVT::i32, Op); } -// FORMAL_ARGUMENTS(CHAIN, CC#, ISVARARG, FLAG0, ..., FLAGn) - This node -// represents the formal arguments for a function. CC# is a Constant value -// indicating the calling convention of the function, and ISVARARG is a -// flag that indicates whether the function is varargs or not. This node -// has one result value for each incoming argument, plus one for the output -// chain. -SDValue BlackfinTargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, - SelectionDAG &DAG) { - DebugLoc dl = Op.getDebugLoc(); - SDValue Root = Op.getOperand(0); - unsigned CC = Op.getConstantOperandVal(1); - bool isVarArg = Op.getConstantOperandVal(2); +SDValue +BlackfinTargetLowering::LowerFormalArguments(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> + &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); SmallVector<CCValAssign, 16> ArgLocs; - CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs, *DAG.getContext()); + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), + ArgLocs, *DAG.getContext()); CCInfo.AllocateStack(12, 4); // ABI requires 12 bytes stack space - CCInfo.AnalyzeFormalArguments(Op.getNode(), CC_Blackfin); + CCInfo.AnalyzeFormalArguments(Ins, CC_Blackfin); - SmallVector<SDValue, 8> ArgValues; for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { CCValAssign &VA = ArgLocs[i]; @@ -193,7 +186,7 @@ SDValue BlackfinTargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, unsigned Reg = MF.getRegInfo().createVirtualRegister(RC); MF.getRegInfo().addLiveIn(VA.getLocReg(), Reg); - SDValue ArgValue = DAG.getCopyFromReg(Root, dl, Reg, RegVT); + SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, RegVT); // If this is an 8 or 16-bit value, it is really passed promoted to 32 // bits. Insert an assert[sz]ext to capture this, then truncate to the @@ -208,35 +201,34 @@ SDValue BlackfinTargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, if (VA.getLocInfo() != CCValAssign::Full) ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue); - ArgValues.push_back(ArgValue); + InVals.push_back(ArgValue); } else { assert(VA.isMemLoc() && "CCValAssign must be RegLoc or MemLoc"); unsigned ObjSize = VA.getLocVT().getStoreSizeInBits()/8; int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset()); SDValue FIN = DAG.getFrameIndex(FI, MVT::i32); - ArgValues.push_back(DAG.getLoad(VA.getValVT(), dl, Root, FIN, NULL, 0)); + InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN, NULL, 0)); } } - ArgValues.push_back(Root); - - // Return the new list of results. - return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getNode()->getVTList(), - &ArgValues[0], ArgValues.size()).getValue(Op.getResNo()); + return Chain; } -SDValue BlackfinTargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) { +SDValue +BlackfinTargetLowering::LowerReturn(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG) { + // CCValAssign - represent the assignment of the return value to locations. SmallVector<CCValAssign, 16> RVLocs; - unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv(); - bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg(); - DebugLoc dl = Op.getDebugLoc(); // CCState - Info about the registers and stack slot. - CCState CCInfo(CC, isVarArg, DAG.getTarget(), RVLocs, *DAG.getContext()); + CCState CCInfo(CallConv, isVarArg, DAG.getTarget(), + RVLocs, *DAG.getContext()); - // Analize return values of ISD::RET - CCInfo.AnalyzeReturn(Op.getNode(), RetCC_Blackfin); + // Analize return values. + CCInfo.AnalyzeReturn(Outs, RetCC_Blackfin); // If this is the first return lowered for this function, add the regs to the // liveout set for the function. @@ -245,14 +237,13 @@ SDValue BlackfinTargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) { DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); } - SDValue Chain = Op.getOperand(0); SDValue Flag; // Copy the result values into the output registers. for (unsigned i = 0; i != RVLocs.size(); ++i) { CCValAssign &VA = RVLocs[i]; assert(VA.isRegLoc() && "Can only return in registers!"); - SDValue Opi = Op.getOperand(i*2+1); + SDValue Opi = Outs[i].Val; // Expand to i32 if necessary switch (VA.getLocInfo()) { @@ -268,8 +259,6 @@ SDValue BlackfinTargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) { Opi = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Opi); break; } - // ISD::RET => ret chain, (regnum1,val1), ... - // So i*2+1 index only the regnums. Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), Opi, SDValue()); // Guarantee that all emitted copies are stuck together with flags. Flag = Chain.getValue(1); @@ -282,20 +271,21 @@ SDValue BlackfinTargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) { } } -SDValue BlackfinTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { - CallSDNode *TheCall = cast<CallSDNode>(Op.getNode()); - unsigned CallingConv = TheCall->getCallingConv(); - SDValue Chain = TheCall->getChain(); - SDValue Callee = TheCall->getCallee(); - bool isVarArg = TheCall->isVarArg(); - DebugLoc dl = TheCall->getDebugLoc(); +SDValue +BlackfinTargetLowering::LowerCall(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, + bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { // Analyze operands of the call, assigning locations to each operand. SmallVector<CCValAssign, 16> ArgLocs; - CCState CCInfo(CallingConv, isVarArg, DAG.getTarget(), ArgLocs, + CCState CCInfo(CallConv, isVarArg, DAG.getTarget(), ArgLocs, *DAG.getContext()); CCInfo.AllocateStack(12, 4); // ABI requires 12 bytes stack space - CCInfo.AnalyzeCallOperands(TheCall, CC_Blackfin); + CCInfo.AnalyzeCallOperands(Outs, CC_Blackfin); // Get the size of the outgoing arguments stack space requirement. unsigned ArgsSize = CCInfo.getNextStackOffset(); @@ -307,9 +297,7 @@ SDValue BlackfinTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { // Walk the register/memloc assignments, inserting copies/loads. for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { CCValAssign &VA = ArgLocs[i]; - - // Arguments start after the 5 first operands of ISD::CALL - SDValue Arg = TheCall->getArg(i); + SDValue Arg = Outs[i].Val; // Promote the value if needed. switch (VA.getLocInfo()) { @@ -383,11 +371,10 @@ SDValue BlackfinTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { // Assign locations to each value returned by this call. SmallVector<CCValAssign, 16> RVLocs; - CCState RVInfo(CallingConv, isVarArg, DAG.getTarget(), RVLocs, + CCState RVInfo(CallConv, isVarArg, DAG.getTarget(), RVLocs, *DAG.getContext()); - RVInfo.AnalyzeCallResult(TheCall, RetCC_Blackfin); - SmallVector<SDValue, 8> ResultVals; + RVInfo.AnalyzeCallResult(Ins, RetCC_Blackfin); // Copy all of the result registers out of their specified physreg. for (unsigned i = 0; i != RVLocs.size(); ++i) { @@ -417,16 +404,10 @@ SDValue BlackfinTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { // Truncate to valtype if (RV.getLocInfo() != CCValAssign::Full) Val = DAG.getNode(ISD::TRUNCATE, dl, RV.getValVT(), Val); - ResultVals.push_back(Val); + InVals.push_back(Val); } - ResultVals.push_back(Chain); - - // Merge everything together with a MERGE_VALUES node. - SDValue merge = DAG.getNode(ISD::MERGE_VALUES, dl, - TheCall->getVTList(), &ResultVals[0], - ResultVals.size()); - return merge; + return Chain; } // Expansion of ADDE / SUBE. This is a bit involved since blackfin doesn't have @@ -477,9 +458,6 @@ SDValue BlackfinTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { // Frame & Return address. Currently unimplemented case ISD::FRAMEADDR: return SDValue(); case ISD::RETURNADDR: return SDValue(); - case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG); - case ISD::CALL: return LowerCALL(Op, DAG); - case ISD::RET: return LowerRET(Op, DAG); case ISD::ADDE: case ISD::SUBE: return LowerADDE(Op, DAG); } diff --git a/lib/Target/Blackfin/BlackfinISelLowering.h b/lib/Target/Blackfin/BlackfinISelLowering.h index 7acbd1a..c1ad11f 100644 --- a/lib/Target/Blackfin/BlackfinISelLowering.h +++ b/lib/Target/Blackfin/BlackfinISelLowering.h @@ -51,10 +51,27 @@ namespace llvm { private: SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG); SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG); - SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG); - SDValue LowerRET(SDValue Op, SelectionDAG &DAG); - SDValue LowerCALL(SDValue Op, SelectionDAG &DAG); SDValue LowerADDE(SDValue Op, SelectionDAG &DAG); + + virtual SDValue + LowerFormalArguments(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + virtual SDValue + LowerCall(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + virtual SDValue + LowerReturn(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG); }; } // end namespace llvm diff --git a/lib/Target/CellSPU/SPUISelLowering.cpp b/lib/Target/CellSPU/SPUISelLowering.cpp index ce7ba72..d9299b4 100644 --- a/lib/Target/CellSPU/SPUISelLowering.cpp +++ b/lib/Target/CellSPU/SPUISelLowering.cpp @@ -115,7 +115,9 @@ namespace { const Type *RetTy = Op.getNode()->getValueType(0).getTypeForMVT(); std::pair<SDValue, SDValue> CallInfo = TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false, - 0, CallingConv::C, false, Callee, Args, DAG, + 0, CallingConv::C, false, + /*isReturnValueUsed=*/true, + Callee, Args, DAG, Op.getDebugLoc()); return CallInfo.first; @@ -396,9 +398,6 @@ SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM) setOperationAction(ISD::JumpTable, VT, Custom); } - // RET must be custom lowered, to meet ABI requirements - setOperationAction(ISD::RET, MVT::Other, Custom); - // VASTART needs to be custom lowered to use the VarArgsFrameIndex setOperationAction(ISD::VASTART , MVT::Other, Custom); @@ -1008,16 +1007,17 @@ LowerConstantFP(SDValue Op, SelectionDAG &DAG) { return SDValue(); } -static SDValue -LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG, int &VarArgsFrameIndex) -{ +SDValue +SPUTargetLowering::LowerFormalArguments(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> + &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); MachineRegisterInfo &RegInfo = MF.getRegInfo(); - SmallVector<SDValue, 48> ArgValues; - SDValue Root = Op.getOperand(0); - bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0; - DebugLoc dl = Op.getDebugLoc(); const unsigned *ArgRegs = SPURegisterInfo::getArgRegs(); const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs(); @@ -1029,9 +1029,8 @@ LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG, int &VarArgsFrameIndex) MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); // Add DAG nodes to load the arguments or copy them out of registers. - for (unsigned ArgNo = 0, e = Op.getNode()->getNumValues() - 1; - ArgNo != e; ++ArgNo) { - MVT ObjectVT = Op.getValue(ArgNo).getValueType(); + for (unsigned ArgNo = 0, e = Ins.size(); ArgNo != e; ++ArgNo) { + MVT ObjectVT = Ins[ArgNo].VT; unsigned ObjSize = ObjectVT.getSizeInBits()/8; SDValue ArgVal; @@ -1042,7 +1041,7 @@ LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG, int &VarArgsFrameIndex) default: { std::string msg; raw_string_ostream Msg(msg); - Msg << "LowerFORMAL_ARGUMENTS Unhandled argument type: " + Msg << "LowerFormalArguments Unhandled argument type: " << ObjectVT.getMVTString(); llvm_report_error(Msg.str()); } @@ -1079,7 +1078,7 @@ LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG, int &VarArgsFrameIndex) unsigned VReg = RegInfo.createVirtualRegister(ArgRegClass); RegInfo.addLiveIn(ArgRegs[ArgRegIdx], VReg); - ArgVal = DAG.getCopyFromReg(Root, dl, VReg, ObjectVT); + ArgVal = DAG.getCopyFromReg(Chain, dl, VReg, ObjectVT); ++ArgRegIdx; } else { // We need to load the argument to a virtual register if we determined @@ -1087,13 +1086,13 @@ LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG, int &VarArgsFrameIndex) // or we're forced to do vararg int FI = MFI->CreateFixedObject(ObjSize, ArgOffset); SDValue FIN = DAG.getFrameIndex(FI, PtrVT); - ArgVal = DAG.getLoad(ObjectVT, dl, Root, FIN, NULL, 0); + ArgVal = DAG.getLoad(ObjectVT, dl, Chain, FIN, NULL, 0); ArgOffset += StackSlotSize; } - ArgValues.push_back(ArgVal); + InVals.push_back(ArgVal); // Update the chain - Root = ArgVal.getOperand(0); + Chain = ArgVal.getOperand(0); } // vararg handling: @@ -1108,23 +1107,19 @@ LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG, int &VarArgsFrameIndex) VarArgsFrameIndex = MFI->CreateFixedObject(StackSlotSize, ArgOffset); SDValue FIN = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT); SDValue ArgVal = DAG.getRegister(ArgRegs[ArgRegIdx], MVT::v16i8); - SDValue Store = DAG.getStore(Root, dl, ArgVal, FIN, NULL, 0); - Root = Store.getOperand(0); + SDValue Store = DAG.getStore(Chain, dl, ArgVal, FIN, NULL, 0); + Chain = Store.getOperand(0); MemOps.push_back(Store); // Increment address by stack slot size for the next stored argument ArgOffset += StackSlotSize; } if (!MemOps.empty()) - Root = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, - &MemOps[0], MemOps.size()); + Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, + &MemOps[0], MemOps.size()); } - ArgValues.push_back(Root); - - // Return the new list of results. - return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getNode()->getVTList(), - &ArgValues[0], ArgValues.size()); + return Chain; } /// isLSAAddress - Return the immediate to use if the specified @@ -1141,16 +1136,20 @@ static SDNode *isLSAAddress(SDValue Op, SelectionDAG &DAG) { return DAG.getConstant((int)C->getZExtValue() >> 2, MVT::i32).getNode(); } -static SDValue -LowerCALL(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) { - CallSDNode *TheCall = cast<CallSDNode>(Op.getNode()); - SDValue Chain = TheCall->getChain(); - SDValue Callee = TheCall->getCallee(); - unsigned NumOps = TheCall->getNumArgs(); +SDValue +SPUTargetLowering::LowerCall(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, + bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + + const SPUSubtarget *ST = SPUTM.getSubtargetImpl(); + unsigned NumOps = Outs.size(); unsigned StackSlotSize = SPUFrameInfo::stackSlotSize(); const unsigned *ArgRegs = SPURegisterInfo::getArgRegs(); const unsigned NumArgRegs = SPURegisterInfo::getNumArgRegs(); - DebugLoc dl = TheCall->getDebugLoc(); // Handy pointer type MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); @@ -1176,7 +1175,7 @@ LowerCALL(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) { SmallVector<SDValue, 8> MemOpChains; for (unsigned i = 0; i != NumOps; ++i) { - SDValue Arg = TheCall->getArg(i); + SDValue Arg = Outs[i].Val; // PtrOff will be used to store the current argument to the stack if a // register cannot be found for it. @@ -1308,50 +1307,46 @@ LowerCALL(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) { Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumStackBytes, true), DAG.getIntPtrConstant(0, true), InFlag); - if (TheCall->getValueType(0) != MVT::Other) + if (!Ins.empty()) InFlag = Chain.getValue(1); - SDValue ResultVals[3]; - unsigned NumResults = 0; + // If the function returns void, just return the chain. + if (Ins.empty()) + return Chain; // If the call has results, copy the values out of the ret val registers. - switch (TheCall->getValueType(0).getSimpleVT()) { + switch (Ins[0].VT.getSimpleVT()) { default: llvm_unreachable("Unexpected ret value!"); case MVT::Other: break; case MVT::i32: - if (TheCall->getValueType(1) == MVT::i32) { + if (Ins.size() > 1 && Ins[1].VT == MVT::i32) { Chain = DAG.getCopyFromReg(Chain, dl, SPU::R4, MVT::i32, InFlag).getValue(1); - ResultVals[0] = Chain.getValue(0); + InVals.push_back(Chain.getValue(0)); Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, MVT::i32, Chain.getValue(2)).getValue(1); - ResultVals[1] = Chain.getValue(0); - NumResults = 2; + InVals.push_back(Chain.getValue(0)); } else { Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, MVT::i32, InFlag).getValue(1); - ResultVals[0] = Chain.getValue(0); - NumResults = 1; + InVals.push_back(Chain.getValue(0)); } break; case MVT::i64: Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, MVT::i64, InFlag).getValue(1); - ResultVals[0] = Chain.getValue(0); - NumResults = 1; + InVals.push_back(Chain.getValue(0)); break; case MVT::i128: Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, MVT::i128, InFlag).getValue(1); - ResultVals[0] = Chain.getValue(0); - NumResults = 1; + InVals.push_back(Chain.getValue(0)); break; case MVT::f32: case MVT::f64: - Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, TheCall->getValueType(0), + Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, Ins[0].VT, InFlag).getValue(1); - ResultVals[0] = Chain.getValue(0); - NumResults = 1; + InVals.push_back(Chain.getValue(0)); break; case MVT::v2f64: case MVT::v2i64: @@ -1359,31 +1354,25 @@ LowerCALL(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) { case MVT::v4i32: case MVT::v8i16: case MVT::v16i8: - Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, TheCall->getValueType(0), + Chain = DAG.getCopyFromReg(Chain, dl, SPU::R3, Ins[0].VT, InFlag).getValue(1); - ResultVals[0] = Chain.getValue(0); - NumResults = 1; + InVals.push_back(Chain.getValue(0)); break; } - // If the function returns void, just return the chain. - if (NumResults == 0) - return Chain; - - // Otherwise, merge everything together with a MERGE_VALUES node. - ResultVals[NumResults++] = Chain; - SDValue Res = DAG.getMergeValues(ResultVals, NumResults, dl); - return Res.getValue(Op.getResNo()); + return Chain; } -static SDValue -LowerRET(SDValue Op, SelectionDAG &DAG, TargetMachine &TM) { +SDValue +SPUTargetLowering::LowerReturn(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG) { + SmallVector<CCValAssign, 16> RVLocs; - unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv(); - bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg(); - DebugLoc dl = Op.getDebugLoc(); - CCState CCInfo(CC, isVarArg, TM, RVLocs, *DAG.getContext()); - CCInfo.AnalyzeReturn(Op.getNode(), RetCC_SPU); + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), + RVLocs, *DAG.getContext()); + CCInfo.AnalyzeReturn(Outs, RetCC_SPU); // If this is the first return lowered for this function, add the regs to the // liveout set for the function. @@ -1392,7 +1381,6 @@ LowerRET(SDValue Op, SelectionDAG &DAG, TargetMachine &TM) { DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); } - SDValue Chain = Op.getOperand(0); SDValue Flag; // Copy the result values into the output registers. @@ -1400,7 +1388,7 @@ LowerRET(SDValue Op, SelectionDAG &DAG, TargetMachine &TM) { CCValAssign &VA = RVLocs[i]; assert(VA.isRegLoc() && "Can only return in registers!"); Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), - Op.getOperand(i*2+1), Flag); + Outs[i].Val, Flag); Flag = Chain.getValue(1); } @@ -2648,12 +2636,6 @@ SPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) return LowerJumpTable(Op, DAG, SPUTM.getSubtargetImpl()); case ISD::ConstantFP: return LowerConstantFP(Op, DAG); - case ISD::FORMAL_ARGUMENTS: - return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex); - case ISD::CALL: - return LowerCALL(Op, DAG, SPUTM.getSubtargetImpl()); - case ISD::RET: - return LowerRET(Op, DAG, getTargetMachine()); // i8, i64 math ops: case ISD::ADD: diff --git a/lib/Target/CellSPU/SPUISelLowering.h b/lib/Target/CellSPU/SPUISelLowering.h index b1583f4..3bc090a 100644 --- a/lib/Target/CellSPU/SPUISelLowering.h +++ b/lib/Target/CellSPU/SPUISelLowering.h @@ -150,6 +150,28 @@ namespace llvm { /// getFunctionAlignment - Return the Log2 alignment of this function. virtual unsigned getFunctionAlignment(const Function *F) const; + + virtual SDValue + LowerFormalArguments(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + virtual SDValue + LowerCall(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, + bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + virtual SDValue + LowerReturn(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG); }; } diff --git a/lib/Target/CellSPU/SPUInstrInfo.td b/lib/Target/CellSPU/SPUInstrInfo.td index 63eb85a..09849da 100644 --- a/lib/Target/CellSPU/SPUInstrInfo.td +++ b/lib/Target/CellSPU/SPUInstrInfo.td @@ -4431,13 +4431,6 @@ def : Pat<(i8 imm:$imm), (ILHr8 imm:$imm)>; //===----------------------------------------------------------------------===// -// Call instruction patterns: -//===----------------------------------------------------------------------===// -// Return void -def : Pat<(ret), - (RET)>; - -//===----------------------------------------------------------------------===// // Zero/Any/Sign extensions //===----------------------------------------------------------------------===// diff --git a/lib/Target/MSP430/MSP430ISelLowering.cpp b/lib/Target/MSP430/MSP430ISelLowering.cpp index 9413060..d1a504b 100644 --- a/lib/Target/MSP430/MSP430ISelLowering.cpp +++ b/lib/Target/MSP430/MSP430ISelLowering.cpp @@ -80,7 +80,6 @@ MSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) : setOperationAction(ISD::ROTR, MVT::i8, Expand); setOperationAction(ISD::ROTL, MVT::i16, Expand); setOperationAction(ISD::ROTR, MVT::i16, Expand); - setOperationAction(ISD::RET, MVT::Other, Custom); setOperationAction(ISD::GlobalAddress, MVT::i16, Custom); setOperationAction(ISD::ExternalSymbol, MVT::i16, Custom); setOperationAction(ISD::BR_JT, MVT::Other, Expand); @@ -129,12 +128,9 @@ MSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) : SDValue MSP430TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { switch (Op.getOpcode()) { - case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG); case ISD::SHL: // FALLTHROUGH case ISD::SRL: case ISD::SRA: return LowerShifts(Op, DAG); - case ISD::RET: return LowerRET(Op, DAG); - case ISD::CALL: return LowerCALL(Op, DAG); case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); case ISD::ExternalSymbol: return LowerExternalSymbol(Op, DAG); case ISD::BR_CC: return LowerBR_CC(Op, DAG); @@ -157,27 +153,41 @@ unsigned MSP430TargetLowering::getFunctionAlignment(const Function *F) const { #include "MSP430GenCallingConv.inc" -SDValue MSP430TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, - SelectionDAG &DAG) { - unsigned CC = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue(); - switch (CC) { +SDValue +MSP430TargetLowering::LowerFormalArguments(SDValue Chain, + unsigned CallConv, + bool isVarArg, + const SmallVectorImpl<ISD::InputArg> + &Ins, + DebugLoc dl, + SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + + switch (CallConv) { default: llvm_unreachable("Unsupported calling convention"); case CallingConv::C: case CallingConv::Fast: - return LowerCCCArguments(Op, DAG); + return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals); } } -SDValue MSP430TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { - CallSDNode *TheCall = cast<CallSDNode>(Op.getNode()); - unsigned CallingConv = TheCall->getCallingConv(); - switch (CallingConv) { +SDValue +MSP430TargetLowering::LowerCall(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, + bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + + switch (CallConv) { default: llvm_unreachable("Unsupported calling convention"); case CallingConv::Fast: case CallingConv::C: - return LowerCCCCallTo(Op, DAG, CallingConv); + return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall, + Outs, Ins, dl, DAG, InVals); } } @@ -185,24 +195,27 @@ SDValue MSP430TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { /// generate load operations for arguments places on the stack. // FIXME: struct return stuff // FIXME: varargs -SDValue MSP430TargetLowering::LowerCCCArguments(SDValue Op, - SelectionDAG &DAG) { +SDValue +MSP430TargetLowering::LowerCCCArguments(SDValue Chain, + unsigned CallConv, + bool isVarArg, + const SmallVectorImpl<ISD::InputArg> + &Ins, + DebugLoc dl, + SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); MachineRegisterInfo &RegInfo = MF.getRegInfo(); - SDValue Root = Op.getOperand(0); - bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0; - unsigned CC = MF.getFunction()->getCallingConv(); - DebugLoc dl = Op.getDebugLoc(); // Assign locations to all of the incoming arguments. SmallVector<CCValAssign, 16> ArgLocs; - CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs, *DAG.getContext()); - CCInfo.AnalyzeFormalArguments(Op.getNode(), CC_MSP430); + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), + ArgLocs, *DAG.getContext()); + CCInfo.AnalyzeFormalArguments(Ins, CC_MSP430); assert(!isVarArg && "Varargs not supported yet"); - SmallVector<SDValue, 16> ArgValues; for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { CCValAssign &VA = ArgLocs[i]; if (VA.isRegLoc()) { @@ -212,7 +225,7 @@ SDValue MSP430TargetLowering::LowerCCCArguments(SDValue Op, default: { #ifndef NDEBUG - cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: " + cerr << "LowerFormalArguments Unhandled argument type: " << RegVT.getSimpleVT() << "\n"; #endif llvm_unreachable(0); @@ -221,7 +234,7 @@ SDValue MSP430TargetLowering::LowerCCCArguments(SDValue Op, unsigned VReg = RegInfo.createVirtualRegister(MSP430::GR16RegisterClass); RegInfo.addLiveIn(VA.getLocReg(), VReg); - SDValue ArgValue = DAG.getCopyFromReg(Root, dl, VReg, RegVT); + SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, VReg, RegVT); // If this is an 8-bit value, it is really passed promoted to 16 // bits. Insert an assert[sz]ext to capture this, then truncate to the @@ -236,7 +249,7 @@ SDValue MSP430TargetLowering::LowerCCCArguments(SDValue Op, if (VA.getLocInfo() != CCValAssign::Full) ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue); - ArgValues.push_back(ArgValue); + InVals.push_back(ArgValue); } } else { // Sanity check @@ -244,7 +257,7 @@ SDValue MSP430TargetLowering::LowerCCCArguments(SDValue Op, // Load the argument to a virtual register unsigned ObjSize = VA.getLocVT().getSizeInBits()/8; if (ObjSize > 2) { - cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: " + cerr << "LowerFormalArguments Unhandled argument type: " << VA.getLocVT().getSimpleVT() << "\n"; } @@ -254,30 +267,29 @@ SDValue MSP430TargetLowering::LowerCCCArguments(SDValue Op, // Create the SelectionDAG nodes corresponding to a load //from this parameter SDValue FIN = DAG.getFrameIndex(FI, MVT::i16); - ArgValues.push_back(DAG.getLoad(VA.getLocVT(), dl, Root, FIN, - PseudoSourceValue::getFixedStack(FI), 0)); + InVals.push_back(DAG.getLoad(VA.getLocVT(), dl, Chain, FIN, + PseudoSourceValue::getFixedStack(FI), 0)); } } - ArgValues.push_back(Root); - - // Return the new list of results. - return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getNode()->getVTList(), - &ArgValues[0], ArgValues.size()).getValue(Op.getResNo()); + return Chain; } -SDValue MSP430TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) { +SDValue +MSP430TargetLowering::LowerReturn(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG) { + // CCValAssign - represent the assignment of the return value to a location SmallVector<CCValAssign, 16> RVLocs; - unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv(); - bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg(); - DebugLoc dl = Op.getDebugLoc(); // CCState - Info about the registers and stack slot. - CCState CCInfo(CC, isVarArg, getTargetMachine(), RVLocs, *DAG.getContext()); + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), + RVLocs, *DAG.getContext()); - // Analize return values of ISD::RET - CCInfo.AnalyzeReturn(Op.getNode(), RetCC_MSP430); + // Analize return values. + CCInfo.AnalyzeReturn(Outs, RetCC_MSP430); // If this is the first return lowered for this function, add the regs to the // liveout set for the function. @@ -287,8 +299,6 @@ SDValue MSP430TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) { DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); } - // The chain is always operand #0 - SDValue Chain = Op.getOperand(0); SDValue Flag; // Copy the result values into the output registers. @@ -296,10 +306,8 @@ SDValue MSP430TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) { CCValAssign &VA = RVLocs[i]; assert(VA.isRegLoc() && "Can only return in registers!"); - // ISD::RET => ret chain, (regnum1,val1), ... - // So i*2+1 index only the regnums Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), - Op.getOperand(i*2+1), Flag); + Outs[i].Val, Flag); // Guarantee that all emitted copies are stuck together, // avoiding something bad. @@ -316,19 +324,21 @@ SDValue MSP430TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) { /// LowerCCCCallTo - functions arguments are copied from virtual regs to /// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted. /// TODO: sret. -SDValue MSP430TargetLowering::LowerCCCCallTo(SDValue Op, SelectionDAG &DAG, - unsigned CC) { - CallSDNode *TheCall = cast<CallSDNode>(Op.getNode()); - SDValue Chain = TheCall->getChain(); - SDValue Callee = TheCall->getCallee(); - bool isVarArg = TheCall->isVarArg(); - DebugLoc dl = Op.getDebugLoc(); - +SDValue +MSP430TargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, + bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> + &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { // Analyze operands of the call, assigning locations to each operand. SmallVector<CCValAssign, 16> ArgLocs; - CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs, *DAG.getContext()); + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), + ArgLocs, *DAG.getContext()); - CCInfo.AnalyzeCallOperands(TheCall, CC_MSP430); + CCInfo.AnalyzeCallOperands(Outs, CC_MSP430); // Get a count of how many bytes are to be pushed on the stack. unsigned NumBytes = CCInfo.getNextStackOffset(); @@ -344,8 +354,7 @@ SDValue MSP430TargetLowering::LowerCCCCallTo(SDValue Op, SelectionDAG &DAG, for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { CCValAssign &VA = ArgLocs[i]; - // Arguments start after the 5 first operands of ISD::CALL - SDValue Arg = TheCall->getArg(i); + SDValue Arg = Outs[i].Val; // Promote the value if needed. switch (VA.getLocInfo()) { @@ -434,44 +443,36 @@ SDValue MSP430TargetLowering::LowerCCCCallTo(SDValue Op, SelectionDAG &DAG, // Handle result values, copying them out of physregs into vregs that we // return. - return SDValue(LowerCallResult(Chain, InFlag, TheCall, CC, DAG), - Op.getResNo()); + return LowerCallResult(Chain, InFlag, CallConv, isVarArg, Ins, dl, + DAG, InVals); } -/// LowerCallResult - Lower the result values of an ISD::CALL into the -/// appropriate copies out of appropriate physical registers. This assumes that -/// Chain/InFlag are the input chain/flag to use, and that TheCall is the call -/// being lowered. Returns a SDNode with the same number of values as the -/// ISD::CALL. -SDNode* +/// LowerCallResult - Lower the result values of a call into the +/// appropriate copies out of appropriate physical registers. +/// +SDValue MSP430TargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, - CallSDNode *TheCall, - unsigned CallingConv, - SelectionDAG &DAG) { - bool isVarArg = TheCall->isVarArg(); - DebugLoc dl = TheCall->getDebugLoc(); + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { // Assign locations to each value returned by this call. SmallVector<CCValAssign, 16> RVLocs; - CCState CCInfo(CallingConv, isVarArg, getTargetMachine(), + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), RVLocs, *DAG.getContext()); - CCInfo.AnalyzeCallResult(TheCall, RetCC_MSP430); - SmallVector<SDValue, 8> ResultVals; + CCInfo.AnalyzeCallResult(Ins, RetCC_MSP430); // Copy all of the result registers out of their specified physreg. for (unsigned i = 0; i != RVLocs.size(); ++i) { Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(), RVLocs[i].getValVT(), InFlag).getValue(1); InFlag = Chain.getValue(2); - ResultVals.push_back(Chain.getValue(0)); + InVals.push_back(Chain.getValue(0)); } - ResultVals.push_back(Chain); - - // Merge everything together with a MERGE_VALUES node. - return DAG.getNode(ISD::MERGE_VALUES, dl, TheCall->getVTList(), - &ResultVals[0], ResultVals.size()).getNode(); + return Chain; } SDValue MSP430TargetLowering::LowerShifts(SDValue Op, diff --git a/lib/Target/MSP430/MSP430ISelLowering.h b/lib/Target/MSP430/MSP430ISelLowering.h index 4a90a0e..1339ccd 100644 --- a/lib/Target/MSP430/MSP430ISelLowering.h +++ b/lib/Target/MSP430/MSP430ISelLowering.h @@ -33,7 +33,7 @@ namespace llvm { /// Y = RRC X, rotate right via carry RRC, - /// CALL/TAILCALL - These operations represent an abstract call + /// CALL - These operations represent an abstract call /// instruction, which includes a bunch of information. CALL, @@ -77,10 +77,6 @@ namespace llvm { /// getFunctionAlignment - Return the Log2 alignment of this function. virtual unsigned getFunctionAlignment(const Function *F) const; - SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG); - SDValue LowerCALL(SDValue Op, SelectionDAG &DAG); - SDValue LowerRET(SDValue Op, SelectionDAG &DAG); - SDValue LowerCCCArguments(SDValue Op, SelectionDAG &DAG); SDValue LowerShifts(SDValue Op, SelectionDAG &DAG); SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG); SDValue LowerExternalSymbol(SDValue Op, SelectionDAG &DAG); @@ -88,16 +84,52 @@ namespace llvm { SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG); SDValue LowerSIGN_EXTEND(SDValue Op, SelectionDAG &DAG); - SDValue LowerCCCCallTo(SDValue Op, SelectionDAG &DAG, - unsigned CC); - SDNode* LowerCallResult(SDValue Chain, SDValue InFlag, - CallSDNode *TheCall, - unsigned CallingConv, SelectionDAG &DAG); - MachineBasicBlock* EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *BB) const; private: + SDValue LowerCCCCallTo(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, + bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + SDValue LowerCCCArguments(SDValue Chain, + unsigned CallConv, + bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, + SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + SDValue LowerCallResult(SDValue Chain, SDValue InFlag, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + virtual SDValue + LowerFormalArguments(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + virtual SDValue + LowerCall(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + virtual SDValue + LowerReturn(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG); + const MSP430Subtarget &Subtarget; const MSP430TargetMachine &TM; }; diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index ab3f144..7ced391 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -94,7 +94,6 @@ MipsTargetLowering(MipsTargetMachine &TM) // Mips Custom Operations setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom); - setOperationAction(ISD::RET, MVT::Other, Custom); setOperationAction(ISD::JumpTable, MVT::i32, Custom); setOperationAction(ISD::ConstantPool, MVT::i32, Custom); setOperationAction(ISD::SELECT, MVT::f32, Custom); @@ -182,16 +181,13 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) { case ISD::AND: return LowerANDOR(Op, DAG); case ISD::BRCOND: return LowerBRCOND(Op, DAG); - case ISD::CALL: return LowerCALL(Op, DAG); case ISD::ConstantPool: return LowerConstantPool(Op, DAG); case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG); - case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG); case ISD::FP_TO_SINT: return LowerFP_TO_SINT(Op, DAG); case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG); case ISD::JumpTable: return LowerJumpTable(Op, DAG); case ISD::OR: return LowerANDOR(Op, DAG); - case ISD::RET: return LowerRET(Op, DAG); case ISD::SELECT: return LowerSELECT(Op, DAG); case ISD::SETCC: return LowerSETCC(Op, DAG); } @@ -580,13 +576,6 @@ LowerConstantPool(SDValue Op, SelectionDAG &DAG) //===----------------------------------------------------------------------===// // Calling Convention Implementation -// -// The lower operations present on calling convention works on this order: -// LowerCALL (virt regs --> phys regs, virt regs --> stack) -// LowerFORMAL_ARGUMENTS (phys --> virt regs, stack --> virt regs) -// LowerRET (virt regs --> phys regs) -// LowerCALL (phys regs --> virt regs) -// //===----------------------------------------------------------------------===// #include "MipsGenCallingConv.inc" @@ -671,38 +660,37 @@ static bool CC_MipsO32(unsigned ValNo, MVT ValVT, } //===----------------------------------------------------------------------===// -// CALL Calling Convention Implementation +// Call Calling Convention Implementation //===----------------------------------------------------------------------===// -/// LowerCALL - functions arguments are copied from virtual regs to +/// LowerCall - functions arguments are copied from virtual regs to /// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted. /// TODO: isVarArg, isTailCall. -SDValue MipsTargetLowering:: -LowerCALL(SDValue Op, SelectionDAG &DAG) -{ - MachineFunction &MF = DAG.getMachineFunction(); - - CallSDNode *TheCall = cast<CallSDNode>(Op.getNode()); - SDValue Chain = TheCall->getChain(); - SDValue Callee = TheCall->getCallee(); - bool isVarArg = TheCall->isVarArg(); - unsigned CC = TheCall->getCallingConv(); - DebugLoc dl = TheCall->getDebugLoc(); +SDValue +MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, + bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); // Analyze operands of the call, assigning locations to each operand. SmallVector<CCValAssign, 16> ArgLocs; - CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs, *DAG.getContext()); + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), ArgLocs, + *DAG.getContext()); // To meet O32 ABI, Mips must always allocate 16 bytes on // the stack (even if less than 4 are used as arguments) if (Subtarget->isABI_O32()) { int VTsize = MVT(MVT::i32).getSizeInBits()/8; MFI->CreateFixedObject(VTsize, (VTsize*3)); - CCInfo.AnalyzeCallOperands(TheCall, CC_MipsO32); + CCInfo.AnalyzeCallOperands(Outs, CC_MipsO32); } else - CCInfo.AnalyzeCallOperands(TheCall, CC_Mips); + CCInfo.AnalyzeCallOperands(Outs, CC_Mips); // Get a count of how many bytes are to be pushed on the stack. unsigned NumBytes = CCInfo.getNextStackOffset(); @@ -719,7 +707,7 @@ LowerCALL(SDValue Op, SelectionDAG &DAG) // Walk the register/memloc assignments, inserting copies/loads. for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { - SDValue Arg = TheCall->getArg(i); + SDValue Arg = Outs[i].Val; CCValAssign &VA = ArgLocs[i]; // Promote the value if needed. @@ -859,76 +847,69 @@ LowerCALL(SDValue Op, SelectionDAG &DAG) // Handle result values, copying them out of physregs into vregs that we // return. - return SDValue(LowerCallResult(Chain, InFlag, TheCall, CC, DAG), Op.getResNo()); + return LowerCallResult(Chain, InFlag, CallConv, isVarArg, + Ins, dl, DAG, InVals); } -/// LowerCallResult - Lower the result values of an ISD::CALL into the -/// appropriate copies out of appropriate physical registers. This assumes that -/// Chain/InFlag are the input chain/flag to use, and that TheCall is the call -/// being lowered. Returns a SDNode with the same number of values as the -/// ISD::CALL. -SDNode *MipsTargetLowering:: -LowerCallResult(SDValue Chain, SDValue InFlag, CallSDNode *TheCall, - unsigned CallingConv, SelectionDAG &DAG) { - - bool isVarArg = TheCall->isVarArg(); - DebugLoc dl = TheCall->getDebugLoc(); +/// LowerCallResult - Lower the result values of a call into the +/// appropriate copies out of appropriate physical registers. +SDValue +MipsTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { // Assign locations to each value returned by this call. SmallVector<CCValAssign, 16> RVLocs; - CCState CCInfo(CallingConv, isVarArg, getTargetMachine(), + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), RVLocs, *DAG.getContext()); - CCInfo.AnalyzeCallResult(TheCall, RetCC_Mips); - SmallVector<SDValue, 8> ResultVals; + CCInfo.AnalyzeCallResult(Ins, RetCC_Mips); // Copy all of the result registers out of their specified physreg. for (unsigned i = 0; i != RVLocs.size(); ++i) { Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(), - RVLocs[i].getValVT(), InFlag).getValue(1); + RVLocs[i].getValVT(), InFlag).getValue(1); InFlag = Chain.getValue(2); - ResultVals.push_back(Chain.getValue(0)); + InVals.push_back(Chain.getValue(0)); } - - ResultVals.push_back(Chain); - // Merge everything together with a MERGE_VALUES node. - return DAG.getNode(ISD::MERGE_VALUES, dl, TheCall->getVTList(), - &ResultVals[0], ResultVals.size()).getNode(); + return Chain; } //===----------------------------------------------------------------------===// -// FORMAL_ARGUMENTS Calling Convention Implementation +// Formal Arguments Calling Convention Implementation //===----------------------------------------------------------------------===// -/// LowerFORMAL_ARGUMENTS - transform physical registers into +/// LowerFormalArguments - transform physical registers into /// virtual registers and generate load operations for /// arguments places on the stack. /// TODO: isVarArg -SDValue MipsTargetLowering:: -LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) -{ - SDValue Root = Op.getOperand(0); +SDValue +MipsTargetLowering::LowerFormalArguments(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> + &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); - DebugLoc dl = Op.getDebugLoc(); - - bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0; - unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv(); unsigned StackReg = MF.getTarget().getRegisterInfo()->getFrameRegister(MF); // Assign locations to all of the incoming arguments. SmallVector<CCValAssign, 16> ArgLocs; - CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs, *DAG.getContext()); + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), + ArgLocs, *DAG.getContext()); if (Subtarget->isABI_O32()) - CCInfo.AnalyzeFormalArguments(Op.getNode(), CC_MipsO32); + CCInfo.AnalyzeFormalArguments(Ins, CC_MipsO32); else - CCInfo.AnalyzeFormalArguments(Op.getNode(), CC_Mips); + CCInfo.AnalyzeFormalArguments(Ins, CC_Mips); - SmallVector<SDValue, 16> ArgValues; SDValue StackPtr; unsigned FirstStackArgLoc = (Subtarget->isABI_EABI() ? 0 : 16); @@ -949,12 +930,12 @@ LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) if (!Subtarget->isSingleFloat()) RC = Mips::AFGR64RegisterClass; } else - llvm_unreachable("RegVT not supported by FORMAL_ARGUMENTS Lowering"); + llvm_unreachable("RegVT not supported by LowerFormalArguments Lowering"); // Transform the arguments stored on // physical registers into virtual ones unsigned Reg = AddLiveIn(DAG.getMachineFunction(), VA.getLocReg(), RC); - SDValue ArgValue = DAG.getCopyFromReg(Root, dl, Reg, RegVT); + SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, RegVT); // If this is an 8 or 16-bit value, it has been passed promoted // to 32 bits. Insert an assert[sz]ext to capture this, then @@ -978,14 +959,14 @@ LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) if (RegVT == MVT::i32 && VA.getValVT() == MVT::f64) { unsigned Reg2 = AddLiveIn(DAG.getMachineFunction(), VA.getLocReg()+1, RC); - SDValue ArgValue2 = DAG.getCopyFromReg(Root, dl, Reg2, RegVT); + SDValue ArgValue2 = DAG.getCopyFromReg(Chain, dl, Reg2, RegVT); SDValue Hi = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, ArgValue); SDValue Lo = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, ArgValue2); ArgValue = DAG.getNode(ISD::BUILD_PAIR, dl, MVT::f64, Lo, Hi); } } - ArgValues.push_back(ArgValue); + InVals.push_back(ArgValue); // To meet ABI, when VARARGS are passed on registers, the registers // must have their values written to the caller stack frame. @@ -1007,7 +988,7 @@ LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) // emit ISD::STORE whichs stores the // parameter value to a stack Location - ArgValues.push_back(DAG.getStore(Root, dl, ArgValue, PtrOff, NULL, 0)); + InVals.push_back(DAG.getStore(Chain, dl, ArgValue, PtrOff, NULL, 0)); } } else { // VA.isRegLoc() @@ -1030,7 +1011,7 @@ LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) // Create load nodes to retrieve arguments from the stack SDValue FIN = DAG.getFrameIndex(FI, getPointerTy()); - ArgValues.push_back(DAG.getLoad(VA.getValVT(), dl, Root, FIN, NULL, 0)); + InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN, NULL, 0)); } } @@ -1043,36 +1024,33 @@ LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) Reg = MF.getRegInfo().createVirtualRegister(getRegClassFor(MVT::i32)); MipsFI->setSRetReturnReg(Reg); } - SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), dl, Reg, ArgValues[0]); - Root = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Copy, Root); + SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), dl, Reg, InVals[0]); + Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Copy, Chain); } - ArgValues.push_back(Root); - - // Return the new list of results. - return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getNode()->getVTList(), - &ArgValues[0], ArgValues.size()).getValue(Op.getResNo()); + return Chain; } //===----------------------------------------------------------------------===// // Return Value Calling Convention Implementation //===----------------------------------------------------------------------===// -SDValue MipsTargetLowering:: -LowerRET(SDValue Op, SelectionDAG &DAG) -{ +SDValue +MipsTargetLowering::LowerReturn(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG) { + // CCValAssign - represent the assignment of // the return value to a location SmallVector<CCValAssign, 16> RVLocs; - unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv(); - bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg(); - DebugLoc dl = Op.getDebugLoc(); // CCState - Info about the registers and stack slot. - CCState CCInfo(CC, isVarArg, getTargetMachine(), RVLocs, *DAG.getContext()); + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), + RVLocs, *DAG.getContext()); - // Analize return values of ISD::RET - CCInfo.AnalyzeReturn(Op.getNode(), RetCC_Mips); + // Analize return values. + CCInfo.AnalyzeReturn(Outs, RetCC_Mips); // If this is the first return lowered for this function, add // the regs to the liveout set for the function. @@ -1082,8 +1060,6 @@ LowerRET(SDValue Op, SelectionDAG &DAG) DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); } - // The chain is always operand #0 - SDValue Chain = Op.getOperand(0); SDValue Flag; // Copy the result values into the output registers. @@ -1091,10 +1067,8 @@ LowerRET(SDValue Op, SelectionDAG &DAG) CCValAssign &VA = RVLocs[i]; assert(VA.isRegLoc() && "Can only return in registers!"); - // ISD::RET => ret chain, (regnum1,val1), ... - // So i*2+1 index only the regnums Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), - Op.getOperand(i*2+1), Flag); + Outs[i].Val, Flag); // guarantee that all emitted copies are // stuck together, avoiding something bad diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h index 234eddd..e116fbe 100644 --- a/lib/Target/Mips/MipsISelLowering.h +++ b/lib/Target/Mips/MipsISelLowering.h @@ -89,24 +89,46 @@ namespace llvm { const MipsSubtarget *Subtarget; // Lower Operand helpers - SDNode *LowerCallResult(SDValue Chain, SDValue InFlag, CallSDNode *TheCall, - unsigned CallingConv, SelectionDAG &DAG); + SDValue LowerCallResult(SDValue Chain, SDValue InFlag, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); // Lower Operand specifics SDValue LowerANDOR(SDValue Op, SelectionDAG &DAG); SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG); - SDValue LowerCALL(SDValue Op, SelectionDAG &DAG); SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG); SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG); - SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG); SDValue LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG); SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG); SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG); SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG); - SDValue LowerRET(SDValue Op, SelectionDAG &DAG); SDValue LowerSELECT(SDValue Op, SelectionDAG &DAG); SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG); + virtual SDValue + LowerFormalArguments(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + virtual SDValue + LowerCall(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, + bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + virtual SDValue + LowerReturn(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG); + virtual MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const; diff --git a/lib/Target/Mips/MipsMachineFunction.h b/lib/Target/Mips/MipsMachineFunction.h index ac3cdfd..949c78a 100644 --- a/lib/Target/Mips/MipsMachineFunction.h +++ b/lib/Target/Mips/MipsMachineFunction.h @@ -57,7 +57,7 @@ private: /// to be used on emitPrologue and processFunctionBeforeFrameFinalized. MipsFIHolder GPHolder; - /// On LowerFORMAL_ARGUMENTS the stack size is unknown, so the Stack + /// On LowerFormalArguments the stack size is unknown, so the Stack /// Pointer Offset calculation of "not in register arguments" must be /// postponed to emitPrologue. SmallVector<MipsFIHolder, 16> FnLoadArgs; @@ -65,7 +65,7 @@ private: // When VarArgs, we must write registers back to caller stack, preserving // on register arguments. Since the stack size is unknown on - // LowerFORMAL_ARGUMENTS, the Stack Pointer Offset calculation must be + // LowerFormalArguments, the Stack Pointer Offset calculation must be // postponed to emitPrologue. SmallVector<MipsFIHolder, 4> FnStoreVarArgs; bool HasStoreVarArgs; diff --git a/lib/Target/Mips/MipsRegisterInfo.cpp b/lib/Target/Mips/MipsRegisterInfo.cpp index 841e40a..1176b42 100644 --- a/lib/Target/Mips/MipsRegisterInfo.cpp +++ b/lib/Target/Mips/MipsRegisterInfo.cpp @@ -212,7 +212,7 @@ getReservedRegs(const MachineFunction &MF) const // The emitted instruction will be something like: // lw REGX, 16+StackSize(SP) // -// Since the total stack size is unknown on LowerFORMAL_ARGUMENTS, all +// Since the total stack size is unknown on LowerFormalArguments, all // stack references (ObjectOffset) created to reference the function // arguments, are negative numbers. This way, on eliminateFrameIndex it's // possible to detect those references and the offsets are adjusted to @@ -234,7 +234,7 @@ void MipsRegisterInfo::adjustMipsStackFrame(MachineFunction &MF) const int TopCPUSavedRegOff = -1, TopFPUSavedRegOff = -1; // Replace the dummy '0' SPOffset by the negative offsets, as explained on - // LowerFORMAL_ARGUMENTS. Leaving '0' for while is necessary to avoid + // LowerFormalArguments. Leaving '0' for while is necessary to avoid // the approach done by calculateFrameObjectOffsets to the stack frame. MipsFI->adjustLoadArgsFI(MFI); MipsFI->adjustStoreVarArgsFI(MFI); @@ -378,7 +378,7 @@ eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, DOUT << "stackSize : " << stackSize << "\n"; #endif - // as explained on LowerFORMAL_ARGUMENTS, detect negative offsets + // as explained on LowerFormalArguments, detect negative offsets // and adjust SPOffsets considering the final stack size. int Offset = ((spOffset < 0) ? (stackSize + (-(spOffset+4))) : (spOffset)); Offset += MI.getOperand(i-1).getImm(); diff --git a/lib/Target/PIC16/PIC16ISelLowering.cpp b/lib/Target/PIC16/PIC16ISelLowering.cpp index 47a51c4..915669b 100644 --- a/lib/Target/PIC16/PIC16ISelLowering.cpp +++ b/lib/Target/PIC16/PIC16ISelLowering.cpp @@ -268,8 +268,6 @@ PIC16TargetLowering::PIC16TargetLowering(PIC16TargetMachine &TM) setOperationAction(ISD::XOR, MVT::i8, Custom); setOperationAction(ISD::FrameIndex, MVT::i16, Custom); - setOperationAction(ISD::CALL, MVT::i16, Custom); - setOperationAction(ISD::RET, MVT::Other, Custom); setOperationAction(ISD::MUL, MVT::i8, Custom); @@ -410,7 +408,9 @@ PIC16TargetLowering::MakePIC16Libcall(PIC16ISD::PIC16Libcall Call, const Type *RetTy = RetVT.getTypeForMVT(); std::pair<SDValue,SDValue> CallInfo = LowerCallTo(DAG.getEntryNode(), RetTy, isSigned, !isSigned, false, - false, 0, CallingConv::C, false, Callee, Args, DAG, dl); + false, 0, CallingConv::C, false, + /*isReturnValueUsed=*/true, + Callee, Args, DAG, dl); return CallInfo.first; } @@ -440,6 +440,7 @@ const char *PIC16TargetLowering::getTargetNodeName(unsigned Opcode) const { case PIC16ISD::SUBCC: return "PIC16ISD::SUBCC"; case PIC16ISD::SELECT_ICC: return "PIC16ISD::SELECT_ICC"; case PIC16ISD::BRCOND: return "PIC16ISD::BRCOND"; + case PIC16ISD::RET: return "PIC16ISD::RET"; case PIC16ISD::Dummy: return "PIC16ISD::Dummy"; } } @@ -994,12 +995,8 @@ PIC16TargetLowering::LowerOperationWrapper(SDNode *N, SDValue Res; unsigned i; switch (Op.getOpcode()) { - case ISD::FORMAL_ARGUMENTS: - Res = LowerFORMAL_ARGUMENTS(Op, DAG); break; case ISD::LOAD: Res = ExpandLoad(Op.getNode(), DAG); break; - case ISD::CALL: - Res = LowerCALL(Op, DAG); break; default: { // All other operations are handled in LowerOperation. Res = LowerOperation(Op, DAG); @@ -1019,8 +1016,6 @@ PIC16TargetLowering::LowerOperationWrapper(SDNode *N, SDValue PIC16TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { switch (Op.getOpcode()) { - case ISD::FORMAL_ARGUMENTS: - return LowerFORMAL_ARGUMENTS(Op, DAG); case ISD::ADD: case ISD::ADDC: case ISD::ADDE: @@ -1043,10 +1038,6 @@ SDValue PIC16TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { case ISD::AND: case ISD::XOR: return LowerBinOp(Op, DAG); - case ISD::CALL: - return LowerCALL(Op, DAG); - case ISD::RET: - return LowerRET(Op, DAG); case ISD::BR_CC: return LowerBR_CC(Op, DAG); case ISD::SELECT_CC: @@ -1091,12 +1082,11 @@ SDValue PIC16TargetLowering::ConvertToMemOperand(SDValue Op, } SDValue PIC16TargetLowering:: -LowerIndirectCallArguments(SDValue Op, SDValue Chain, SDValue InFlag, +LowerIndirectCallArguments(SDValue Chain, SDValue InFlag, SDValue DataAddr_Lo, SDValue DataAddr_Hi, - SelectionDAG &DAG) { - CallSDNode *TheCall = dyn_cast<CallSDNode>(Op); - unsigned NumOps = TheCall->getNumArgs(); - DebugLoc dl = TheCall->getDebugLoc(); + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG) { + unsigned NumOps = Outs.size(); // If call has no arguments then do nothing and return. if (NumOps == 0) @@ -1107,10 +1097,10 @@ LowerIndirectCallArguments(SDValue Op, SDValue Chain, SDValue InFlag, SDValue Arg, StoreRet; // For PIC16 ABI the arguments come after the return value. - unsigned RetVals = TheCall->getNumRetVals(); + unsigned RetVals = Outs.size(); for (unsigned i = 0, ArgOffset = RetVals; i < NumOps; i++) { // Get the arguments - Arg = TheCall->getArg(i); + Arg = Outs[i].Val; Ops.clear(); Ops.push_back(Chain); @@ -1130,16 +1120,14 @@ LowerIndirectCallArguments(SDValue Op, SDValue Chain, SDValue InFlag, } SDValue PIC16TargetLowering:: -LowerDirectCallArguments(SDValue Op, SDValue Chain, SDValue ArgLabel, - SDValue InFlag, SelectionDAG &DAG) { - CallSDNode *TheCall = dyn_cast<CallSDNode>(Op); - unsigned NumOps = TheCall->getNumArgs(); - DebugLoc dl = TheCall->getDebugLoc(); +LowerDirectCallArguments(SDValue ArgLabel, SDValue Chain, SDValue InFlag, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG) { + unsigned NumOps = Outs.size(); std::string Name; SDValue Arg, StoreAt; MVT ArgVT; unsigned Size=0; - unsigned ArgCount=0; // If call has no arguments then do nothing and return. if (NumOps == 0) @@ -1157,9 +1145,9 @@ LowerDirectCallArguments(SDValue Op, SDValue Chain, SDValue ArgLabel, std::vector<SDValue> Ops; SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag); - for (unsigned i=ArgCount, Offset = 0; i<NumOps; i++) { + for (unsigned i=0, Offset = 0; i<NumOps; i++) { // Get the argument - Arg = TheCall->getArg(i); + Arg = Outs[i].Val; StoreOffset = (Offset + AddressOffset); // Store the argument on frame @@ -1187,12 +1175,12 @@ LowerDirectCallArguments(SDValue Op, SDValue Chain, SDValue ArgLabel, } SDValue PIC16TargetLowering:: -LowerIndirectCallReturn (SDValue Op, SDValue Chain, SDValue InFlag, - SDValue DataAddr_Lo, SDValue DataAddr_Hi, - SelectionDAG &DAG) { - CallSDNode *TheCall = dyn_cast<CallSDNode>(Op); - DebugLoc dl = TheCall->getDebugLoc(); - unsigned RetVals = TheCall->getNumRetVals(); +LowerIndirectCallReturn(SDValue Chain, SDValue InFlag, + SDValue DataAddr_Lo, SDValue DataAddr_Hi, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + unsigned RetVals = Ins.size(); // If call does not have anything to return // then do nothing and go back. @@ -1200,7 +1188,6 @@ LowerIndirectCallReturn (SDValue Op, SDValue Chain, SDValue InFlag, return Chain; // Call has something to return - std::vector<SDValue> ResultVals; SDValue LoadRet; SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Other, MVT::Flag); @@ -1210,23 +1197,20 @@ LowerIndirectCallReturn (SDValue Op, SDValue Chain, SDValue InFlag, InFlag); InFlag = getOutFlag(LoadRet); Chain = getChain(LoadRet); - ResultVals.push_back(LoadRet); + InVals.push_back(LoadRet); } - ResultVals.push_back(Chain); - SDValue Res = DAG.getMergeValues(&ResultVals[0], ResultVals.size(), dl); - return Res; + return Chain; } SDValue PIC16TargetLowering:: -LowerDirectCallReturn(SDValue Op, SDValue Chain, SDValue RetLabel, - SDValue InFlag, SelectionDAG &DAG) { - CallSDNode *TheCall = dyn_cast<CallSDNode>(Op); - DebugLoc dl = TheCall->getDebugLoc(); +LowerDirectCallReturn(SDValue RetLabel, SDValue Chain, SDValue InFlag, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + // Currently handling primitive types only. They will come in // i8 parts - unsigned RetVals = TheCall->getNumRetVals(); - - std::vector<SDValue> ResultVals; + unsigned RetVals = Ins.size(); // Return immediately if the return type is void if (RetVals == 0) @@ -1252,29 +1236,20 @@ LowerDirectCallReturn(SDValue Op, SDValue Chain, SDValue RetLabel, Chain = getChain(LoadRet); Offset++; - ResultVals.push_back(LoadRet); + InVals.push_back(LoadRet); } - // To return use MERGE_VALUES - ResultVals.push_back(Chain); - SDValue Res = DAG.getMergeValues(&ResultVals[0], ResultVals.size(), dl); - return Res; + return Chain; } -SDValue PIC16TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) { - SDValue Chain = Op.getOperand(0); - DebugLoc dl = Op.getDebugLoc(); - - if (Op.getNumOperands() == 1) // return void - return Op; +SDValue +PIC16TargetLowering::LowerReturn(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG) { - // return should have odd number of operands - if ((Op.getNumOperands() % 2) == 0 ) { - llvm_unreachable("Do not know how to return this many arguments!"); - } - // Number of values to return - unsigned NumRet = (Op.getNumOperands() / 2); + unsigned NumRet = Outs.size(); // Function returns value always on stack with the offset starting // from 0 @@ -1288,68 +1263,13 @@ SDValue PIC16TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) { SDValue BS = DAG.getConstant(1, MVT::i8); SDValue RetVal; for(unsigned i=0;i<NumRet; ++i) { - RetVal = Op.getNode()->getOperand(2*i + 1); + RetVal = Outs[i].Val; Chain = DAG.getNode (PIC16ISD::PIC16Store, dl, MVT::Other, Chain, RetVal, ES, BS, DAG.getConstant (i, MVT::i8)); } - return DAG.getNode(ISD::RET, dl, MVT::Other, Chain); -} - -// CALL node may have some operands non-legal to PIC16. Generate new CALL -// node with all the operands legal. -// Currently only Callee operand of the CALL node is non-legal. This function -// legalizes the Callee operand and uses all other operands as are to generate -// new CALL node. - -SDValue PIC16TargetLowering::LegalizeCALL(SDValue Op, SelectionDAG &DAG) { - CallSDNode *TheCall = dyn_cast<CallSDNode>(Op); - SDValue Chain = TheCall->getChain(); - SDValue Callee = TheCall->getCallee(); - DebugLoc dl = TheCall->getDebugLoc(); - unsigned i =0; - - assert(Callee.getValueType() == MVT::i16 && - "Don't know how to legalize this call node!!!"); - assert(Callee.getOpcode() == ISD::BUILD_PAIR && - "Don't know how to legalize this call node!!!"); - - if (isDirectAddress(Callee)) { - // Come here for direct calls - Callee = Callee.getOperand(0).getOperand(0); - } else { - // Come here for indirect calls - SDValue Lo, Hi; - // Indirect addresses. Get the hi and lo parts of ptr. - GetExpandedParts(Callee, DAG, Lo, Hi); - // Connect Lo and Hi parts of the callee with the PIC16Connect - Callee = DAG.getNode(PIC16ISD::PIC16Connect, dl, MVT::i8, Lo, Hi); - } - std::vector<SDValue> Ops; - Ops.push_back(Chain); - Ops.push_back(Callee); - - // Add the call arguments and their flags - unsigned NumArgs = TheCall->getNumArgs(); - for(i=0;i<NumArgs;i++) { - Ops.push_back(TheCall->getArg(i)); - Ops.push_back(TheCall->getArgFlagsVal(i)); - } - std::vector<MVT> NodeTys; - unsigned NumRets = TheCall->getNumRetVals(); - for(i=0;i<NumRets;i++) - NodeTys.push_back(TheCall->getRetValType(i)); - - // Return a Chain as well - NodeTys.push_back(MVT::Other); - - SDVTList VTs = DAG.getVTList(&NodeTys[0], NodeTys.size()); - // Generate new call with all the operands legal - return DAG.getCall(TheCall->getCallingConv(), dl, - TheCall->isVarArg(), TheCall->isTailCall(), - TheCall->isInreg(), VTs, &Ops[0], Ops.size(), - TheCall->getNumFixedArgs()); + return DAG.getNode(PIC16ISD::RET, dl, MVT::Other, Chain); } void PIC16TargetLowering:: @@ -1414,36 +1334,40 @@ GetDataAddress(DebugLoc dl, SDValue Callee, SDValue &Chain, DataAddr_Hi = DAG.getNode(PIC16ISD::MTHI, dl, MVT::i8, Call, OperFlag); } +SDValue +PIC16TargetLowering::LowerCall(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, + bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { -SDValue PIC16TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { - CallSDNode *TheCall = dyn_cast<CallSDNode>(Op); - SDValue Chain = TheCall->getChain(); - SDValue Callee = TheCall->getCallee(); - DebugLoc dl = TheCall->getDebugLoc(); - if (Callee.getValueType() == MVT::i16 && - Callee.getOpcode() == ISD::BUILD_PAIR) { - // Control should come here only from TypeLegalizer for lowering - - // Legalize the non-legal arguments of call and return the - // new call with legal arguments. - return LegalizeCALL(Op, DAG); - } - // Control should come here from Legalize DAG. - // Here all the operands of CALL node should be legal. - - // If this is an indirect call then to pass the arguments - // and read the return value back, we need the data address - // of the function being called. - // To get the data address two more calls need to be made. + assert(Callee.getValueType() == MVT::i16 && + "Don't know how to legalize this call node!!!"); // The flag to track if this is a direct or indirect call. bool IsDirectCall = true; - unsigned RetVals = TheCall->getNumRetVals(); - unsigned NumArgs = TheCall->getNumArgs(); + unsigned RetVals = Ins.size(); + unsigned NumArgs = Outs.size(); SDValue DataAddr_Lo, DataAddr_Hi; - if (Callee.getOpcode() == PIC16ISD::PIC16Connect) { + if (!isa<GlobalAddressSDNode>(Callee) && + !isa<ExternalSymbolSDNode>(Callee)) { IsDirectCall = false; // This is indirect call + + // If this is an indirect call then to pass the arguments + // and read the return value back, we need the data address + // of the function being called. + // To get the data address two more calls need to be made. + + // Come here for indirect calls + SDValue Lo, Hi; + // Indirect addresses. Get the hi and lo parts of ptr. + GetExpandedParts(Callee, DAG, Lo, Hi); + // Connect Lo and Hi parts of the callee with the PIC16Connect + Callee = DAG.getNode(PIC16ISD::PIC16Connect, dl, MVT::i8, Lo, Hi); + // Read DataAddress only if we have to pass arguments or // read return value. if ((RetVals > 0) || (NumArgs > 0)) @@ -1499,12 +1423,13 @@ SDValue PIC16TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { // Pass the argument to function before making the call. SDValue CallArgs; if (IsDirectCall) { - CallArgs = LowerDirectCallArguments(Op, Chain, ArgLabel, OperFlag, DAG); + CallArgs = LowerDirectCallArguments(ArgLabel, Chain, OperFlag, + Outs, dl, DAG); Chain = getChain(CallArgs); OperFlag = getOutFlag(CallArgs); } else { - CallArgs = LowerIndirectCallArguments(Op, Chain, OperFlag, DataAddr_Lo, - DataAddr_Hi, DAG); + CallArgs = LowerIndirectCallArguments(Chain, OperFlag, DataAddr_Lo, + DataAddr_Hi, Outs, dl, DAG); Chain = getChain(CallArgs); OperFlag = getOutFlag(CallArgs); } @@ -1525,10 +1450,11 @@ SDValue PIC16TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { // Lower the return value reading after the call. if (IsDirectCall) - return LowerDirectCallReturn(Op, Chain, RetLabel, OperFlag, DAG); + return LowerDirectCallReturn(RetLabel, Chain, OperFlag, + Ins, dl, DAG, InVals); else - return LowerIndirectCallReturn(Op, Chain, OperFlag, DataAddr_Lo, - DataAddr_Hi, DAG); + return LowerIndirectCallReturn(Chain, OperFlag, DataAddr_Lo, + DataAddr_Hi, Ins, dl, DAG, InVals); } bool PIC16TargetLowering::isDirectLoad(const SDValue Op) { @@ -1660,17 +1586,19 @@ void PIC16TargetLowering::InitReservedFrameCount(const Function *F) { ReservedFrameCount = NumArgs + 1; } -// LowerFORMAL_ARGUMENTS - Argument values are loaded from the +// LowerFormalArguments - Argument values are loaded from the // <fname>.args + offset. All arguments are already broken to leaglized // types, so the offset just runs from 0 to NumArgVals - 1. -SDValue PIC16TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, - SelectionDAG &DAG) { - SmallVector<SDValue, 8> ArgValues; - unsigned NumArgVals = Op.getNode()->getNumValues() - 1; - DebugLoc dl = Op.getDebugLoc(); - SDValue Chain = Op.getOperand(0); // Formal arguments' chain - +SDValue +PIC16TargetLowering::LowerFormalArguments(SDValue Chain, + unsigned CallConv, + bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, + SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + unsigned NumArgVals = Ins.size(); // Get the callee's name to create the <fname>.args label to pass args. MachineFunction &MF = DAG.getMachineFunction(); @@ -1694,13 +1622,10 @@ SDValue PIC16TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, SDValue PICLoad = DAG.getNode(PIC16ISD::PIC16LdArg, dl, VTs, Chain, ES, BS, Offset); Chain = getChain(PICLoad); - ArgValues.push_back(PICLoad); + InVals.push_back(PICLoad); } - // Return a MERGE_VALUE node. - ArgValues.push_back(Op.getOperand(0)); - return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getNode()->getVTList(), - &ArgValues[0], ArgValues.size()).getValue(Op.getResNo()); + return Chain; } // Perform DAGCombine of PIC16Load. diff --git a/lib/Target/PIC16/PIC16ISelLowering.h b/lib/Target/PIC16/PIC16ISelLowering.h index 69cc270..1f3c59a 100644 --- a/lib/Target/PIC16/PIC16ISelLowering.h +++ b/lib/Target/PIC16/PIC16ISelLowering.h @@ -52,6 +52,7 @@ namespace llvm { SUBCC, // Compare for equality or inequality. SELECT_ICC, // Psuedo to be caught in schedular and expanded to brcond. BRCOND, // Conditional branch. + RET, // Return. Dummy }; @@ -82,32 +83,35 @@ namespace llvm { virtual const char *getTargetNodeName(unsigned Opcode) const; /// getSetCCResultType - Return the ISD::SETCC ValueType virtual MVT getSetCCResultType(MVT ValType) const; - SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG); SDValue LowerShift(SDValue Op, SelectionDAG &DAG); SDValue LowerMUL(SDValue Op, SelectionDAG &DAG); SDValue LowerADD(SDValue Op, SelectionDAG &DAG); SDValue LowerSUB(SDValue Op, SelectionDAG &DAG); SDValue LowerBinOp(SDValue Op, SelectionDAG &DAG); - SDValue LowerCALL(SDValue Op, SelectionDAG &DAG); - SDValue LowerRET(SDValue Op, SelectionDAG &DAG); // Call returns SDValue - LowerDirectCallReturn(SDValue Op, SDValue Chain, SDValue FrameAddress, - SDValue InFlag, SelectionDAG &DAG); + LowerDirectCallReturn(SDValue RetLabel, SDValue Chain, SDValue InFlag, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); SDValue - LowerIndirectCallReturn(SDValue Op, SDValue Chain, SDValue InFlag, - SDValue DataAddr_Lo, SDValue DataAddr_Hi, - SelectionDAG &DAG); + LowerIndirectCallReturn(SDValue Chain, SDValue InFlag, + SDValue DataAddr_Lo, SDValue DataAddr_Hi, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); // Call arguments SDValue - LowerDirectCallArguments(SDValue Op, SDValue Chain, SDValue FrameAddress, - SDValue InFlag, SelectionDAG &DAG); + LowerDirectCallArguments(SDValue ArgLabel, SDValue Chain, SDValue InFlag, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG); SDValue - LowerIndirectCallArguments(SDValue Op, SDValue Chain, SDValue InFlag, + LowerIndirectCallArguments(SDValue Chain, SDValue InFlag, SDValue DataAddr_Lo, SDValue DataAddr_Hi, - SelectionDAG &DAG); + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG); SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG); SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG); @@ -125,6 +129,28 @@ namespace llvm { SmallVectorImpl<SDValue> &Results, SelectionDAG &DAG); + virtual SDValue + LowerFormalArguments(SDValue Chain, + unsigned CallConv, + bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + virtual SDValue + LowerCall(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + virtual SDValue + LowerReturn(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG); + SDValue ExpandStore(SDNode *N, SelectionDAG &DAG); SDValue ExpandLoad(SDNode *N, SelectionDAG &DAG); SDValue ExpandGlobalAddress(SDNode *N, SelectionDAG &DAG); @@ -175,12 +201,6 @@ namespace llvm { void LegalizeFrameIndex(SDValue Op, SelectionDAG &DAG, SDValue &ES, int &Offset); - - // CALL node should have all legal operands only. Legalize all non-legal - // operands of CALL node and then return the new call will all operands - // legal. - SDValue LegalizeCALL(SDValue Op, SelectionDAG &DAG); - // For indirect calls data address of the callee frame need to be // extracted. This function fills the arguments DataAddr_Lo and // DataAddr_Hi with the address of the callee frame. diff --git a/lib/Target/PIC16/PIC16InstrInfo.td b/lib/Target/PIC16/PIC16InstrInfo.td index 5e925c2..250ca0a 100644 --- a/lib/Target/PIC16/PIC16InstrInfo.td +++ b/lib/Target/PIC16/PIC16InstrInfo.td @@ -115,6 +115,8 @@ def PIC16Brcond : SDNode<"PIC16ISD::BRCOND", SDT_PIC16Brcond, def PIC16Selecticc : SDNode<"PIC16ISD::SELECT_ICC", SDT_PIC16Selecticc, [SDNPInFlag]>; +def PIC16ret : SDNode<"PIC16ISD::RET", SDTNone, [SDNPHasChain]>; + //===----------------------------------------------------------------------===// // PIC16 Operand Definitions. //===----------------------------------------------------------------------===// @@ -493,7 +495,7 @@ def pagesel : // Return insn. let isTerminator = 1, isBarrier = 1, isReturn = 1 in def Return : - ControlFormat<0, (outs), (ins), "return", [(ret)]>; + ControlFormat<0, (outs), (ins), "return", [(PIC16ret)]>; //===----------------------------------------------------------------------===// // PIC16 Replacment Patterns. diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index 2db69ec..c2b1888 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -203,9 +203,6 @@ PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM) setOperationAction(ISD::ConstantPool, MVT::i64, Custom); setOperationAction(ISD::JumpTable, MVT::i64, Custom); - // RET must be custom lowered, to meet ABI requirements. - setOperationAction(ISD::RET , MVT::Other, Custom); - // TRAP is legal. setOperationAction(ISD::TRAP, MVT::Other, Legal); @@ -448,7 +445,6 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const { case PPCISD::MTFSB1: return "PPCISD::MTFSB1"; case PPCISD::FADDRTZ: return "PPCISD::FADDRTZ"; case PPCISD::MTFSF: return "PPCISD::MTFSF"; - case PPCISD::TAILCALL: return "PPCISD::TAILCALL"; case PPCISD::TC_RETURN: return "PPCISD::TC_RETURN"; } } @@ -1293,6 +1289,7 @@ SDValue PPCTargetLowering::LowerTRAMPOLINE(SDValue Op, SelectionDAG &DAG) { std::pair<SDValue, SDValue> CallResult = LowerCallTo(Chain, Op.getValueType().getTypeForMVT(), false, false, false, false, 0, CallingConv::C, false, + /*isReturnValueUsed=*/true, DAG.getExternalSymbol("__trampoline_setup", PtrVT), Args, DAG, dl); @@ -1472,9 +1469,8 @@ static const unsigned *GetFPR(const PPCSubtarget &Subtarget) { /// CalculateStackSlotSize - Calculates the size reserved for this argument on /// the stack. -static unsigned CalculateStackSlotSize(SDValue Arg, ISD::ArgFlagsTy Flags, +static unsigned CalculateStackSlotSize(MVT ArgVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize) { - MVT ArgVT = Arg.getValueType(); unsigned ArgSize = ArgVT.getSizeInBits()/8; if (Flags.isByVal()) ArgSize = Flags.getByValSize(); @@ -1484,13 +1480,30 @@ static unsigned CalculateStackSlotSize(SDValue Arg, ISD::ArgFlagsTy Flags, } SDValue -PPCTargetLowering::LowerFORMAL_ARGUMENTS_SVR4(SDValue Op, - SelectionDAG &DAG, - int &VarArgsFrameIndex, - int &VarArgsStackOffset, - unsigned &VarArgsNumGPR, - unsigned &VarArgsNumFPR, - const PPCSubtarget &Subtarget) { +PPCTargetLowering::LowerFormalArguments(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> + &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + if (PPCSubTarget.isSVR4ABI()) { + return LowerFormalArguments_SVR4(Chain, CallConv, isVarArg, Ins, + dl, DAG, InVals); + } else { + return LowerFormalArguments_Darwin(Chain, CallConv, isVarArg, Ins, + dl, DAG, InVals); + } +} + +SDValue +PPCTargetLowering::LowerFormalArguments_SVR4( + SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> + &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + // SVR4 ABI Stack Frame Layout: // +-----------------------------------+ // +--> | Back chain | @@ -1522,25 +1535,21 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_SVR4(SDValue Op, MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); - SmallVector<SDValue, 8> ArgValues; - SDValue Root = Op.getOperand(0); - bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0; - DebugLoc dl = Op.getDebugLoc(); MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); // Potential tail calls could cause overwriting of argument stack slots. - unsigned CC = MF.getFunction()->getCallingConv(); - bool isImmutable = !(PerformTailCallOpt && (CC==CallingConv::Fast)); + bool isImmutable = !(PerformTailCallOpt && (CallConv==CallingConv::Fast)); unsigned PtrByteSize = 4; // Assign locations to all of the incoming arguments. SmallVector<CCValAssign, 16> ArgLocs; - CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs, *DAG.getContext()); + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), ArgLocs, + *DAG.getContext()); // Reserve space for the linkage area on the stack. CCInfo.AllocateStack(PPCFrameInfo::getLinkageSize(false, false), PtrByteSize); - CCInfo.AnalyzeFormalArguments(Op.getNode(), CC_PPC_SVR4); + CCInfo.AnalyzeFormalArguments(Ins, CC_PPC_SVR4); for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { CCValAssign &VA = ArgLocs[i]; @@ -1552,7 +1561,7 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_SVR4(SDValue Op, switch (ValVT.getSimpleVT()) { default: - llvm_unreachable("ValVT not supported by FORMAL_ARGUMENTS Lowering"); + llvm_unreachable("ValVT not supported by formal arguments Lowering"); case MVT::i32: RC = PPC::GPRCRegisterClass; break; @@ -1572,9 +1581,9 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_SVR4(SDValue Op, // Transform the arguments stored in physical registers into virtual ones. unsigned Reg = MF.addLiveIn(VA.getLocReg(), RC); - SDValue ArgValue = DAG.getCopyFromReg(Root, dl, Reg, ValVT); + SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, ValVT); - ArgValues.push_back(ArgValue); + InVals.push_back(ArgValue); } else { // Argument stored in memory. assert(VA.isMemLoc()); @@ -1585,7 +1594,7 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_SVR4(SDValue Op, // Create load nodes to retrieve arguments from the stack. SDValue FIN = DAG.getFrameIndex(FI, PtrVT); - ArgValues.push_back(DAG.getLoad(VA.getValVT(), dl, Root, FIN, NULL, 0)); + InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN, NULL, 0)); } } @@ -1593,13 +1602,13 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_SVR4(SDValue Op, // Aggregates passed by value are stored in the local variable space of the // caller's stack frame, right above the parameter list area. SmallVector<CCValAssign, 16> ByValArgLocs; - CCState CCByValInfo(CC, isVarArg, getTargetMachine(), + CCState CCByValInfo(CallConv, isVarArg, getTargetMachine(), ByValArgLocs, *DAG.getContext()); // Reserve stack space for the allocations in CCInfo. CCByValInfo.AllocateStack(CCInfo.getNextStackOffset(), PtrByteSize); - CCByValInfo.AnalyzeFormalArguments(Op.getNode(), CC_PPC_SVR4_ByVal); + CCByValInfo.AnalyzeFormalArguments(Ins, CC_PPC_SVR4_ByVal); // Area that is at least reserved in the caller of this function. unsigned MinReservedArea = CCByValInfo.getNextStackOffset(); @@ -1656,7 +1665,7 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_SVR4(SDValue Op, unsigned GPRIndex = 0; for (; GPRIndex != VarArgsNumGPR; ++GPRIndex) { SDValue Val = DAG.getRegister(GPArgRegs[GPRIndex], PtrVT); - SDValue Store = DAG.getStore(Root, dl, Val, FIN, NULL, 0); + SDValue Store = DAG.getStore(Chain, dl, Val, FIN, NULL, 0); MemOps.push_back(Store); // Increment the address by four for the next argument to store SDValue PtrOff = DAG.getConstant(PtrVT.getSizeInBits()/8, PtrVT); @@ -1669,7 +1678,7 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_SVR4(SDValue Op, for (; GPRIndex != NumGPArgRegs; ++GPRIndex) { unsigned VReg = MF.addLiveIn(GPArgRegs[GPRIndex], &PPC::GPRCRegClass); - SDValue Val = DAG.getCopyFromReg(Root, dl, VReg, PtrVT); + SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, PtrVT); SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0); MemOps.push_back(Store); // Increment the address by four for the next argument to store @@ -1685,7 +1694,7 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_SVR4(SDValue Op, unsigned FPRIndex = 0; for (FPRIndex = 0; FPRIndex != VarArgsNumFPR; ++FPRIndex) { SDValue Val = DAG.getRegister(FPArgRegs[FPRIndex], MVT::f64); - SDValue Store = DAG.getStore(Root, dl, Val, FIN, NULL, 0); + SDValue Store = DAG.getStore(Chain, dl, Val, FIN, NULL, 0); MemOps.push_back(Store); // Increment the address by eight for the next argument to store SDValue PtrOff = DAG.getConstant(MVT(MVT::f64).getSizeInBits()/8, @@ -1696,7 +1705,7 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_SVR4(SDValue Op, for (; FPRIndex != NumFPArgRegs; ++FPRIndex) { unsigned VReg = MF.addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass); - SDValue Val = DAG.getCopyFromReg(Root, dl, VReg, MVT::f64); + SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::f64); SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0); MemOps.push_back(Store); // Increment the address by eight for the next argument to store @@ -1707,36 +1716,30 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_SVR4(SDValue Op, } if (!MemOps.empty()) - Root = DAG.getNode(ISD::TokenFactor, dl, - MVT::Other, &MemOps[0], MemOps.size()); + Chain = DAG.getNode(ISD::TokenFactor, dl, + MVT::Other, &MemOps[0], MemOps.size()); - - ArgValues.push_back(Root); - - // Return the new list of results. - return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getNode()->getVTList(), - &ArgValues[0], ArgValues.size()).getValue(Op.getResNo()); + return Chain; } SDValue -PPCTargetLowering::LowerFORMAL_ARGUMENTS_Darwin(SDValue Op, - SelectionDAG &DAG, - int &VarArgsFrameIndex, - const PPCSubtarget &Subtarget) { +PPCTargetLowering::LowerFormalArguments_Darwin( + SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> + &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + // TODO: add description of PPC stack frame format, or at least some docs. // MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); - SmallVector<SDValue, 8> ArgValues; - SDValue Root = Op.getOperand(0); - bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0; - DebugLoc dl = Op.getDebugLoc(); MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); bool isPPC64 = PtrVT == MVT::i64; // Potential tail calls could cause overwriting of argument stack slots. - unsigned CC = MF.getFunction()->getCallingConv(); - bool isImmutable = !(PerformTailCallOpt && (CC==CallingConv::Fast)); + bool isImmutable = !(PerformTailCallOpt && (CallConv==CallingConv::Fast)); unsigned PtrByteSize = isPPC64 ? 8 : 4; unsigned ArgOffset = PPCFrameInfo::getLinkageSize(isPPC64, true); @@ -1752,7 +1755,7 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_Darwin(SDValue Op, PPC::X7, PPC::X8, PPC::X9, PPC::X10, }; - static const unsigned *FPR = GetFPR(Subtarget); + static const unsigned *FPR = GetFPR(PPCSubTarget); static const unsigned VR[] = { PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8, @@ -1776,12 +1779,11 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_Darwin(SDValue Op, // entire point of the following loop. unsigned VecArgOffset = ArgOffset; if (!isVarArg && !isPPC64) { - for (unsigned ArgNo = 0, e = Op.getNode()->getNumValues()-1; ArgNo != e; + for (unsigned ArgNo = 0, e = Ins.size(); ArgNo != e; ++ArgNo) { - MVT ObjectVT = Op.getValue(ArgNo).getValueType(); + MVT ObjectVT = Ins[ArgNo].VT; unsigned ObjSize = ObjectVT.getSizeInBits()/8; - ISD::ArgFlagsTy Flags = - cast<ARG_FLAGSSDNode>(Op.getOperand(ArgNo+3))->getArgFlags(); + ISD::ArgFlagsTy Flags = Ins[ArgNo].Flags; if (Flags.isByVal()) { // ObjSize is the true size, ArgSize rounded up to multiple of regs. @@ -1822,15 +1824,13 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_Darwin(SDValue Op, SmallVector<SDValue, 8> MemOps; unsigned nAltivecParamsAtEnd = 0; - for (unsigned ArgNo = 0, e = Op.getNode()->getNumValues() - 1; - ArgNo != e; ++ArgNo) { + for (unsigned ArgNo = 0, e = Ins.size(); ArgNo != e; ++ArgNo) { SDValue ArgVal; bool needsLoad = false; - MVT ObjectVT = Op.getValue(ArgNo).getValueType(); + MVT ObjectVT = Ins[ArgNo].VT; unsigned ObjSize = ObjectVT.getSizeInBits()/8; unsigned ArgSize = ObjSize; - ISD::ArgFlagsTy Flags = - cast<ARG_FLAGSSDNode>(Op.getOperand(ArgNo+3))->getArgFlags(); + ISD::ArgFlagsTy Flags = Ins[ArgNo].Flags; unsigned CurArgOffset = ArgOffset; @@ -1839,13 +1839,13 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_Darwin(SDValue Op, ObjectVT==MVT::v8i16 || ObjectVT==MVT::v16i8) { if (isVarArg || isPPC64) { MinReservedArea = ((MinReservedArea+15)/16)*16; - MinReservedArea += CalculateStackSlotSize(Op.getValue(ArgNo), + MinReservedArea += CalculateStackSlotSize(ObjectVT, Flags, PtrByteSize); } else nAltivecParamsAtEnd++; } else // Calculate min reserved area. - MinReservedArea += CalculateStackSlotSize(Op.getValue(ArgNo), + MinReservedArea += CalculateStackSlotSize(Ins[ArgNo].VT, Flags, PtrByteSize); @@ -1863,11 +1863,11 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_Darwin(SDValue Op, // The value of the object is its address. int FI = MFI->CreateFixedObject(ObjSize, CurArgOffset); SDValue FIN = DAG.getFrameIndex(FI, PtrVT); - ArgValues.push_back(FIN); + InVals.push_back(FIN); if (ObjSize==1 || ObjSize==2) { if (GPR_idx != Num_GPR_Regs) { unsigned VReg = MF.addLiveIn(GPR[GPR_idx], &PPC::GPRCRegClass); - SDValue Val = DAG.getCopyFromReg(Root, dl, VReg, PtrVT); + SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, PtrVT); SDValue Store = DAG.getTruncStore(Val.getValue(1), dl, Val, FIN, NULL, 0, ObjSize==1 ? MVT::i8 : MVT::i16 ); MemOps.push_back(Store); @@ -1886,7 +1886,7 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_Darwin(SDValue Op, unsigned VReg = MF.addLiveIn(GPR[GPR_idx], &PPC::GPRCRegClass); int FI = MFI->CreateFixedObject(PtrByteSize, ArgOffset); SDValue FIN = DAG.getFrameIndex(FI, PtrVT); - SDValue Val = DAG.getCopyFromReg(Root, dl, VReg, PtrVT); + SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, PtrVT); SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0); MemOps.push_back(Store); ++GPR_idx; @@ -1905,7 +1905,7 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_Darwin(SDValue Op, if (!isPPC64) { if (GPR_idx != Num_GPR_Regs) { unsigned VReg = MF.addLiveIn(GPR[GPR_idx], &PPC::GPRCRegClass); - ArgVal = DAG.getCopyFromReg(Root, dl, VReg, MVT::i32); + ArgVal = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32); ++GPR_idx; } else { needsLoad = true; @@ -1919,7 +1919,7 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_Darwin(SDValue Op, case MVT::i64: // PPC64 if (GPR_idx != Num_GPR_Regs) { unsigned VReg = MF.addLiveIn(GPR[GPR_idx], &PPC::G8RCRegClass); - ArgVal = DAG.getCopyFromReg(Root, dl, VReg, MVT::i64); + ArgVal = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i64); if (ObjectVT == MVT::i32) { // PPC64 passes i8, i16, and i32 values in i64 registers. Promote @@ -1960,7 +1960,7 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_Darwin(SDValue Op, else VReg = MF.addLiveIn(FPR[FPR_idx], &PPC::F8RCRegClass); - ArgVal = DAG.getCopyFromReg(Root, dl, VReg, ObjectVT); + ArgVal = DAG.getCopyFromReg(Chain, dl, VReg, ObjectVT); ++FPR_idx; } else { needsLoad = true; @@ -1977,7 +1977,7 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_Darwin(SDValue Op, // except in varargs functions. if (VR_idx != Num_VR_Regs) { unsigned VReg = MF.addLiveIn(VR[VR_idx], &PPC::VRRCRegClass); - ArgVal = DAG.getCopyFromReg(Root, dl, VReg, ObjectVT); + ArgVal = DAG.getCopyFromReg(Chain, dl, VReg, ObjectVT); if (isVarArg) { while ((ArgOffset % 16) != 0) { ArgOffset += PtrByteSize; @@ -2011,10 +2011,10 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_Darwin(SDValue Op, CurArgOffset + (ArgSize - ObjSize), isImmutable); SDValue FIN = DAG.getFrameIndex(FI, PtrVT); - ArgVal = DAG.getLoad(ObjectVT, dl, Root, FIN, NULL, 0); + ArgVal = DAG.getLoad(ObjectVT, dl, Chain, FIN, NULL, 0); } - ArgValues.push_back(ArgVal); + InVals.push_back(ArgVal); } // Set the size that is at least reserved in caller of this function. Tail @@ -2056,7 +2056,7 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_Darwin(SDValue Op, else VReg = MF.addLiveIn(GPR[GPR_idx], &PPC::GPRCRegClass); - SDValue Val = DAG.getCopyFromReg(Root, dl, VReg, PtrVT); + SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, PtrVT); SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0); MemOps.push_back(Store); // Increment the address by four for the next argument to store @@ -2066,14 +2066,10 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_Darwin(SDValue Op, } if (!MemOps.empty()) - Root = DAG.getNode(ISD::TokenFactor, dl, - MVT::Other, &MemOps[0], MemOps.size()); - - ArgValues.push_back(Root); + Chain = DAG.getNode(ISD::TokenFactor, dl, + MVT::Other, &MemOps[0], MemOps.size()); - // Return the new list of results. - return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getNode()->getVTList(), - &ArgValues[0], ArgValues.size()); + return Chain; } /// CalculateParameterAndLinkageAreaSize - Get the size of the paramter plus @@ -2083,13 +2079,14 @@ CalculateParameterAndLinkageAreaSize(SelectionDAG &DAG, bool isPPC64, bool isVarArg, unsigned CC, - CallSDNode *TheCall, + const SmallVectorImpl<ISD::OutputArg> + &Outs, 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, true); - unsigned NumOps = TheCall->getNumArgs(); + unsigned NumOps = Outs.size(); unsigned PtrByteSize = isPPC64 ? 8 : 4; // Add up all the space actually used. @@ -2100,8 +2097,8 @@ CalculateParameterAndLinkageAreaSize(SelectionDAG &DAG, // 16-byte aligned. nAltivecParamsAtEnd = 0; for (unsigned i = 0; i != NumOps; ++i) { - SDValue Arg = TheCall->getArg(i); - ISD::ArgFlagsTy Flags = TheCall->getArgFlags(i); + SDValue Arg = Outs[i].Val; + ISD::ArgFlagsTy Flags = Outs[i].Flags; MVT ArgVT = Arg.getValueType(); // Varargs Altivec parameters are padded to a 16 byte boundary. if (ArgVT==MVT::v4f32 || ArgVT==MVT::v4i32 || @@ -2115,7 +2112,7 @@ CalculateParameterAndLinkageAreaSize(SelectionDAG &DAG, // Varargs and 64-bit Altivec parameters are padded to 16 byte boundary. NumBytes = ((NumBytes+15)/16)*16; } - NumBytes += CalculateStackSlotSize(Arg, Flags, PtrByteSize); + NumBytes += CalculateStackSlotSize(ArgVT, Flags, PtrByteSize); } // Allow for Altivec parameters at the end, if needed. @@ -2160,40 +2157,37 @@ static int CalculateTailCallSPDiff(SelectionDAG& DAG, bool IsTailCall, return SPDiff; } -/// IsEligibleForTailCallElimination - Check to see whether the next instruction -/// 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. +/// IsEligibleForTailCallOptimization - Check whether the call is eligible +/// for tail call optimization. Targets which want to do tail call +/// optimization should implement this function. bool -PPCTargetLowering::IsEligibleForTailCallOptimization(CallSDNode *TheCall, - SDValue Ret, +PPCTargetLowering::IsEligibleForTailCallOptimization(SDValue Callee, + unsigned CalleeCC, + bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, SelectionDAG& DAG) const { // Variable argument functions are not supported. - if (!PerformTailCallOpt || TheCall->isVarArg()) + if (isVarArg) return false; - if (CheckTailCallReturnConstraints(TheCall, Ret)) { - MachineFunction &MF = DAG.getMachineFunction(); - unsigned CallerCC = MF.getFunction()->getCallingConv(); - unsigned CalleeCC = TheCall->getCallingConv(); - if (CalleeCC == CallingConv::Fast && CallerCC == CalleeCC) { - // Functions containing by val parameters are not supported. - for (unsigned i = 0; i != TheCall->getNumArgs(); i++) { - ISD::ArgFlagsTy Flags = TheCall->getArgFlags(i); - if (Flags.isByVal()) return false; - } + MachineFunction &MF = DAG.getMachineFunction(); + unsigned CallerCC = MF.getFunction()->getCallingConv(); + if (CalleeCC == CallingConv::Fast && CallerCC == CalleeCC) { + // Functions containing by val parameters are not supported. + for (unsigned i = 0; i != Ins.size(); i++) { + ISD::ArgFlagsTy Flags = Ins[i].Flags; + if (Flags.isByVal()) return false; + } - SDValue Callee = TheCall->getCallee(); - // Non PIC/GOT tail calls are supported. - if (getTargetMachine().getRelocationModel() != Reloc::PIC_) - return true; + // Non PIC/GOT tail calls are supported. + if (getTargetMachine().getRelocationModel() != Reloc::PIC_) + return true; - // At the moment we can only do local tail calls (in same module, hidden - // or protected) if we are generating PIC. - if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) - return G->getGlobal()->hasHiddenVisibility() - || G->getGlobal()->hasProtectedVisibility(); - } + // At the moment we can only do local tail calls (in same module, hidden + // or protected) if we are generating PIC. + if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) + return G->getGlobal()->hasHiddenVisibility() + || G->getGlobal()->hasProtectedVisibility(); } return false; @@ -2455,16 +2449,17 @@ unsigned PrepareCall(SelectionDAG &DAG, SDValue &Callee, SDValue &InFlag, return CallOpc; } -static SDValue LowerCallReturn(SDValue Op, SelectionDAG &DAG, TargetMachine &TM, - CallSDNode *TheCall, SDValue Chain, - SDValue InFlag) { - bool isVarArg = TheCall->isVarArg(); - DebugLoc dl = TheCall->getDebugLoc(); - SmallVector<SDValue, 16> ResultVals; +SDValue +PPCTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + SmallVector<CCValAssign, 16> RVLocs; - unsigned CallerCC = DAG.getMachineFunction().getFunction()->getCallingConv(); - CCState CCRetInfo(CallerCC, isVarArg, TM, RVLocs, *DAG.getContext()); - CCRetInfo.AnalyzeCallResult(TheCall, RetCC_PPC); + CCState CCRetInfo(CallConv, isVarArg, getTargetMachine(), + RVLocs, *DAG.getContext()); + CCRetInfo.AnalyzeCallResult(Ins, RetCC_PPC); // Copy all of the result registers out of their specified physreg. for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) { @@ -2473,53 +2468,61 @@ static SDValue LowerCallReturn(SDValue Op, SelectionDAG &DAG, TargetMachine &TM, assert(VA.isRegLoc() && "Can only return in registers!"); Chain = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), VT, InFlag).getValue(1); - ResultVals.push_back(Chain.getValue(0)); + InVals.push_back(Chain.getValue(0)); InFlag = Chain.getValue(2); } - // If the function returns void, just return the chain. - if (RVLocs.empty()) - return Chain; - - // Otherwise, merge everything together with a MERGE_VALUES node. - ResultVals.push_back(Chain); - SDValue Res = DAG.getNode(ISD::MERGE_VALUES, dl, TheCall->getVTList(), - &ResultVals[0], ResultVals.size()); - return Res.getValue(Op.getResNo()); + return Chain; } -static -SDValue FinishCall(SelectionDAG &DAG, CallSDNode *TheCall, TargetMachine &TM, - SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass, - SDValue Op, SDValue InFlag, SDValue Chain, SDValue &Callee, - int SPDiff, unsigned NumBytes) { - unsigned CC = TheCall->getCallingConv(); - DebugLoc dl = TheCall->getDebugLoc(); - bool isTailCall = TheCall->isTailCall() - && CC == CallingConv::Fast && PerformTailCallOpt; +SDValue +PPCTargetLowering::FinishCall(unsigned CallConv, DebugLoc dl, bool isTailCall, + bool isVarArg, + SelectionDAG &DAG, + SmallVector<std::pair<unsigned, SDValue>, 8> + &RegsToPass, + SDValue InFlag, SDValue Chain, + SDValue &Callee, + int SPDiff, unsigned NumBytes, + const SmallVectorImpl<ISD::InputArg> &Ins, + SmallVectorImpl<SDValue> &InVals) { std::vector<MVT> NodeTys; SmallVector<SDValue, 8> Ops; unsigned CallOpc = PrepareCall(DAG, Callee, InFlag, Chain, dl, SPDiff, isTailCall, RegsToPass, Ops, NodeTys, - TM.getSubtarget<PPCSubtarget>().isSVR4ABI()); + PPCSubTarget.isSVR4ABI()); // When performing tail call optimization the callee pops its arguments off // the stack. Account for this here so these bytes can be pushed back on in // PPCRegisterInfo::eliminateCallFramePseudoInstr. int BytesCalleePops = - (CC==CallingConv::Fast && PerformTailCallOpt) ? NumBytes : 0; + (CallConv==CallingConv::Fast && PerformTailCallOpt) ? NumBytes : 0; if (InFlag.getNode()) Ops.push_back(InFlag); // Emit tail call. if (isTailCall) { - assert(InFlag.getNode() && - "Flag must be set. Depend on flag being set in LowerRET"); - Chain = DAG.getNode(PPCISD::TAILCALL, dl, - TheCall->getVTList(), &Ops[0], Ops.size()); - return SDValue(Chain.getNode(), Op.getResNo()); + // If this is the first return lowered for this function, add the regs + // to the liveout set for the function. + if (DAG.getMachineFunction().getRegInfo().liveout_empty()) { + SmallVector<CCValAssign, 16> RVLocs; + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), RVLocs, + *DAG.getContext()); + CCInfo.AnalyzeCallResult(Ins, RetCC_PPC); + for (unsigned i = 0; i != RVLocs.size(); ++i) + DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); + } + + assert(((Callee.getOpcode() == ISD::Register && + cast<RegisterSDNode>(Callee)->getReg() == PPC::CTR) || + Callee.getOpcode() == ISD::TargetExternalSymbol || + Callee.getOpcode() == ISD::TargetGlobalAddress || + isa<ConstantSDNode>(Callee)) && + "Expecting an global address, external symbol, absolute value or register"); + + return DAG.getNode(PPCISD::TC_RETURN, dl, MVT::Other, &Ops[0], Ops.size()); } Chain = DAG.getNode(CallOpc, dl, NodeTys, &Ops[0], Ops.size()); @@ -2528,27 +2531,49 @@ SDValue FinishCall(SelectionDAG &DAG, CallSDNode *TheCall, TargetMachine &TM, Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumBytes, true), DAG.getIntPtrConstant(BytesCalleePops, true), InFlag); - if (TheCall->getValueType(0) != MVT::Other) + if (!Ins.empty()) InFlag = Chain.getValue(1); - return LowerCallReturn(Op, DAG, TM, TheCall, Chain, InFlag); + return LowerCallResult(Chain, InFlag, CallConv, isVarArg, + Ins, dl, DAG, InVals); +} + +SDValue +PPCTargetLowering::LowerCall(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, + bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + if (PPCSubTarget.isSVR4ABI()) { + return LowerCall_SVR4(Chain, Callee, CallConv, isVarArg, + isTailCall, Outs, Ins, + dl, DAG, InVals); + } else { + return LowerCall_Darwin(Chain, Callee, CallConv, isVarArg, + isTailCall, Outs, Ins, + dl, DAG, InVals); + } } -SDValue PPCTargetLowering::LowerCALL_SVR4(SDValue Op, SelectionDAG &DAG, - const PPCSubtarget &Subtarget, - TargetMachine &TM) { - // See PPCTargetLowering::LowerFORMAL_ARGUMENTS_SVR4() for a description +SDValue +PPCTargetLowering::LowerCall_SVR4(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, + bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + // See PPCTargetLowering::LowerFormalArguments_SVR4() for a description // of the SVR4 ABI stack frame layout. - CallSDNode *TheCall = cast<CallSDNode>(Op.getNode()); - SDValue Chain = TheCall->getChain(); - bool isVarArg = TheCall->isVarArg(); - unsigned CC = TheCall->getCallingConv(); - assert((CC == CallingConv::C || - CC == CallingConv::Fast) && "Unknown calling convention!"); - bool isTailCall = TheCall->isTailCall() - && CC == CallingConv::Fast && PerformTailCallOpt; - SDValue Callee = TheCall->getCallee(); - DebugLoc dl = TheCall->getDebugLoc(); + + assert((!isTailCall || + (CallConv == CallingConv::Fast && PerformTailCallOpt)) && + "IsEligibleForTailCallOptimization missed a case!"); + + assert((CallConv == CallingConv::C || + CallConv == CallingConv::Fast) && "Unknown calling convention!"); MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); unsigned PtrByteSize = 4; @@ -2560,7 +2585,7 @@ SDValue PPCTargetLowering::LowerCALL_SVR4(SDValue Op, SelectionDAG &DAG, // and restoring the callers stack pointer in this functions epilog. This is // done because by tail calling the called function might overwrite the value // in this function's (MF) stack pointer stack slot 0(SP). - if (PerformTailCallOpt && CC==CallingConv::Fast) + if (PerformTailCallOpt && CallConv==CallingConv::Fast) MF.getInfo<PPCFunctionInfo>()->setHasFastCall(); // Count how many bytes are to be pushed on the stack, including the linkage @@ -2569,7 +2594,8 @@ SDValue PPCTargetLowering::LowerCALL_SVR4(SDValue Op, SelectionDAG &DAG, // Assign locations to all of the outgoing arguments. SmallVector<CCValAssign, 16> ArgLocs; - CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs, *DAG.getContext()); + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), + ArgLocs, *DAG.getContext()); // Reserve space for the linkage area on the stack. CCInfo.AllocateStack(PPCFrameInfo::getLinkageSize(false, false), PtrByteSize); @@ -2578,15 +2604,14 @@ SDValue PPCTargetLowering::LowerCALL_SVR4(SDValue Op, SelectionDAG &DAG, // Handle fixed and variable vector arguments differently. // Fixed vector arguments go into registers as long as registers are // available. Variable vector arguments always go into memory. - unsigned NumArgs = TheCall->getNumArgs(); - unsigned NumFixedArgs = TheCall->getNumFixedArgs(); + unsigned NumArgs = Outs.size(); for (unsigned i = 0; i != NumArgs; ++i) { - MVT ArgVT = TheCall->getArg(i).getValueType(); - ISD::ArgFlagsTy ArgFlags = TheCall->getArgFlags(i); + MVT ArgVT = Outs[i].Val.getValueType(); + ISD::ArgFlagsTy ArgFlags = Outs[i].Flags; bool Result; - if (i < NumFixedArgs) { + if (Outs[i].IsFixed) { Result = CC_PPC_SVR4(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, CCInfo); } else { @@ -2604,18 +2629,18 @@ SDValue PPCTargetLowering::LowerCALL_SVR4(SDValue Op, SelectionDAG &DAG, } } else { // All arguments are treated the same. - CCInfo.AnalyzeCallOperands(TheCall, CC_PPC_SVR4); + CCInfo.AnalyzeCallOperands(Outs, CC_PPC_SVR4); } // Assign locations to all of the outgoing aggregate by value arguments. SmallVector<CCValAssign, 16> ByValArgLocs; - CCState CCByValInfo(CC, isVarArg, getTargetMachine(), ByValArgLocs, + CCState CCByValInfo(CallConv, isVarArg, getTargetMachine(), ByValArgLocs, *DAG.getContext()); // Reserve stack space for the allocations in CCInfo. CCByValInfo.AllocateStack(CCInfo.getNextStackOffset(), PtrByteSize); - CCByValInfo.AnalyzeCallOperands(TheCall, CC_PPC_SVR4_ByVal); + CCByValInfo.AnalyzeCallOperands(Outs, CC_PPC_SVR4_ByVal); // Size of the linkage area, parameter list area and the part of the local // space variable where copies of aggregates which are passed by value are @@ -2651,8 +2676,8 @@ SDValue PPCTargetLowering::LowerCALL_SVR4(SDValue Op, SelectionDAG &DAG, i != e; ++i) { CCValAssign &VA = ArgLocs[i]; - SDValue Arg = TheCall->getArg(i); - ISD::ArgFlagsTy Flags = TheCall->getArgFlags(i); + SDValue Arg = Outs[i].Val; + ISD::ArgFlagsTy Flags = Outs[i].Flags; if (Flags.isByVal()) { // Argument is an aggregate which is passed by value, thus we need to @@ -2736,22 +2761,21 @@ SDValue PPCTargetLowering::LowerCALL_SVR4(SDValue Op, SelectionDAG &DAG, false, TailCallArguments); } - return FinishCall(DAG, TheCall, TM, RegsToPass, Op, InFlag, Chain, Callee, - SPDiff, NumBytes); + return FinishCall(CallConv, dl, isTailCall, isVarArg, DAG, + RegsToPass, InFlag, Chain, Callee, SPDiff, NumBytes, + Ins, InVals); } -SDValue PPCTargetLowering::LowerCALL_Darwin(SDValue Op, SelectionDAG &DAG, - const PPCSubtarget &Subtarget, - TargetMachine &TM) { - CallSDNode *TheCall = cast<CallSDNode>(Op.getNode()); - SDValue Chain = TheCall->getChain(); - bool isVarArg = TheCall->isVarArg(); - unsigned CC = TheCall->getCallingConv(); - bool isTailCall = TheCall->isTailCall() - && CC == CallingConv::Fast && PerformTailCallOpt; - SDValue Callee = TheCall->getCallee(); - unsigned NumOps = TheCall->getNumArgs(); - DebugLoc dl = TheCall->getDebugLoc(); +SDValue +PPCTargetLowering::LowerCall_Darwin(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, + bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + + unsigned NumOps = Outs.size(); MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); bool isPPC64 = PtrVT == MVT::i64; @@ -2764,7 +2788,7 @@ SDValue PPCTargetLowering::LowerCALL_Darwin(SDValue Op, SelectionDAG &DAG, // and restoring the callers stack pointer in this functions epilog. This is // done because by tail calling the called function might overwrite the value // in this function's (MF) stack pointer stack slot 0(SP). - if (PerformTailCallOpt && CC==CallingConv::Fast) + if (PerformTailCallOpt && CallConv==CallingConv::Fast) MF.getInfo<PPCFunctionInfo>()->setHasFastCall(); unsigned nAltivecParamsAtEnd = 0; @@ -2773,13 +2797,19 @@ SDValue PPCTargetLowering::LowerCALL_Darwin(SDValue Op, SelectionDAG &DAG, // area, and parameter passing area. We start with 24/48 bytes, which is // prereserved space for [SP][CR][LR][3 x unused]. unsigned NumBytes = - CalculateParameterAndLinkageAreaSize(DAG, isPPC64, isVarArg, CC, TheCall, + CalculateParameterAndLinkageAreaSize(DAG, isPPC64, isVarArg, CallConv, + Outs, nAltivecParamsAtEnd); // Calculate by how many bytes the stack has to be adjusted in case of tail // call optimization. int SPDiff = CalculateTailCallSPDiff(DAG, isTailCall, NumBytes); + // To protect arguments on the stack from being clobbered in a tail call, + // force all the loads to happen before doing any other lowering. + if (isTailCall) + Chain = DAG.getStackArgumentTokenFactor(Chain); + // Adjust the stack pointer for the new arguments... // These operations are automatically eliminated by the prolog/epilog pass Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumBytes, true)); @@ -2815,7 +2845,7 @@ SDValue PPCTargetLowering::LowerCALL_Darwin(SDValue Op, SelectionDAG &DAG, PPC::X3, PPC::X4, PPC::X5, PPC::X6, PPC::X7, PPC::X8, PPC::X9, PPC::X10, }; - static const unsigned *FPR = GetFPR(Subtarget); + static const unsigned *FPR = GetFPR(PPCSubTarget); static const unsigned VR[] = { PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8, @@ -2833,8 +2863,8 @@ SDValue PPCTargetLowering::LowerCALL_Darwin(SDValue Op, SelectionDAG &DAG, SmallVector<SDValue, 8> MemOpChains; for (unsigned i = 0; i != NumOps; ++i) { bool inMem = false; - SDValue Arg = TheCall->getArg(i); - ISD::ArgFlagsTy Flags = TheCall->getArgFlags(i); + SDValue Arg = Outs[i].Val; + ISD::ArgFlagsTy Flags = Outs[i].Flags; // PtrOff will be used to store the current argument to the stack if a // register cannot be found for it. @@ -3031,7 +3061,7 @@ SDValue PPCTargetLowering::LowerCALL_Darwin(SDValue Op, SelectionDAG &DAG, ArgOffset = ((ArgOffset+15)/16)*16; ArgOffset += 12*16; for (unsigned i = 0; i != NumOps; ++i) { - SDValue Arg = TheCall->getArg(i); + SDValue Arg = Outs[i].Val; MVT ArgType = Arg.getValueType(); if (ArgType==MVT::v4f32 || ArgType==MVT::v4i32 || ArgType==MVT::v8i16 || ArgType==MVT::v16i8) { @@ -3065,18 +3095,21 @@ SDValue PPCTargetLowering::LowerCALL_Darwin(SDValue Op, SelectionDAG &DAG, FPOp, true, TailCallArguments); } - return FinishCall(DAG, TheCall, TM, RegsToPass, Op, InFlag, Chain, Callee, - SPDiff, NumBytes); + return FinishCall(CallConv, dl, isTailCall, isVarArg, DAG, + RegsToPass, InFlag, Chain, Callee, SPDiff, NumBytes, + Ins, InVals); } -SDValue PPCTargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG, - TargetMachine &TM) { +SDValue +PPCTargetLowering::LowerReturn(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG) { + SmallVector<CCValAssign, 16> RVLocs; - unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv(); - bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg(); - DebugLoc dl = Op.getDebugLoc(); - CCState CCInfo(CC, isVarArg, TM, RVLocs, *DAG.getContext()); - CCInfo.AnalyzeReturn(Op.getNode(), RetCC_PPC); + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), + RVLocs, *DAG.getContext()); + CCInfo.AnalyzeReturn(Outs, RetCC_PPC); // If this is the first return lowered for this function, add the regs to the // liveout set for the function. @@ -3085,37 +3118,6 @@ SDValue PPCTargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG, DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); } - SDValue Chain = Op.getOperand(0); - - Chain = GetPossiblePreceedingTailCall(Chain, PPCISD::TAILCALL); - if (Chain.getOpcode() == PPCISD::TAILCALL) { - SDValue TailCall = Chain; - SDValue TargetAddress = TailCall.getOperand(1); - SDValue StackAdjustment = TailCall.getOperand(2); - - assert(((TargetAddress.getOpcode() == ISD::Register && - cast<RegisterSDNode>(TargetAddress)->getReg() == PPC::CTR) || - TargetAddress.getOpcode() == ISD::TargetExternalSymbol || - TargetAddress.getOpcode() == ISD::TargetGlobalAddress || - isa<ConstantSDNode>(TargetAddress)) && - "Expecting an global address, external symbol, absolute value or register"); - - assert(StackAdjustment.getOpcode() == ISD::Constant && - "Expecting a const value"); - - SmallVector<SDValue,8> Operands; - Operands.push_back(Chain.getOperand(0)); - Operands.push_back(TargetAddress); - Operands.push_back(StackAdjustment); - // Copy registers used by the call. Last operand is a flag so it is not - // copied. - for (unsigned i=3; i < TailCall.getNumOperands()-1; i++) { - Operands.push_back(Chain.getOperand(i)); - } - return DAG.getNode(PPCISD::TC_RETURN, dl, MVT::Other, &Operands[0], - Operands.size()); - } - SDValue Flag; // Copy the result values into the output registers. @@ -3123,7 +3125,7 @@ SDValue PPCTargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG, CCValAssign &VA = RVLocs[i]; assert(VA.isRegLoc() && "Can only return in registers!"); Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), - Op.getOperand(i*2+1), Flag); + Outs[i].Val, Flag); Flag = Chain.getValue(1); } @@ -4178,24 +4180,6 @@ SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { return LowerVAARG(Op, DAG, VarArgsFrameIndex, VarArgsStackOffset, VarArgsNumGPR, VarArgsNumFPR, PPCSubTarget); - case ISD::FORMAL_ARGUMENTS: - if (PPCSubTarget.isSVR4ABI()) { - return LowerFORMAL_ARGUMENTS_SVR4(Op, DAG, VarArgsFrameIndex, - VarArgsStackOffset, VarArgsNumGPR, - VarArgsNumFPR, PPCSubTarget); - } else { - return LowerFORMAL_ARGUMENTS_Darwin(Op, DAG, VarArgsFrameIndex, - PPCSubTarget); - } - - case ISD::CALL: - if (PPCSubTarget.isSVR4ABI()) { - return LowerCALL_SVR4(Op, DAG, PPCSubTarget, getTargetMachine()); - } else { - return LowerCALL_Darwin(Op, DAG, PPCSubTarget, getTargetMachine()); - } - - case ISD::RET: return LowerRET(Op, DAG, getTargetMachine()); case ISD::STACKRESTORE: return LowerSTACKRESTORE(Op, DAG, PPCSubTarget); case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG, PPCSubTarget); diff --git a/lib/Target/PowerPC/PPCISelLowering.h b/lib/Target/PowerPC/PPCISelLowering.h index a650db3..91a9ad8 100644 --- a/lib/Target/PowerPC/PPCISelLowering.h +++ b/lib/Target/PowerPC/PPCISelLowering.h @@ -160,8 +160,6 @@ namespace llvm { /// indexed. This is used to implement atomic operations. STCX, - /// TAILCALL - Indicates a tail call should be taken. - TAILCALL, /// TC_RETURN - A tail call return. /// operand #0 chain /// operand #1 callee (register or absolute) @@ -327,12 +325,12 @@ namespace llvm { /// the offset of the target addressing mode. virtual bool isLegalAddressImmediate(GlobalValue *GV) const; - /// IsEligibleForTailCallOptimization - Check whether the call is eligible - /// for tail call optimization. Targets which want to do tail call - /// optimization should implement this function. - virtual bool IsEligibleForTailCallOptimization(CallSDNode *TheCall, - SDValue Ret, - SelectionDAG &DAG) const; + virtual bool + IsEligibleForTailCallOptimization(SDValue Callee, + unsigned CalleeCC, + bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + SelectionDAG& DAG) const; virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const; @@ -370,20 +368,6 @@ namespace llvm { SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG, int VarArgsFrameIndex, int VarArgsStackOffset, unsigned VarArgsNumGPR, unsigned VarArgsNumFPR, const PPCSubtarget &Subtarget); - SDValue LowerFORMAL_ARGUMENTS_SVR4(SDValue Op, SelectionDAG &DAG, - int &VarArgsFrameIndex, - int &VarArgsStackOffset, - unsigned &VarArgsNumGPR, - unsigned &VarArgsNumFPR, - const PPCSubtarget &Subtarget); - SDValue LowerFORMAL_ARGUMENTS_Darwin(SDValue Op, SelectionDAG &DAG, - int &VarArgsFrameIndex, - const PPCSubtarget &Subtarget); - SDValue LowerCALL_Darwin(SDValue Op, SelectionDAG &DAG, - const PPCSubtarget &Subtarget, TargetMachine &TM); - SDValue LowerCALL_SVR4(SDValue Op, SelectionDAG &DAG, - const PPCSubtarget &Subtarget, TargetMachine &TM); - SDValue LowerRET(SDValue Op, SelectionDAG &DAG, TargetMachine &TM); SDValue LowerSTACKRESTORE(SDValue Op, SelectionDAG &DAG, const PPCSubtarget &Subtarget); SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG, @@ -400,6 +384,71 @@ namespace llvm { SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG); SDValue LowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG); SDValue LowerMUL(SDValue Op, SelectionDAG &DAG); + + SDValue LowerCallResult(SDValue Chain, SDValue InFlag, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + SDValue FinishCall(unsigned CallConv, DebugLoc dl, bool isTailCall, + bool isVarArg, + SelectionDAG &DAG, + SmallVector<std::pair<unsigned, SDValue>, 8> + &RegsToPass, + SDValue InFlag, SDValue Chain, + SDValue &Callee, + int SPDiff, unsigned NumBytes, + const SmallVectorImpl<ISD::InputArg> &Ins, + SmallVectorImpl<SDValue> &InVals); + + virtual SDValue + LowerFormalArguments(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + virtual SDValue + LowerCall(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + virtual SDValue + LowerReturn(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG); + + SDValue + LowerFormalArguments_Darwin(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + SDValue + LowerFormalArguments_SVR4(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + SDValue + LowerCall_Darwin(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + SDValue + LowerCall_SVR4(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); }; } diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td index 7af59a2..759cdf0 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.td +++ b/lib/Target/PowerPC/PPCInstrInfo.td @@ -125,9 +125,6 @@ def retflag : SDNode<"PPCISD::RET_FLAG", SDTNone, def PPCtc_return : SDNode<"PPCISD::TC_RETURN", SDT_PPCTC_ret, [SDNPHasChain, SDNPOptInFlag]>; -def PPCtailcall : SDNode<"PPCISD::TAILCALL", SDT_PPCCall, - [SDNPHasChain, SDNPOutFlag, SDNPOptInFlag]>; - def PPCvcmp : SDNode<"PPCISD::VCMP" , SDT_PPCvcmp, []>; def PPCvcmp_o : SDNode<"PPCISD::VCMPo", SDT_PPCvcmp, [SDNPOutFlag]>; diff --git a/lib/Target/Sparc/SparcISelLowering.cpp b/lib/Target/Sparc/SparcISelLowering.cpp index 16d9229..e3e45f6 100644 --- a/lib/Target/Sparc/SparcISelLowering.cpp +++ b/lib/Target/Sparc/SparcISelLowering.cpp @@ -33,18 +33,21 @@ using namespace llvm; #include "SparcGenCallingConv.inc" -static SDValue LowerRET(SDValue Op, SelectionDAG &DAG) { +SDValue +SparcTargetLowering::LowerReturn(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG) { + // CCValAssign - represent the assignment of the return value to locations. SmallVector<CCValAssign, 16> RVLocs; - unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv(); - bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg(); - DebugLoc dl = Op.getDebugLoc(); // CCState - Info about the registers and stack slot. - CCState CCInfo(CC, isVarArg, DAG.getTarget(), RVLocs, *DAG.getContext()); + CCState CCInfo(CallConv, isVarArg, DAG.getTarget(), + RVLocs, *DAG.getContext()); - // Analize return values of ISD::RET - CCInfo.AnalyzeReturn(Op.getNode(), RetCC_Sparc32); + // Analize return values. + CCInfo.AnalyzeReturn(Outs, RetCC_Sparc32); // If this is the first return lowered for this function, add the regs to the // liveout set for the function. @@ -54,7 +57,6 @@ static SDValue LowerRET(SDValue Op, SelectionDAG &DAG) { DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); } - SDValue Chain = Op.getOperand(0); SDValue Flag; // Copy the result values into the output registers. @@ -62,10 +64,8 @@ static SDValue LowerRET(SDValue Op, SelectionDAG &DAG) { CCValAssign &VA = RVLocs[i]; assert(VA.isRegLoc() && "Can only return in registers!"); - // ISD::RET => ret chain, (regnum1,val1), ... - // So i*2+1 index only the regnums. Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), - Op.getOperand(i*2+1), Flag); + Outs[i].Val, Flag); // Guarantee that all emitted copies are stuck together with flags. Flag = Chain.getValue(1); @@ -76,23 +76,25 @@ static SDValue LowerRET(SDValue Op, SelectionDAG &DAG) { return DAG.getNode(SPISD::RET_FLAG, dl, MVT::Other, Chain); } -/// LowerArguments - V8 uses a very simple ABI, where all values are passed in -/// either one or two GPRs, including FP values. TODO: we should pass FP values -/// in FP registers for fastcc functions. +/// LowerFormalArguments - V8 uses a very simple ABI, where all values are +/// passed in either one or two GPRs, including FP values. TODO: we should +/// pass FP values in FP registers for fastcc functions. SDValue -SparcTargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, - SelectionDAG &DAG) { +SparcTargetLowering::LowerFormalArguments(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> + &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + MachineFunction &MF = DAG.getMachineFunction(); MachineRegisterInfo &RegInfo = MF.getRegInfo(); - SDValue Root = Op.getOperand(0); - bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0; - unsigned CC = MF.getFunction()->getCallingConv(); - DebugLoc dl = Op.getDebugLoc(); // Assign locations to all of the incoming arguments. SmallVector<CCValAssign, 16> ArgLocs; - CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs, *DAG.getContext()); - CCInfo.AnalyzeFormalArguments(Op.getNode(), CC_Sparc32); + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), + ArgLocs, *DAG.getContext()); + CCInfo.AnalyzeFormalArguments(Ins, CC_Sparc32); static const unsigned ArgRegs[] = { SP::I0, SP::I1, SP::I2, SP::I3, SP::I4, SP::I5 @@ -100,7 +102,6 @@ SparcTargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, const unsigned *CurArgReg = ArgRegs, *ArgRegEnd = ArgRegs+6; unsigned ArgOffset = 68; - SmallVector<SDValue, 16> ArgValues; for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { SDValue ArgValue; CCValAssign &VA = ArgLocs[i]; @@ -113,23 +114,26 @@ SparcTargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, case MVT::i8: case MVT::i16: case MVT::i32: - if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR + if (!Ins[i].Used) { // Argument is dead. + if (CurArgReg < ArgRegEnd) ++CurArgReg; + InVals.push_back(DAG.getUNDEF(ObjectVT)); + } else if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR unsigned VReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass); MF.getRegInfo().addLiveIn(*CurArgReg++, VReg); - SDValue Arg = DAG.getCopyFromReg(Root, dl, VReg, MVT::i32); + SDValue Arg = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32); if (ObjectVT != MVT::i32) { unsigned AssertOp = ISD::AssertSext; Arg = DAG.getNode(AssertOp, dl, MVT::i32, Arg, DAG.getValueType(ObjectVT)); Arg = DAG.getNode(ISD::TRUNCATE, dl, ObjectVT, Arg); } - ArgValues.push_back(Arg); + InVals.push_back(Arg); } else { int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset); SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32); SDValue Load; if (ObjectVT == MVT::i32) { - Load = DAG.getLoad(MVT::i32, dl, Root, FIPtr, NULL, 0); + Load = DAG.getLoad(MVT::i32, dl, Chain, FIPtr, NULL, 0); } else { ISD::LoadExtType LoadOp = ISD::SEXTLOAD; @@ -137,56 +141,63 @@ SparcTargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, unsigned Offset = 4-std::max(1U, ObjectVT.getSizeInBits()/8); FIPtr = DAG.getNode(ISD::ADD, dl, MVT::i32, FIPtr, DAG.getConstant(Offset, MVT::i32)); - Load = DAG.getExtLoad(LoadOp, dl, MVT::i32, Root, FIPtr, + Load = DAG.getExtLoad(LoadOp, dl, MVT::i32, Chain, FIPtr, NULL, 0, ObjectVT); Load = DAG.getNode(ISD::TRUNCATE, dl, ObjectVT, Load); } - ArgValues.push_back(Load); + InVals.push_back(Load); } ArgOffset += 4; break; case MVT::f32: - if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR + if (!Ins[i].Used) { // Argument is dead. + if (CurArgReg < ArgRegEnd) ++CurArgReg; + InVals.push_back(DAG.getUNDEF(ObjectVT)); + } else if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR // FP value is passed in an integer register. unsigned VReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass); MF.getRegInfo().addLiveIn(*CurArgReg++, VReg); - SDValue Arg = DAG.getCopyFromReg(Root, dl, VReg, MVT::i32); + SDValue Arg = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32); Arg = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, Arg); - ArgValues.push_back(Arg); + InVals.push_back(Arg); } else { int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset); SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32); - SDValue Load = DAG.getLoad(MVT::f32, dl, Root, FIPtr, NULL, 0); - ArgValues.push_back(Load); + SDValue Load = DAG.getLoad(MVT::f32, dl, Chain, FIPtr, NULL, 0); + InVals.push_back(Load); } ArgOffset += 4; break; case MVT::i64: case MVT::f64: - { + if (!Ins[i].Used) { // Argument is dead. + if (CurArgReg < ArgRegEnd) ++CurArgReg; + if (CurArgReg < ArgRegEnd) ++CurArgReg; + InVals.push_back(DAG.getUNDEF(ObjectVT)); + } else { SDValue HiVal; if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR unsigned VRegHi = RegInfo.createVirtualRegister(&SP::IntRegsRegClass); MF.getRegInfo().addLiveIn(*CurArgReg++, VRegHi); - HiVal = DAG.getCopyFromReg(Root, dl, VRegHi, MVT::i32); + HiVal = DAG.getCopyFromReg(Chain, dl, VRegHi, MVT::i32); } else { int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset); SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32); - HiVal = DAG.getLoad(MVT::i32, dl, Root, FIPtr, NULL, 0); + HiVal = DAG.getLoad(MVT::i32, dl, Chain, FIPtr, NULL, 0); } SDValue LoVal; if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR unsigned VRegLo = RegInfo.createVirtualRegister(&SP::IntRegsRegClass); MF.getRegInfo().addLiveIn(*CurArgReg++, VRegLo); - LoVal = DAG.getCopyFromReg(Root, dl, VRegLo, MVT::i32); + LoVal = DAG.getCopyFromReg(Chain, dl, VRegLo, MVT::i32); } else { int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset+4); SDValue FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32); - LoVal = DAG.getLoad(MVT::i32, dl, Root, FIPtr, NULL, 0); + LoVal = DAG.getLoad(MVT::i32, dl, Chain, FIPtr, NULL, 0); } // Compose the two halves together into an i64 unit. @@ -197,7 +208,7 @@ SparcTargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, if (ObjectVT == MVT::f64) WholeValue = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f64, WholeValue); - ArgValues.push_back(WholeValue); + InVals.push_back(WholeValue); } ArgOffset += 8; break; @@ -224,32 +235,29 @@ SparcTargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, } if (!OutChains.empty()) { - OutChains.push_back(Root); - Root = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, - &OutChains[0], OutChains.size()); + OutChains.push_back(Chain); + Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, + &OutChains[0], OutChains.size()); } } - ArgValues.push_back(Root); - - // Return the new list of results. - return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getNode()->getVTList(), - &ArgValues[0], ArgValues.size()).getValue(Op.getResNo()); + return Chain; } -static SDValue LowerCALL(SDValue Op, SelectionDAG &DAG) { - CallSDNode *TheCall = cast<CallSDNode>(Op.getNode()); - unsigned CallingConv = TheCall->getCallingConv(); - SDValue Chain = TheCall->getChain(); - SDValue Callee = TheCall->getCallee(); - bool isVarArg = TheCall->isVarArg(); - DebugLoc dl = TheCall->getDebugLoc(); +SDValue +SparcTargetLowering::LowerCall(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, + bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { #if 0 // Analyze operands of the call, assigning locations to each operand. SmallVector<CCValAssign, 16> ArgLocs; - CCState CCInfo(CallingConv, isVarArg, DAG.getTarget(), ArgLocs); - CCInfo.AnalyzeCallOperands(Op.getNode(), CC_Sparc32); + CCState CCInfo(CallConv, isVarArg, DAG.getTarget(), ArgLocs); + CCInfo.AnalyzeCallOperands(Outs, CC_Sparc32); // Get the size of the outgoing arguments stack space requirement. unsigned ArgsSize = CCInfo.getNextStackOffset(); @@ -259,8 +267,8 @@ static SDValue LowerCALL(SDValue Op, SelectionDAG &DAG) { // Count the size of the outgoing arguments. unsigned ArgsSize = 0; - for (unsigned i = 0, e = TheCall->getNumArgs(); i != e; ++i) { - switch (TheCall->getArg(i).getValueType().getSimpleVT()) { + for (unsigned i = 0, e = Outs.size(); i != e; ++i) { + switch (Outs[i].Val.getValueType().getSimpleVT()) { default: llvm_unreachable("Unknown value type!"); case MVT::i1: case MVT::i8: @@ -293,9 +301,7 @@ static SDValue LowerCALL(SDValue Op, SelectionDAG &DAG) { // Walk the register/memloc assignments, inserting copies/loads. for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { CCValAssign &VA = ArgLocs[i]; - - // Arguments start after the 5 first operands of ISD::CALL - SDValue Arg = TheCall->getArg(i); + SDValue Arg = Outs[i].Val; // Promote the value if needed. switch (VA.getLocInfo()) { @@ -335,8 +341,8 @@ static SDValue LowerCALL(SDValue Op, SelectionDAG &DAG) { }; unsigned ArgOffset = 68; - for (unsigned i = 0, e = TheCall->getNumArgs(); i != e; ++i) { - SDValue Val = TheCall->getArg(i); + for (unsigned i = 0, e = Outs.size(); i != e; ++i) { + SDValue Val = Outs[i].Val; MVT ObjectVT = Val.getValueType(); SDValue ValToStore(0, 0); unsigned ObjSize; @@ -469,11 +475,10 @@ static SDValue LowerCALL(SDValue Op, SelectionDAG &DAG) { // Assign locations to each value returned by this call. SmallVector<CCValAssign, 16> RVLocs; - CCState RVInfo(CallingConv, isVarArg, DAG.getTarget(), + CCState RVInfo(CallConv, isVarArg, DAG.getTarget(), RVLocs, *DAG.getContext()); - RVInfo.AnalyzeCallResult(TheCall, RetCC_Sparc32); - SmallVector<SDValue, 8> ResultVals; + RVInfo.AnalyzeCallResult(Ins, RetCC_Sparc32); // Copy all of the result registers out of their specified physreg. for (unsigned i = 0; i != RVLocs.size(); ++i) { @@ -486,15 +491,10 @@ static SDValue LowerCALL(SDValue Op, SelectionDAG &DAG) { Chain = DAG.getCopyFromReg(Chain, dl, Reg, RVLocs[i].getValVT(), InFlag).getValue(1); InFlag = Chain.getValue(2); - ResultVals.push_back(Chain.getValue(0)); + InVals.push_back(Chain.getValue(0)); } - ResultVals.push_back(Chain); - - // Merge everything together with a MERGE_VALUES node. - return DAG.getNode(ISD::MERGE_VALUES, dl, - TheCall->getVTList(), &ResultVals[0], - ResultVals.size()); + return Chain; } @@ -668,9 +668,6 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM) setOperationAction(ISD::DBG_LABEL, MVT::Other, Expand); setOperationAction(ISD::EH_LABEL, MVT::Other, Expand); - // RET must be custom lowered, to meet ABI requirements - setOperationAction(ISD::RET , MVT::Other, Custom); - // VASTART needs to be custom lowered to use the VarArgsFrameIndex. setOperationAction(ISD::VASTART , MVT::Other, Custom); // VAARG needs to be lowered to not do unaligned accesses for doubles. @@ -948,9 +945,6 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) { case ISD::VASTART: return LowerVASTART(Op, DAG, *this); case ISD::VAARG: return LowerVAARG(Op, DAG); case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG); - case ISD::CALL: return LowerCALL(Op, DAG); - case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG); - case ISD::RET: return LowerRET(Op, DAG); } } diff --git a/lib/Target/Sparc/SparcISelLowering.h b/lib/Target/Sparc/SparcISelLowering.h index 37fb29d..dab4cc6 100644 --- a/lib/Target/Sparc/SparcISelLowering.h +++ b/lib/Target/Sparc/SparcISelLowering.h @@ -44,7 +44,6 @@ namespace llvm { public: SparcTargetLowering(TargetMachine &TM); virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG); - SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG); int getVarArgsFrameOffset() const { return VarArgsFrameOffset; } @@ -74,6 +73,29 @@ namespace llvm { /// getFunctionAlignment - Return the Log2 alignment of this function. virtual unsigned getFunctionAlignment(const Function *F) const; + + virtual SDValue + LowerFormalArguments(SDValue Chain, + unsigned CallConv, + bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + virtual SDValue + LowerCall(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, + bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + virtual SDValue + LowerReturn(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG); }; } // end namespace llvm diff --git a/lib/Target/Sparc/SparcInstrInfo.td b/lib/Target/Sparc/SparcInstrInfo.td index 2d6c920..8ecc588 100644 --- a/lib/Target/Sparc/SparcInstrInfo.td +++ b/lib/Target/Sparc/SparcInstrInfo.td @@ -754,8 +754,6 @@ def : Pat<(call tglobaladdr:$dst), def : Pat<(call texternalsym:$dst), (CALL texternalsym:$dst)>; -def : Pat<(ret), (RETL)>; - // Map integer extload's to zextloads. def : Pat<(i32 (extloadi1 ADDRrr:$src)), (LDUBrr ADDRrr:$src)>; def : Pat<(i32 (extloadi1 ADDRri:$src)), (LDUBri ADDRri:$src)>; diff --git a/lib/Target/SystemZ/SystemZISelLowering.cpp b/lib/Target/SystemZ/SystemZISelLowering.cpp index 38b4c30..6265a13 100644 --- a/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -82,8 +82,6 @@ SystemZTargetLowering::SystemZTargetLowering(SystemZTargetMachine &tm) : setSchedulingPreference(SchedulingForLatency); setBooleanContents(ZeroOrOneBooleanContent); - setOperationAction(ISD::RET, MVT::Other, Custom); - setOperationAction(ISD::BR_JT, MVT::Other, Expand); setOperationAction(ISD::BRCOND, MVT::Other, Expand); setOperationAction(ISD::BR_CC, MVT::i32, Custom); @@ -155,9 +153,6 @@ SystemZTargetLowering::SystemZTargetLowering(SystemZTargetMachine &tm) : SDValue SystemZTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { switch (Op.getOpcode()) { - case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG); - case ISD::RET: return LowerRET(Op, DAG); - case ISD::CALL: return LowerCALL(Op, DAG); case ISD::BR_CC: return LowerBR_CC(Op, DAG); case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); @@ -175,27 +170,41 @@ SDValue SystemZTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { #include "SystemZGenCallingConv.inc" -SDValue SystemZTargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, - SelectionDAG &DAG) { - unsigned CC = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue(); - switch (CC) { +SDValue +SystemZTargetLowering::LowerFormalArguments(SDValue Chain, + unsigned CallConv, + bool isVarArg, + const SmallVectorImpl<ISD::InputArg> + &Ins, + DebugLoc dl, + SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + + switch (CallConv) { default: llvm_unreachable("Unsupported calling convention"); case CallingConv::C: case CallingConv::Fast: - return LowerCCCArguments(Op, DAG); + return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals); } } -SDValue SystemZTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { - CallSDNode *TheCall = cast<CallSDNode>(Op.getNode()); - unsigned CallingConv = TheCall->getCallingConv(); - switch (CallingConv) { +SDValue +SystemZTargetLowering::LowerCall(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, + bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + + switch (CallConv) { default: llvm_unreachable("Unsupported calling convention"); case CallingConv::Fast: case CallingConv::C: - return LowerCCCCallTo(Op, DAG, CallingConv); + return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall, + Outs, Ins, dl, DAG, InVals); } } @@ -203,25 +212,29 @@ SDValue SystemZTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { /// generate load operations for arguments places on the stack. // FIXME: struct return stuff // FIXME: varargs -SDValue SystemZTargetLowering::LowerCCCArguments(SDValue Op, - SelectionDAG &DAG) { +SDValue +SystemZTargetLowering::LowerCCCArguments(SDValue Chain, + unsigned CallConv, + bool isVarArg, + const SmallVectorImpl<ISD::InputArg> + &Ins, + DebugLoc dl, + SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); MachineRegisterInfo &RegInfo = MF.getRegInfo(); - SDValue Root = Op.getOperand(0); - bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0; - unsigned CC = MF.getFunction()->getCallingConv(); - DebugLoc dl = Op.getDebugLoc(); // Assign locations to all of the incoming arguments. SmallVector<CCValAssign, 16> ArgLocs; - CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs, *DAG.getContext()); - CCInfo.AnalyzeFormalArguments(Op.getNode(), CC_SystemZ); + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), + ArgLocs, *DAG.getContext()); + CCInfo.AnalyzeFormalArguments(Ins, CC_SystemZ); if (isVarArg) llvm_report_error("Varargs not supported yet"); - SmallVector<SDValue, 16> ArgValues; for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { SDValue ArgValue; CCValAssign &VA = ArgLocs[i]; @@ -232,7 +245,7 @@ SDValue SystemZTargetLowering::LowerCCCArguments(SDValue Op, switch (LocVT.getSimpleVT()) { default: #ifndef NDEBUG - cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: " + cerr << "LowerFormalArguments Unhandled argument type: " << LocVT.getSimpleVT() << "\n"; #endif @@ -250,7 +263,7 @@ SDValue SystemZTargetLowering::LowerCCCArguments(SDValue Op, unsigned VReg = RegInfo.createVirtualRegister(RC); RegInfo.addLiveIn(VA.getLocReg(), VReg); - ArgValue = DAG.getCopyFromReg(Root, dl, VReg, LocVT); + ArgValue = DAG.getCopyFromReg(Chain, dl, VReg, LocVT); } else { // Sanity check assert(VA.isMemLoc()); @@ -263,7 +276,7 @@ SDValue SystemZTargetLowering::LowerCCCArguments(SDValue Op, // Create the SelectionDAG nodes corresponding to a load // from this parameter SDValue FIN = DAG.getFrameIndex(FI, getPointerTy()); - ArgValue = DAG.getLoad(LocVT, dl, Root, FIN, + ArgValue = DAG.getLoad(LocVT, dl, Chain, FIN, PseudoSourceValue::getFixedStack(FI), 0); } @@ -280,26 +293,25 @@ SDValue SystemZTargetLowering::LowerCCCArguments(SDValue Op, if (VA.getLocInfo() != CCValAssign::Full) ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue); - ArgValues.push_back(ArgValue); + InVals.push_back(ArgValue); } - ArgValues.push_back(Root); - - // Return the new list of results. - return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getNode()->getVTList(), - &ArgValues[0], ArgValues.size()).getValue(Op.getResNo()); + return Chain; } /// LowerCCCCallTo - functions arguments are copied from virtual regs to /// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted. /// TODO: sret. -SDValue SystemZTargetLowering::LowerCCCCallTo(SDValue Op, SelectionDAG &DAG, - unsigned CC) { - CallSDNode *TheCall = cast<CallSDNode>(Op.getNode()); - SDValue Chain = TheCall->getChain(); - SDValue Callee = TheCall->getCallee(); - bool isVarArg = TheCall->isVarArg(); - DebugLoc dl = Op.getDebugLoc(); +SDValue +SystemZTargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, + bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> + &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + MachineFunction &MF = DAG.getMachineFunction(); // Offset to first argument stack slot. @@ -307,9 +319,10 @@ SDValue SystemZTargetLowering::LowerCCCCallTo(SDValue Op, SelectionDAG &DAG, // Analyze operands of the call, assigning locations to each operand. SmallVector<CCValAssign, 16> ArgLocs; - CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs, *DAG.getContext()); + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), + ArgLocs, *DAG.getContext()); - CCInfo.AnalyzeCallOperands(TheCall, CC_SystemZ); + CCInfo.AnalyzeCallOperands(Outs, CC_SystemZ); // Get a count of how many bytes are to be pushed on the stack. unsigned NumBytes = CCInfo.getNextStackOffset(); @@ -325,8 +338,7 @@ SDValue SystemZTargetLowering::LowerCCCCallTo(SDValue Op, SelectionDAG &DAG, for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { CCValAssign &VA = ArgLocs[i]; - // Arguments start after the 5 first operands of ISD::CALL - SDValue Arg = TheCall->getArg(i); + SDValue Arg = Outs[i].Val; // Promote the value if needed. switch (VA.getLocInfo()) { @@ -418,30 +430,27 @@ SDValue SystemZTargetLowering::LowerCCCCallTo(SDValue Op, SelectionDAG &DAG, // Handle result values, copying them out of physregs into vregs that we // return. - return SDValue(LowerCallResult(Chain, InFlag, TheCall, CC, DAG), - Op.getResNo()); + return LowerCallResult(Chain, InFlag, CallConv, isVarArg, Ins, dl, + DAG, InVals); } -/// LowerCallResult - Lower the result values of an ISD::CALL into the -/// appropriate copies out of appropriate physical registers. This assumes that -/// Chain/InFlag are the input chain/flag to use, and that TheCall is the call -/// being lowered. Returns a SDNode with the same number of values as the -/// ISD::CALL. -SDNode* +/// LowerCallResult - Lower the result values of a call into the +/// appropriate copies out of appropriate physical registers. +/// +SDValue SystemZTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, - CallSDNode *TheCall, - unsigned CallingConv, - SelectionDAG &DAG) { - bool isVarArg = TheCall->isVarArg(); - DebugLoc dl = TheCall->getDebugLoc(); + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> + &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { // Assign locations to each value returned by this call. SmallVector<CCValAssign, 16> RVLocs; - CCState CCInfo(CallingConv, isVarArg, getTargetMachine(), RVLocs, + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), RVLocs, *DAG.getContext()); - CCInfo.AnalyzeCallResult(TheCall, RetCC_SystemZ); - SmallVector<SDValue, 8> ResultVals; + CCInfo.AnalyzeCallResult(Ins, RetCC_SystemZ); // Copy all of the result registers out of their specified physreg. for (unsigned i = 0; i != RVLocs.size(); ++i) { @@ -465,29 +474,28 @@ SystemZTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, if (VA.getLocInfo() != CCValAssign::Full) RetValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), RetValue); - ResultVals.push_back(RetValue); + InVals.push_back(RetValue); } - ResultVals.push_back(Chain); - - // Merge everything together with a MERGE_VALUES node. - return DAG.getNode(ISD::MERGE_VALUES, dl, TheCall->getVTList(), - &ResultVals[0], ResultVals.size()).getNode(); + return Chain; } -SDValue SystemZTargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) { +SDValue +SystemZTargetLowering::LowerReturn(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG) { + // CCValAssign - represent the assignment of the return value to a location SmallVector<CCValAssign, 16> RVLocs; - unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv(); - bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg(); - DebugLoc dl = Op.getDebugLoc(); // CCState - Info about the registers and stack slot. - CCState CCInfo(CC, isVarArg, getTargetMachine(), RVLocs, *DAG.getContext()); + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), + RVLocs, *DAG.getContext()); - // Analize return values of ISD::RET - CCInfo.AnalyzeReturn(Op.getNode(), RetCC_SystemZ); + // Analize return values. + CCInfo.AnalyzeReturn(Outs, RetCC_SystemZ); // If this is the first return lowered for this function, add the regs to the // liveout set for the function. @@ -497,14 +505,12 @@ SDValue SystemZTargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) { DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); } - // The chain is always operand #0 - SDValue Chain = Op.getOperand(0); SDValue Flag; // Copy the result values into the output registers. for (unsigned i = 0; i != RVLocs.size(); ++i) { CCValAssign &VA = RVLocs[i]; - SDValue ResValue = Op.getOperand(i*2+1); + SDValue ResValue = Outs[i].Val; assert(VA.isRegLoc() && "Can only return in registers!"); // If this is an 8/16/32-bit value, it is really should be passed promoted @@ -516,8 +522,6 @@ SDValue SystemZTargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) { else if (VA.getLocInfo() == CCValAssign::AExt) ResValue = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), ResValue); - // ISD::RET => ret chain, (regnum1,val1), ... - // So i*2+1 index only the regnums Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), ResValue, Flag); // Guarantee that all emitted copies are stuck together, diff --git a/lib/Target/SystemZ/SystemZISelLowering.h b/lib/Target/SystemZ/SystemZISelLowering.h index 33fa13f..0cf0783 100644 --- a/lib/Target/SystemZ/SystemZISelLowering.h +++ b/lib/Target/SystemZ/SystemZISelLowering.h @@ -28,7 +28,7 @@ namespace llvm { /// Return with a flag operand. Operand 0 is the chain operand. RET_FLAG, - /// CALL/TAILCALL - These operations represent an abstract call + /// CALL - These operations represent an abstract call /// instruction, which includes a bunch of information. CALL, @@ -69,21 +69,12 @@ namespace llvm { return 1; } - SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG); - SDValue LowerRET(SDValue Op, SelectionDAG &DAG); - SDValue LowerCALL(SDValue Op, SelectionDAG &DAG); SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG); SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG); SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG); SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG); SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG); - SDValue LowerCCCArguments(SDValue Op, SelectionDAG &DAG); - SDValue LowerCCCCallTo(SDValue Op, SelectionDAG &DAG, unsigned CC); - SDNode* LowerCallResult(SDValue Chain, SDValue InFlag, - CallSDNode *TheCall, - unsigned CallingConv, SelectionDAG &DAG); - SDValue EmitCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC, SDValue &SystemZCC, SelectionDAG &DAG); @@ -93,6 +84,48 @@ namespace llvm { MachineBasicBlock *BB) const; private: + SDValue LowerCCCCallTo(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, + bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + SDValue LowerCCCArguments(SDValue Chain, + unsigned CallConv, + bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, + SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + SDValue LowerCallResult(SDValue Chain, SDValue InFlag, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + virtual SDValue + LowerFormalArguments(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + virtual SDValue + LowerCall(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + virtual SDValue + LowerReturn(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG); + const SystemZSubtarget &Subtarget; const SystemZTargetMachine &TM; const SystemZRegisterInfo *RegInfo; diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 298a5a8..74db8ef 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -294,8 +294,6 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM) setOperationAction(ISD::SELECT , MVT::i64 , Custom); setOperationAction(ISD::SETCC , MVT::i64 , Custom); } - // X86 ret instruction may pop stack. - setOperationAction(ISD::RET , MVT::Other, Custom); setOperationAction(ISD::EH_RETURN , MVT::Other, Custom); // Darwin ABI issue. @@ -1060,16 +1058,16 @@ unsigned X86TargetLowering::getFunctionAlignment(const Function *F) const { #include "X86GenCallingConv.inc" -/// LowerRET - Lower an ISD::RET node. -SDValue X86TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) { - DebugLoc dl = Op.getDebugLoc(); - assert((Op.getNumOperands() & 1) == 1 && "ISD::RET should have odd # args"); +SDValue +X86TargetLowering::LowerReturn(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG) { SmallVector<CCValAssign, 16> RVLocs; - unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv(); - bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg(); - CCState CCInfo(CC, isVarArg, getTargetMachine(), RVLocs, *DAG.getContext()); - CCInfo.AnalyzeReturn(Op.getNode(), RetCC_X86); + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), + RVLocs, *DAG.getContext()); + CCInfo.AnalyzeReturn(Outs, RetCC_X86); // If this is the first return lowered for this function, add the regs to the // liveout set for the function. @@ -1078,37 +1076,7 @@ SDValue X86TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) { if (RVLocs[i].isRegLoc()) DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); } - SDValue Chain = Op.getOperand(0); - - // Handle tail call return. - Chain = GetPossiblePreceedingTailCall(Chain, X86ISD::TAILCALL); - if (Chain.getOpcode() == X86ISD::TAILCALL) { - SDValue TailCall = Chain; - SDValue TargetAddress = TailCall.getOperand(1); - SDValue StackAdjustment = TailCall.getOperand(2); - assert(((TargetAddress.getOpcode() == ISD::Register && - (cast<RegisterSDNode>(TargetAddress)->getReg() == X86::EAX || - cast<RegisterSDNode>(TargetAddress)->getReg() == X86::R11)) || - TargetAddress.getOpcode() == ISD::TargetExternalSymbol || - TargetAddress.getOpcode() == ISD::TargetGlobalAddress) && - "Expecting an global address, external symbol, or register"); - assert(StackAdjustment.getOpcode() == ISD::Constant && - "Expecting a const value"); - - SmallVector<SDValue,8> Operands; - Operands.push_back(Chain.getOperand(0)); - Operands.push_back(TargetAddress); - Operands.push_back(StackAdjustment); - // Copy registers used by the call. Last operand is a flag so it is not - // copied. - for (unsigned i=3; i < TailCall.getNumOperands()-1; i++) { - Operands.push_back(Chain.getOperand(i)); - } - return DAG.getNode(X86ISD::TC_RETURN, dl, MVT::Other, &Operands[0], - Operands.size()); - } - // Regular return. SDValue Flag; SmallVector<SDValue, 6> RetOps; @@ -1120,7 +1088,7 @@ SDValue X86TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) { for (unsigned i = 0; i != RVLocs.size(); ++i) { CCValAssign &VA = RVLocs[i]; assert(VA.isRegLoc() && "Can only return in registers!"); - SDValue ValToCopy = Op.getOperand(i*2+1); + SDValue ValToCopy = Outs[i].Val; // Returns in ST0/ST1 are handled specially: these are pushed as operands to // the RET instruction and handled by the FP Stackifier. @@ -1179,26 +1147,22 @@ SDValue X86TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) { MVT::Other, &RetOps[0], RetOps.size()); } +/// LowerCallResult - Lower the result values of a call into the +/// appropriate copies out of appropriate physical registers. +/// +SDValue +X86TargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { -/// LowerCallResult - Lower the result values of an ISD::CALL into the -/// appropriate copies out of appropriate physical registers. This assumes that -/// Chain/InFlag are the input chain/flag to use, and that TheCall is the call -/// being lowered. The returns a SDNode with the same number of values as the -/// ISD::CALL. -SDNode *X86TargetLowering:: -LowerCallResult(SDValue Chain, SDValue InFlag, CallSDNode *TheCall, - unsigned CallingConv, SelectionDAG &DAG) { - - DebugLoc dl = TheCall->getDebugLoc(); // Assign locations to each value returned by this call. SmallVector<CCValAssign, 16> RVLocs; - bool isVarArg = TheCall->isVarArg(); bool Is64Bit = Subtarget->is64Bit(); - CCState CCInfo(CallingConv, isVarArg, getTargetMachine(), + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), RVLocs, *DAG.getContext()); - CCInfo.AnalyzeCallResult(TheCall, RetCC_X86); - - SmallVector<SDValue, 8> ResultVals; + CCInfo.AnalyzeCallResult(Ins, RetCC_X86); // Copy all of the result registers out of their specified physreg. for (unsigned i = 0; i != RVLocs.size(); ++i) { @@ -1207,7 +1171,7 @@ LowerCallResult(SDValue Chain, SDValue InFlag, CallSDNode *TheCall, // If this is x86-64, and we disabled SSE, we can't return FP values if ((CopyVT == MVT::f32 || CopyVT == MVT::f64) && - ((Is64Bit || TheCall->isInreg()) && !Subtarget->hasSSE1())) { + ((Is64Bit || Ins[i].Flags.isInReg()) && !Subtarget->hasSSE1())) { llvm_report_error("SSE register return with SSE disabled"); } @@ -1250,13 +1214,10 @@ LowerCallResult(SDValue Chain, SDValue InFlag, CallSDNode *TheCall, DAG.getIntPtrConstant(1)); } - ResultVals.push_back(Val); + InVals.push_back(Val); } - // Merge everything together with a MERGE_VALUES node. - ResultVals.push_back(Chain); - return DAG.getNode(ISD::MERGE_VALUES, dl, TheCall->getVTList(), - &ResultVals[0], ResultVals.size()).getNode(); + return Chain; } @@ -1270,24 +1231,23 @@ LowerCallResult(SDValue Chain, SDValue InFlag, CallSDNode *TheCall, // For info on fast calling convention see Fast Calling Convention (tail call) // implementation LowerX86_32FastCCCallTo. -/// CallIsStructReturn - Determines whether a CALL node uses struct return +/// CallIsStructReturn - Determines whether a call uses struct return /// semantics. -static bool CallIsStructReturn(CallSDNode *TheCall) { - unsigned NumOps = TheCall->getNumArgs(); - if (!NumOps) +static bool CallIsStructReturn(const SmallVectorImpl<ISD::OutputArg> &Outs) { + if (Outs.empty()) return false; - return TheCall->getArgFlags(0).isSRet(); + return Outs[0].Flags.isSRet(); } /// ArgsAreStructReturn - Determines whether a function uses struct /// return semantics. -static bool ArgsAreStructReturn(SDValue Op) { - unsigned NumArgs = Op.getNode()->getNumValues() - 1; - if (!NumArgs) +static bool +ArgsAreStructReturn(const SmallVectorImpl<ISD::InputArg> &Ins) { + if (Ins.empty()) return false; - return cast<ARG_FLAGSSDNode>(Op.getOperand(3))->getArgFlags().isSRet(); + return Ins[0].Flags.isSRet(); } /// IsCalleePop - Determines whether the callee is required to pop its @@ -1326,14 +1286,13 @@ CCAssignFn *X86TargetLowering::CCAssignFnForNode(unsigned CC) const { return CC_X86_32_C; } -/// NameDecorationForFORMAL_ARGUMENTS - Selects the appropriate decoration to -/// apply to a MachineFunction containing a given FORMAL_ARGUMENTS node. +/// NameDecorationForCallConv - Selects the appropriate decoration to +/// apply to a MachineFunction containing a given calling convention. NameDecorationStyle -X86TargetLowering::NameDecorationForFORMAL_ARGUMENTS(SDValue Op) { - unsigned CC = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue(); - if (CC == CallingConv::X86_FastCall) +X86TargetLowering::NameDecorationForCallConv(unsigned CallConv) { + if (CallConv == CallingConv::X86_FastCall) return FastCall; - else if (CC == CallingConv::X86_StdCall) + else if (CallConv == CallingConv::X86_StdCall) return StdCall; return None; } @@ -1352,15 +1311,18 @@ CreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain, /*AlwaysInline=*/true, NULL, 0, NULL, 0); } -SDValue X86TargetLowering::LowerMemArgument(SDValue Op, SelectionDAG &DAG, - const CCValAssign &VA, - MachineFrameInfo *MFI, - unsigned CC, - SDValue Root, unsigned i) { +SDValue +X86TargetLowering::LowerMemArgument(SDValue Chain, + unsigned CallConv, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + const CCValAssign &VA, + MachineFrameInfo *MFI, + unsigned i) { + // Create the nodes corresponding to a load from this parameter slot. - ISD::ArgFlagsTy Flags = - cast<ARG_FLAGSSDNode>(Op.getOperand(3 + i))->getArgFlags(); - bool AlwaysUseMutable = (CC==CallingConv::Fast) && PerformTailCallOpt; + ISD::ArgFlagsTy Flags = Ins[i].Flags; + bool AlwaysUseMutable = (CallConv==CallingConv::Fast) && PerformTailCallOpt; bool isImmutable = !AlwaysUseMutable && !Flags.isByVal(); // FIXME: For now, all byval parameter objects are marked mutable. This can be @@ -1372,15 +1334,21 @@ SDValue X86TargetLowering::LowerMemArgument(SDValue Op, SelectionDAG &DAG, SDValue FIN = DAG.getFrameIndex(FI, getPointerTy()); if (Flags.isByVal()) return FIN; - return DAG.getLoad(VA.getValVT(), Op.getDebugLoc(), Root, FIN, + return DAG.getLoad(VA.getValVT(), dl, Chain, FIN, PseudoSourceValue::getFixedStack(FI), 0); } SDValue -X86TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) { +X86TargetLowering::LowerFormalArguments(SDValue Chain, + unsigned CallConv, + bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, + SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + MachineFunction &MF = DAG.getMachineFunction(); X86MachineFunctionInfo *FuncInfo = MF.getInfo<X86MachineFunctionInfo>(); - DebugLoc dl = Op.getDebugLoc(); const Function* Fn = MF.getFunction(); if (Fn->hasExternalLinkage() && @@ -1389,24 +1357,21 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) { FuncInfo->setForceFramePointer(true); // Decorate the function name. - FuncInfo->setDecorationStyle(NameDecorationForFORMAL_ARGUMENTS(Op)); + FuncInfo->setDecorationStyle(NameDecorationForCallConv(CallConv)); MachineFrameInfo *MFI = MF.getFrameInfo(); - SDValue Root = Op.getOperand(0); - bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0; - unsigned CC = MF.getFunction()->getCallingConv(); bool Is64Bit = Subtarget->is64Bit(); bool IsWin64 = Subtarget->isTargetWin64(); - assert(!(isVarArg && CC == CallingConv::Fast) && + assert(!(isVarArg && CallConv == CallingConv::Fast) && "Var args not supported with calling convention fastcc"); // Assign locations to all of the incoming arguments. SmallVector<CCValAssign, 16> ArgLocs; - CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs, *DAG.getContext()); - CCInfo.AnalyzeFormalArguments(Op.getNode(), CCAssignFnForNode(CC)); + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), + ArgLocs, *DAG.getContext()); + CCInfo.AnalyzeFormalArguments(Ins, CCAssignFnForNode(CallConv)); - SmallVector<SDValue, 8> ArgValues; unsigned LastVal = ~0U; SDValue ArgValue; for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { @@ -1436,7 +1401,7 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) { llvm_unreachable("Unknown argument type!"); unsigned Reg = MF.addLiveIn(VA.getLocReg(), RC); - ArgValue = DAG.getCopyFromReg(Root, dl, Reg, RegVT); + ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, RegVT); // If this is an 8 or 16-bit value, it is really passed promoted to 32 // bits. Insert an assert[sz]ext to capture this, then truncate to the @@ -1461,14 +1426,14 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) { } } else { assert(VA.isMemLoc()); - ArgValue = LowerMemArgument(Op, DAG, VA, MFI, CC, Root, i); + ArgValue = LowerMemArgument(Chain, CallConv, Ins, dl, DAG, VA, MFI, i); } // If value is passed via pointer - do a load. if (VA.getLocInfo() == CCValAssign::Indirect) - ArgValue = DAG.getLoad(VA.getValVT(), dl, Root, ArgValue, NULL, 0); + ArgValue = DAG.getLoad(VA.getValVT(), dl, Chain, ArgValue, NULL, 0); - ArgValues.push_back(ArgValue); + InVals.push_back(ArgValue); } // The x86-64 ABI for returning structs by value requires that we copy @@ -1481,19 +1446,19 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) { Reg = MF.getRegInfo().createVirtualRegister(getRegClassFor(MVT::i64)); FuncInfo->setSRetReturnReg(Reg); } - SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), dl, Reg, ArgValues[0]); - Root = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Copy, Root); + SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), dl, Reg, InVals[0]); + Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Copy, Chain); } unsigned StackSize = CCInfo.getNextStackOffset(); // align stack specially for tail calls - if (PerformTailCallOpt && CC == CallingConv::Fast) + if (PerformTailCallOpt && CallConv == CallingConv::Fast) StackSize = GetAlignedArgumentStackSize(StackSize, DAG); // If the function takes variable number of arguments, make a frame index for // the start of the first vararg value... for expansion of llvm.va_start. if (isVarArg) { - if (Is64Bit || CC != CallingConv::X86_FastCall) { + if (Is64Bit || CallConv != CallingConv::X86_FastCall) { VarArgsFrameIndex = MFI->CreateFixedObject(1, StackSize); } if (Is64Bit) { @@ -1555,7 +1520,7 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) { for (; NumIntRegs != TotalNumIntRegs; ++NumIntRegs) { unsigned VReg = MF.addLiveIn(GPR64ArgRegs[NumIntRegs], X86::GR64RegisterClass); - SDValue Val = DAG.getCopyFromReg(Root, dl, VReg, MVT::i64); + SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i64); SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, PseudoSourceValue::getFixedStack(RegSaveFrameIndex), 0); @@ -1570,7 +1535,7 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) { for (; NumXMMRegs != TotalNumXMMRegs; ++NumXMMRegs) { unsigned VReg = MF.addLiveIn(XMMArgRegs[NumXMMRegs], X86::VR128RegisterClass); - SDValue Val = DAG.getCopyFromReg(Root, dl, VReg, MVT::v4f32); + SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::v4f32); SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, PseudoSourceValue::getFixedStack(RegSaveFrameIndex), 0); @@ -1579,46 +1544,41 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) { DAG.getIntPtrConstant(16)); } if (!MemOps.empty()) - Root = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, + Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &MemOps[0], MemOps.size()); } } - ArgValues.push_back(Root); - // Some CCs need callee pop. - if (IsCalleePop(isVarArg, CC)) { + if (IsCalleePop(isVarArg, CallConv)) { BytesToPopOnReturn = StackSize; // Callee pops everything. BytesCallerReserves = 0; } else { BytesToPopOnReturn = 0; // Callee pops nothing. // If this is an sret function, the return should pop the hidden pointer. - if (!Is64Bit && CC != CallingConv::Fast && ArgsAreStructReturn(Op)) + if (!Is64Bit && CallConv != CallingConv::Fast && ArgsAreStructReturn(Ins)) BytesToPopOnReturn = 4; BytesCallerReserves = StackSize; } if (!Is64Bit) { RegSaveFrameIndex = 0xAAAAAAA; // RegSaveFrameIndex is X86-64 only. - if (CC == CallingConv::X86_FastCall) + if (CallConv == CallingConv::X86_FastCall) VarArgsFrameIndex = 0xAAAAAAA; // fastcc functions can't have varargs. } FuncInfo->setBytesToPopOnReturn(BytesToPopOnReturn); - // Return the new list of results. - return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getNode()->getVTList(), - &ArgValues[0], ArgValues.size()).getValue(Op.getResNo()); + return Chain; } SDValue -X86TargetLowering::LowerMemOpCallTo(CallSDNode *TheCall, SelectionDAG &DAG, - const SDValue &StackPtr, +X86TargetLowering::LowerMemOpCallTo(SDValue Chain, + SDValue StackPtr, SDValue Arg, + DebugLoc dl, SelectionDAG &DAG, const CCValAssign &VA, - SDValue Chain, - SDValue Arg, ISD::ArgFlagsTy Flags) { + ISD::ArgFlagsTy Flags) { const unsigned FirstStackArgOffset = (Subtarget->isTargetWin64() ? 32 : 0); - DebugLoc dl = TheCall->getDebugLoc(); unsigned LocMemOffset = FirstStackArgOffset + VA.getLocMemOffset(); SDValue PtrOff = DAG.getIntPtrConstant(LocMemOffset); PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(), StackPtr, PtrOff); @@ -1669,34 +1629,37 @@ EmitTailCallStoreRetAddr(SelectionDAG & DAG, MachineFunction &MF, return Chain; } -SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { +SDValue +X86TargetLowering::LowerCall(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + MachineFunction &MF = DAG.getMachineFunction(); - CallSDNode *TheCall = cast<CallSDNode>(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(TheCall); - DebugLoc dl = TheCall->getDebugLoc(); + bool IsStructRet = CallIsStructReturn(Outs); - assert(!(isVarArg && CC == CallingConv::Fast) && + assert((!isTailCall || + (CallConv == CallingConv::Fast && PerformTailCallOpt)) && + "IsEligibleForTailCallOptimization missed a case!"); + assert(!(isVarArg && CallConv == CallingConv::Fast) && "Var args not supported with calling convention fastcc"); // Analyze operands of the call, assigning locations to each operand. SmallVector<CCValAssign, 16> ArgLocs; - CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs, *DAG.getContext()); - CCInfo.AnalyzeCallOperands(TheCall, CCAssignFnForNode(CC)); + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), + ArgLocs, *DAG.getContext()); + CCInfo.AnalyzeCallOperands(Outs, CCAssignFnForNode(CallConv)); // Get a count of how many bytes are to be pushed on the stack. unsigned NumBytes = CCInfo.getNextStackOffset(); - if (PerformTailCallOpt && CC == CallingConv::Fast) + if (PerformTailCallOpt && CallConv == CallingConv::Fast) NumBytes = GetAlignedArgumentStackSize(NumBytes, DAG); int FPDiff = 0; - if (IsTailCall) { + if (isTailCall) { // Lower arguments at fp - stackoffset + fpdiff. unsigned NumBytesCallerPushed = MF.getInfo<X86MachineFunctionInfo>()->getBytesToPopOnReturn(); @@ -1712,7 +1675,7 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { SDValue RetAddrFrIdx; // Load return adress for tail calls. - Chain = EmitTailCallLoadRetAddr(DAG, RetAddrFrIdx, Chain, IsTailCall, Is64Bit, + Chain = EmitTailCallLoadRetAddr(DAG, RetAddrFrIdx, Chain, isTailCall, Is64Bit, FPDiff, dl); SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPass; @@ -1724,8 +1687,8 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { CCValAssign &VA = ArgLocs[i]; MVT RegVT = VA.getLocVT(); - SDValue Arg = TheCall->getArg(i); - ISD::ArgFlagsTy Flags = TheCall->getArgFlags(i); + SDValue Arg = Outs[i].Val; + ISD::ArgFlagsTy Flags = Outs[i].Flags; bool isByVal = Flags.isByVal(); // Promote the value if needed. @@ -1764,13 +1727,13 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { if (VA.isRegLoc()) { RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); } else { - if (!IsTailCall || (IsTailCall && isByVal)) { + if (!isTailCall || (isTailCall && isByVal)) { assert(VA.isMemLoc()); if (StackPtr.getNode() == 0) StackPtr = DAG.getCopyFromReg(Chain, dl, X86StackPtr, getPointerTy()); - MemOpChains.push_back(LowerMemOpCallTo(TheCall, DAG, StackPtr, VA, - Chain, Arg, Flags)); + MemOpChains.push_back(LowerMemOpCallTo(Chain, StackPtr, Arg, + dl, DAG, VA, Flags)); } } } @@ -1784,7 +1747,7 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { SDValue InFlag; // Tail call byval lowering might overwrite argument registers so in case of // tail call optimization the copies to registers are lowered later. - if (!IsTailCall) + if (!isTailCall) for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first, RegsToPass[i].second, InFlag); @@ -1795,7 +1758,7 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { if (Subtarget->isPICStyleGOT()) { // ELF / PIC requires GOT in the EBX register before function calls via PLT // GOT pointer. - if (!IsTailCall) { + if (!isTailCall) { Chain = DAG.getCopyToReg(Chain, dl, X86::EBX, DAG.getNode(X86ISD::GlobalBaseReg, DebugLoc::getUnknownLoc(), @@ -1847,7 +1810,15 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { // For tail calls lower the arguments to the 'real' stack slot. - if (IsTailCall) { + if (isTailCall) { + // Force all the incoming stack arguments to be loaded from the stack + // before any new outgoing arguments are stored to the stack, because the + // outgoing stack slots may alias the incoming argument stack slots, and + // the alias isn't otherwise explicit. This is slightly more conservative + // than necessary, because it means that each store effectively depends + // on every argument instead of just those arguments it would clobber. + SDValue ArgChain = DAG.getStackArgumentTokenFactor(Chain); + SmallVector<SDValue, 8> MemOpChains2; SDValue FIN; int FI = 0; @@ -1857,8 +1828,8 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { CCValAssign &VA = ArgLocs[i]; if (!VA.isRegLoc()) { assert(VA.isMemLoc()); - SDValue Arg = TheCall->getArg(i); - ISD::ArgFlagsTy Flags = TheCall->getArgFlags(i); + SDValue Arg = Outs[i].Val; + ISD::ArgFlagsTy Flags = Outs[i].Flags; // Create frame index. int32_t Offset = VA.getLocMemOffset()+FPDiff; uint32_t OpSize = (VA.getLocVT().getSizeInBits()+7)/8; @@ -1873,12 +1844,13 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { getPointerTy()); Source = DAG.getNode(ISD::ADD, dl, getPointerTy(), StackPtr, Source); - MemOpChains2.push_back(CreateCopyOfByValArgument(Source, FIN, Chain, + MemOpChains2.push_back(CreateCopyOfByValArgument(Source, FIN, + ArgChain, Flags, DAG, dl)); } else { // Store relative to framepointer. MemOpChains2.push_back( - DAG.getStore(Chain, dl, Arg, FIN, + DAG.getStore(ArgChain, dl, Arg, FIN, PseudoSourceValue::getFixedStack(FI), 0)); } } @@ -1948,7 +1920,7 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy(), OpFlags); - } else if (IsTailCall) { + } else if (isTailCall) { unsigned Opc = Is64Bit ? X86::R11 : X86::EAX; Chain = DAG.getCopyToReg(Chain, dl, @@ -1963,20 +1935,16 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag); SmallVector<SDValue, 8> Ops; - if (IsTailCall) { + if (isTailCall) { Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumBytes, true), DAG.getIntPtrConstant(0, true), InFlag); InFlag = Chain.getValue(1); - - // Returns a chain & a flag for retval copy to use. - NodeTys = DAG.getVTList(MVT::Other, MVT::Flag); - Ops.clear(); } Ops.push_back(Chain); Ops.push_back(Callee); - if (IsTailCall) + if (isTailCall) Ops.push_back(DAG.getConstant(FPDiff, MVT::i32)); // Add argument registers to the end of the list so that they are known live @@ -1986,7 +1954,7 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { RegsToPass[i].second.getValueType())); // Add an implicit use GOT pointer in EBX. - if (!IsTailCall && Subtarget->isPICStyleGOT()) + if (!isTailCall && Subtarget->isPICStyleGOT()) Ops.push_back(DAG.getRegister(X86::EBX, getPointerTy())); // Add an implicit use of AL for x86 vararg functions. @@ -1996,13 +1964,28 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { if (InFlag.getNode()) Ops.push_back(InFlag); - if (IsTailCall) { - assert(InFlag.getNode() && - "Flag must be set. Depend on flag being set in LowerRET"); - Chain = DAG.getNode(X86ISD::TAILCALL, dl, - TheCall->getVTList(), &Ops[0], Ops.size()); + if (isTailCall) { + // If this is the first return lowered for this function, add the regs + // to the liveout set for the function. + if (MF.getRegInfo().liveout_empty()) { + SmallVector<CCValAssign, 16> RVLocs; + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), RVLocs, + *DAG.getContext()); + CCInfo.AnalyzeCallResult(Ins, RetCC_X86); + for (unsigned i = 0; i != RVLocs.size(); ++i) + if (RVLocs[i].isRegLoc()) + MF.getRegInfo().addLiveOut(RVLocs[i].getLocReg()); + } + + assert(((Callee.getOpcode() == ISD::Register && + (cast<RegisterSDNode>(Callee)->getReg() == X86::EAX || + cast<RegisterSDNode>(Callee)->getReg() == X86::R9)) || + Callee.getOpcode() == ISD::TargetExternalSymbol || + Callee.getOpcode() == ISD::TargetGlobalAddress) && + "Expecting an global address, external symbol, or register"); - return SDValue(Chain.getNode(), Op.getResNo()); + return DAG.getNode(X86ISD::TC_RETURN, dl, + NodeTys, &Ops[0], Ops.size()); } Chain = DAG.getNode(X86ISD::CALL, dl, NodeTys, &Ops[0], Ops.size()); @@ -2010,9 +1993,9 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { // Create the CALLSEQ_END node. unsigned NumBytesForCalleeToPush; - if (IsCalleePop(isVarArg, CC)) + if (IsCalleePop(isVarArg, CallConv)) NumBytesForCalleeToPush = NumBytes; // Callee pops everything - else if (!Is64Bit && CC != CallingConv::Fast && IsStructRet) + else if (!Is64Bit && CallConv != CallingConv::Fast && IsStructRet) // If this is is a call to a struct-return function, the callee // pops the hidden struct pointer, so we have to push it back. // This is common for Darwin/X86, Linux & Mingw32 targets. @@ -2030,8 +2013,8 @@ 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, TheCall, CC, DAG), - Op.getResNo()); + return LowerCallResult(Chain, InFlag, CallConv, isVarArg, + Ins, dl, DAG, InVals); } @@ -2088,25 +2071,18 @@ unsigned X86TargetLowering::GetAlignedArgumentStackSize(unsigned StackSize, return Offset; } -/// IsEligibleForTailCallElimination - Check to see whether the next instruction -/// 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(CallSDNode *TheCall, - SDValue Ret, - SelectionDAG& DAG) const { - if (!PerformTailCallOpt) - return false; - - if (CheckTailCallReturnConstraints(TheCall, Ret)) { - unsigned CallerCC = - DAG.getMachineFunction().getFunction()->getCallingConv(); - unsigned CalleeCC = TheCall->getCallingConv(); - if (CalleeCC == CallingConv::Fast && CallerCC == CalleeCC) - return true; - } - - return false; +/// IsEligibleForTailCallOptimization - Check whether the call is eligible +/// for tail call optimization. Targets which want to do tail call +/// optimization should implement this function. +bool +X86TargetLowering::IsEligibleForTailCallOptimization(SDValue Callee, + unsigned CalleeCC, + bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + SelectionDAG& DAG) const { + MachineFunction &MF = DAG.getMachineFunction(); + unsigned CallerCC = MF.getFunction()->getCallingConv(); + return CalleeCC == CallingConv::Fast && CallerCC == CalleeCC; } FastISel * @@ -5825,7 +5801,7 @@ X86TargetLowering::EmitTargetCodeForMemset(SelectionDAG &DAG, DebugLoc dl, Args.push_back(Entry); std::pair<SDValue,SDValue> CallResult = LowerCallTo(Chain, Type::VoidTy, false, false, false, false, - 0, CallingConv::C, false, + 0, CallingConv::C, false, /*isReturnValueUsed=*/false, DAG.getExternalSymbol(bzeroEntry, IntPtr), Args, DAG, dl); return CallResult.second; } @@ -6845,9 +6821,6 @@ SDValue X86TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { case ISD::SELECT: return LowerSELECT(Op, DAG); case ISD::BRCOND: return LowerBRCOND(Op, DAG); case ISD::JumpTable: return LowerJumpTable(Op, DAG); - case ISD::CALL: return LowerCALL(Op, DAG); - case ISD::RET: return LowerRET(Op, DAG); - case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG); case ISD::VASTART: return LowerVASTART(Op, DAG); case ISD::VAARG: return LowerVAARG(Op, DAG); case ISD::VACOPY: return LowerVACOPY(Op, DAG); @@ -7009,7 +6982,6 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const { case X86ISD::FLD: return "X86ISD::FLD"; case X86ISD::FST: return "X86ISD::FST"; case X86ISD::CALL: return "X86ISD::CALL"; - case X86ISD::TAILCALL: return "X86ISD::TAILCALL"; case X86ISD::RDTSC_DAG: return "X86ISD::RDTSC_DAG"; case X86ISD::BT: return "X86ISD::BT"; case X86ISD::CMP: return "X86ISD::CMP"; diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h index 9a88cc7..0b7ed09 100644 --- a/lib/Target/X86/X86ISelLowering.h +++ b/lib/Target/X86/X86ISelLowering.h @@ -85,7 +85,7 @@ namespace llvm { /// as. FST, - /// CALL/TAILCALL - These operations represent an abstract X86 call + /// CALL - These operations represent an abstract X86 call /// instruction, which includes a bunch of information. In particular the /// operands of these node are: /// @@ -102,12 +102,8 @@ namespace llvm { /// #1 - The first register result value (optional) /// #2 - The second register result value (optional) /// - /// The CALL vs TAILCALL distinction boils down to whether the callee is - /// known not to modify the caller's stack frame, as is standard with - /// LLVM. CALL, - TAILCALL, - + /// RDTSC_DAG - This operation implements the lowering for /// readcyclecounter RDTSC_DAG, @@ -508,9 +504,12 @@ namespace llvm { /// IsEligibleForTailCallOptimization - Check whether the call is eligible /// for tail call optimization. Targets which want to do tail call /// optimization should implement this function. - virtual bool IsEligibleForTailCallOptimization(CallSDNode *TheCall, - SDValue Ret, - SelectionDAG &DAG) const; + virtual bool + IsEligibleForTailCallOptimization(SDValue Callee, + unsigned CalleeCC, + bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + SelectionDAG& DAG) const; virtual const X86Subtarget* getSubtarget() { return Subtarget; @@ -563,26 +562,30 @@ namespace llvm { bool X86ScalarSSEf32; bool X86ScalarSSEf64; - 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(CallSDNode *TheCall, SelectionDAG &DAG, - const SDValue &StackPtr, - const CCValAssign &VA, SDValue Chain, - SDValue Arg, ISD::ArgFlagsTy Flags); + SDValue LowerCallResult(SDValue Chain, SDValue InFlag, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + SDValue LowerMemArgument(SDValue Chain, + unsigned CallConv, + const SmallVectorImpl<ISD::InputArg> &ArgInfo, + DebugLoc dl, SelectionDAG &DAG, + const CCValAssign &VA, MachineFrameInfo *MFI, + unsigned i); + SDValue LowerMemOpCallTo(SDValue Chain, SDValue StackPtr, SDValue Arg, + DebugLoc dl, SelectionDAG &DAG, + const CCValAssign &VA, + ISD::ArgFlagsTy Flags); // Call lowering helpers. - bool IsCalleePop(bool isVarArg, unsigned CallingConv); + bool IsCalleePop(bool isVarArg, unsigned CallConv); SDValue EmitTailCallLoadRetAddr(SelectionDAG &DAG, SDValue &OutRetAddr, SDValue Chain, bool IsTailCall, bool Is64Bit, int FPDiff, DebugLoc dl); - CCAssignFn *CCAssignFnForNode(unsigned CallingConv) const; - NameDecorationStyle NameDecorationForFORMAL_ARGUMENTS(SDValue Op); + CCAssignFn *CCAssignFnForNode(unsigned CallConv) const; + NameDecorationStyle NameDecorationForCallConv(unsigned CallConv); unsigned GetAlignedArgumentStackSize(unsigned StackSize, SelectionDAG &DAG); std::pair<SDValue,SDValue> FP_TO_INTHelper(SDValue Op, SelectionDAG &DAG, @@ -619,10 +622,7 @@ namespace llvm { SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG); SDValue LowerMEMSET(SDValue Op, SelectionDAG &DAG); SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG); - SDValue LowerCALL(SDValue Op, SelectionDAG &DAG); - SDValue LowerRET(SDValue Op, SelectionDAG &DAG); SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG); - SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG); SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG); SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG); SDValue LowerVACOPY(SDValue Op, SelectionDAG &DAG); @@ -642,6 +642,26 @@ namespace llvm { SDValue LowerLOAD_SUB(SDValue Op, SelectionDAG &DAG); SDValue LowerREADCYCLECOUNTER(SDValue Op, SelectionDAG &DAG); + virtual SDValue + LowerFormalArguments(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + virtual SDValue + LowerCall(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + virtual SDValue + LowerReturn(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG); + void ReplaceATOMIC_BINARY_64(SDNode *N, SmallVectorImpl<SDValue> &Results, SelectionDAG &DAG, unsigned NewOp); diff --git a/lib/Target/X86/X86Instr64bit.td b/lib/Target/X86/X86Instr64bit.td index c8712d4..94bb1de 100644 --- a/lib/Target/X86/X86Instr64bit.td +++ b/lib/Target/X86/X86Instr64bit.td @@ -1528,23 +1528,7 @@ def : Pat<(X86call (i64 tglobaladdr:$dst)), def : Pat<(X86call (i64 texternalsym:$dst)), (WINCALL64pcrel32 texternalsym:$dst)>, Requires<[IsWin64]>; -def : Pat<(X86tailcall (i64 tglobaladdr:$dst)), - (CALL64pcrel32 tglobaladdr:$dst)>; -def : Pat<(X86tailcall (i64 texternalsym:$dst)), - (CALL64pcrel32 texternalsym:$dst)>; - -def : Pat<(X86tailcall GR64:$dst), - (CALL64r GR64:$dst)>; - - // tailcall stuff -def : Pat<(X86tailcall GR32:$dst), - (TAILCALL)>; -def : Pat<(X86tailcall (i64 tglobaladdr:$dst)), - (TAILCALL)>; -def : Pat<(X86tailcall (i64 texternalsym:$dst)), - (TAILCALL)>; - def : Pat<(X86tcret GR64:$dst, imm:$off), (TCRETURNri64 GR64:$dst, imm:$off)>; diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index 7fb78f5..bbf0cb5 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -124,9 +124,6 @@ def X86callseq_end : def X86call : SDNode<"X86ISD::CALL", SDT_X86Call, [SDNPHasChain, SDNPOutFlag, SDNPOptInFlag]>; -def X86tailcall: SDNode<"X86ISD::TAILCALL", SDT_X86Call, - [SDNPHasChain, SDNPOutFlag, SDNPOptInFlag]>; - def X86rep_stos: SDNode<"X86ISD::REP_STOS", SDTX86RepStr, [SDNPHasChain, SDNPInFlag, SDNPOutFlag, SDNPMayStore]>; def X86rep_movs: SDNode<"X86ISD::REP_MOVS", SDTX86RepStr, @@ -622,10 +619,6 @@ let isCall = 1 in // Tail call stuff. -def TAILCALL : I<0, Pseudo, (outs), (ins), - "#TAILCALL", - []>; - let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in def TCRETURNdi : I<0, Pseudo, (outs), (ins i32imm:$dst, i32imm:$offset, variable_ops), "#TC_RETURN $dst $offset", @@ -3452,14 +3445,6 @@ def : Pat<(store (i32 (X86Wrapper texternalsym:$src)), addr:$dst), // Calls // tailcall stuff -def : Pat<(X86tailcall GR32:$dst), - (TAILCALL)>; - -def : Pat<(X86tailcall (i32 tglobaladdr:$dst)), - (TAILCALL)>; -def : Pat<(X86tailcall (i32 texternalsym:$dst)), - (TAILCALL)>; - def : Pat<(X86tcret GR32:$dst, imm:$off), (TCRETURNri GR32:$dst, imm:$off)>; diff --git a/lib/Target/XCore/XCoreISelLowering.cpp b/lib/Target/XCore/XCoreISelLowering.cpp index 24d9f9b..38648e0 100644 --- a/lib/Target/XCore/XCoreISelLowering.cpp +++ b/lib/Target/XCore/XCoreISelLowering.cpp @@ -113,9 +113,6 @@ XCoreTargetLowering::XCoreTargetLowering(XCoreTargetMachine &XTM) setOperationAction(ISD::BR_JT, MVT::Other, Expand); setOperationAction(ISD::JumpTable, MVT::i32, Custom); - // RET must be custom lowered, to meet ABI requirements - setOperationAction(ISD::RET, MVT::Other, Custom); - setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); // Thread Local Storage @@ -162,9 +159,6 @@ SDValue XCoreTargetLowering:: LowerOperation(SDValue Op, SelectionDAG &DAG) { switch (Op.getOpcode()) { - case ISD::CALL: return LowerCALL(Op, DAG); - case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG); - case ISD::RET: return LowerRET(Op, DAG); case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG); case ISD::ConstantPool: return LowerConstantPool(Op, DAG); @@ -455,6 +449,7 @@ LowerLOAD(SDValue Op, SelectionDAG &DAG) std::pair<SDValue, SDValue> CallResult = LowerCallTo(Chain, IntPtrTy, false, false, false, false, 0, CallingConv::C, false, + /*isReturnValueUsed=*/true, DAG.getExternalSymbol("__misaligned_load", getPointerTy()), Args, DAG, dl); @@ -515,6 +510,7 @@ LowerSTORE(SDValue Op, SelectionDAG &DAG) std::pair<SDValue, SDValue> CallResult = LowerCallTo(Chain, Type::VoidTy, false, false, false, false, 0, CallingConv::C, false, + /*isReturnValueUsed=*/true, DAG.getExternalSymbol("__misaligned_store", getPointerTy()), Args, DAG, dl); @@ -603,35 +599,33 @@ SDValue XCoreTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) { //===----------------------------------------------------------------------===// // Calling Convention Implementation -// -// The lower operations present on calling convention works on this order: -// LowerCALL (virt regs --> phys regs, virt regs --> stack) -// LowerFORMAL_ARGUMENTS (phys --> virt regs, stack --> virt regs) -// LowerRET (virt regs --> phys regs) -// LowerCALL (phys regs --> virt regs) -// //===----------------------------------------------------------------------===// #include "XCoreGenCallingConv.inc" //===----------------------------------------------------------------------===// -// CALL Calling Convention Implementation +// Call Calling Convention Implementation //===----------------------------------------------------------------------===// -/// XCore custom CALL implementation -SDValue XCoreTargetLowering:: -LowerCALL(SDValue Op, SelectionDAG &DAG) -{ - CallSDNode *TheCall = cast<CallSDNode>(Op.getNode()); - unsigned CallingConv = TheCall->getCallingConv(); +/// XCore call implementation +SDValue +XCoreTargetLowering::LowerCall(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, + bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + // For now, only CallingConv::C implemented - switch (CallingConv) + switch (CallConv) { default: llvm_unreachable("Unsupported calling convention"); case CallingConv::Fast: case CallingConv::C: - return LowerCCCCallTo(Op, DAG, CallingConv); + return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall, + Outs, Ins, dl, DAG, InVals); } } @@ -639,24 +633,25 @@ LowerCALL(SDValue Op, SelectionDAG &DAG) /// regs to (physical regs)/(stack frame), CALLSEQ_START and /// CALLSEQ_END are emitted. /// TODO: isTailCall, sret. -SDValue XCoreTargetLowering:: -LowerCCCCallTo(SDValue Op, SelectionDAG &DAG, unsigned CC) -{ - CallSDNode *TheCall = cast<CallSDNode>(Op.getNode()); - SDValue Chain = TheCall->getChain(); - SDValue Callee = TheCall->getCallee(); - bool isVarArg = TheCall->isVarArg(); - DebugLoc dl = Op.getDebugLoc(); +SDValue +XCoreTargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, + bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { // Analyze operands of the call, assigning locations to each operand. SmallVector<CCValAssign, 16> ArgLocs; - CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs, *DAG.getContext()); + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), + ArgLocs, *DAG.getContext()); // The ABI dictates there should be one stack slot available to the callee // on function entry (for saving lr). CCInfo.AllocateStack(4, 4); - CCInfo.AnalyzeCallOperands(TheCall, CC_XCore); + CCInfo.AnalyzeCallOperands(Outs, CC_XCore); // Get a count of how many bytes are to be pushed on the stack. unsigned NumBytes = CCInfo.getNextStackOffset(); @@ -670,9 +665,7 @@ LowerCCCCallTo(SDValue Op, SelectionDAG &DAG, unsigned CC) // Walk the register/memloc assignments, inserting copies/loads. for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { CCValAssign &VA = ArgLocs[i]; - - // Arguments start after the 5 first operands of ISD::CALL - SDValue Arg = TheCall->getArg(i); + SDValue Arg = Outs[i].Val; // Promote the value if needed. switch (VA.getLocInfo()) { @@ -759,60 +752,58 @@ LowerCCCCallTo(SDValue Op, SelectionDAG &DAG, unsigned CC) // Handle result values, copying them out of physregs into vregs that we // return. - return SDValue(LowerCallResult(Chain, InFlag, TheCall, CC, DAG), - Op.getResNo()); + return LowerCallResult(Chain, InFlag, CallConv, isVarArg, + Ins, dl, DAG, InVals); } -/// LowerCallResult - Lower the result values of an ISD::CALL into the -/// appropriate copies out of appropriate physical registers. This assumes that -/// Chain/InFlag are the input chain/flag to use, and that TheCall is the call -/// being lowered. Returns a SDNode with the same number of values as the -/// ISD::CALL. -SDNode *XCoreTargetLowering:: -LowerCallResult(SDValue Chain, SDValue InFlag, CallSDNode *TheCall, - unsigned CallingConv, SelectionDAG &DAG) { - bool isVarArg = TheCall->isVarArg(); - DebugLoc dl = TheCall->getDebugLoc(); +/// LowerCallResult - Lower the result values of a call into the +/// appropriate copies out of appropriate physical registers. +SDValue +XCoreTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { // Assign locations to each value returned by this call. SmallVector<CCValAssign, 16> RVLocs; - CCState CCInfo(CallingConv, isVarArg, getTargetMachine(), + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), RVLocs, *DAG.getContext()); - CCInfo.AnalyzeCallResult(TheCall, RetCC_XCore); - SmallVector<SDValue, 8> ResultVals; + CCInfo.AnalyzeCallResult(Ins, RetCC_XCore); // Copy all of the result registers out of their specified physreg. for (unsigned i = 0; i != RVLocs.size(); ++i) { Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(), RVLocs[i].getValVT(), InFlag).getValue(1); InFlag = Chain.getValue(2); - ResultVals.push_back(Chain.getValue(0)); + InVals.push_back(Chain.getValue(0)); } - ResultVals.push_back(Chain); - - // Merge everything together with a MERGE_VALUES node. - return DAG.getNode(ISD::MERGE_VALUES, dl, TheCall->getVTList(), - &ResultVals[0], ResultVals.size()).getNode(); + return Chain; } //===----------------------------------------------------------------------===// -// FORMAL_ARGUMENTS Calling Convention Implementation +// Formal Arguments Calling Convention Implementation //===----------------------------------------------------------------------===// -/// XCore custom FORMAL_ARGUMENTS implementation -SDValue XCoreTargetLowering:: -LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) -{ - unsigned CC = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue(); - switch(CC) +/// XCore formal arguments implementation +SDValue +XCoreTargetLowering::LowerFormalArguments(SDValue Chain, + unsigned CallConv, + bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, + SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + switch (CallConv) { default: llvm_unreachable("Unsupported calling convention"); case CallingConv::C: case CallingConv::Fast: - return LowerCCCArguments(Op, DAG); + return LowerCCCArguments(Chain, CallConv, isVarArg, + Ins, dl, DAG, InVals); } } @@ -820,27 +811,28 @@ LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) /// virtual registers and generate load operations for /// arguments places on the stack. /// TODO: sret -SDValue XCoreTargetLowering:: -LowerCCCArguments(SDValue Op, SelectionDAG &DAG) -{ +SDValue +XCoreTargetLowering::LowerCCCArguments(SDValue Chain, + unsigned CallConv, + bool isVarArg, + const SmallVectorImpl<ISD::InputArg> + &Ins, + DebugLoc dl, + SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); MachineRegisterInfo &RegInfo = MF.getRegInfo(); - SDValue Root = Op.getOperand(0); - bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0; - unsigned CC = MF.getFunction()->getCallingConv(); - DebugLoc dl = Op.getDebugLoc(); // Assign locations to all of the incoming arguments. SmallVector<CCValAssign, 16> ArgLocs; - CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs, *DAG.getContext()); + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), + ArgLocs, *DAG.getContext()); - CCInfo.AnalyzeFormalArguments(Op.getNode(), CC_XCore); + CCInfo.AnalyzeFormalArguments(Ins, CC_XCore); unsigned StackSlotSize = XCoreFrameInfo::stackSlotSize(); - SmallVector<SDValue, 16> ArgValues; - unsigned LRSaveSize = StackSlotSize; for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { @@ -854,7 +846,7 @@ LowerCCCArguments(SDValue Op, SelectionDAG &DAG) default: { #ifndef NDEBUG - errs() << "LowerFORMAL_ARGUMENTS Unhandled argument type: " + errs() << "LowerFormalArguments Unhandled argument type: " << RegVT.getSimpleVT() << "\n"; #endif llvm_unreachable(0); @@ -863,7 +855,7 @@ LowerCCCArguments(SDValue Op, SelectionDAG &DAG) unsigned VReg = RegInfo.createVirtualRegister( XCore::GRRegsRegisterClass); RegInfo.addLiveIn(VA.getLocReg(), VReg); - ArgValues.push_back(DAG.getCopyFromReg(Root, dl, VReg, RegVT)); + InVals.push_back(DAG.getCopyFromReg(Chain, dl, VReg, RegVT)); } } else { // sanity check @@ -871,7 +863,7 @@ LowerCCCArguments(SDValue Op, SelectionDAG &DAG) // Load the argument to a virtual register unsigned ObjSize = VA.getLocVT().getSizeInBits()/8; if (ObjSize > StackSlotSize) { - errs() << "LowerFORMAL_ARGUMENTS Unhandled argument type: " + errs() << "LowerFormalArguments Unhandled argument type: " << VA.getLocVT().getSimpleVT() << "\n"; } @@ -882,7 +874,7 @@ LowerCCCArguments(SDValue Op, SelectionDAG &DAG) // Create the SelectionDAG nodes corresponding to a load //from this parameter SDValue FIN = DAG.getFrameIndex(FI, MVT::i32); - ArgValues.push_back(DAG.getLoad(VA.getLocVT(), dl, Root, FIN, NULL, 0)); + InVals.push_back(DAG.getLoad(VA.getLocVT(), dl, Chain, FIN, NULL, 0)); } } @@ -911,14 +903,14 @@ LowerCCCArguments(SDValue Op, SelectionDAG &DAG) unsigned VReg = RegInfo.createVirtualRegister( XCore::GRRegsRegisterClass); RegInfo.addLiveIn(ArgRegs[i], VReg); - SDValue Val = DAG.getCopyFromReg(Root, dl, VReg, MVT::i32); + SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32); // Move argument from virt reg -> stack SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0); MemOps.push_back(Store); } if (!MemOps.empty()) - Root = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, - &MemOps[0], MemOps.size()); + Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, + &MemOps[0], MemOps.size()); } else { // This will point to the next argument passed via stack. XFI->setVarArgsFrameIndex( @@ -926,34 +918,29 @@ LowerCCCArguments(SDValue Op, SelectionDAG &DAG) } } - ArgValues.push_back(Root); - - // Return the new list of results. - std::vector<MVT> RetVT(Op.getNode()->value_begin(), - Op.getNode()->value_end()); - return DAG.getNode(ISD::MERGE_VALUES, dl, RetVT, - &ArgValues[0], ArgValues.size()); + return Chain; } //===----------------------------------------------------------------------===// // Return Value Calling Convention Implementation //===----------------------------------------------------------------------===// -SDValue XCoreTargetLowering:: -LowerRET(SDValue Op, SelectionDAG &DAG) -{ +SDValue +XCoreTargetLowering::LowerReturn(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG) { + // CCValAssign - represent the assignment of // the return value to a location SmallVector<CCValAssign, 16> RVLocs; - unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv(); - bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg(); - DebugLoc dl = Op.getDebugLoc(); // CCState - Info about the registers and stack slot. - CCState CCInfo(CC, isVarArg, getTargetMachine(), RVLocs, *DAG.getContext()); + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), + RVLocs, *DAG.getContext()); - // Analize return values of ISD::RET - CCInfo.AnalyzeReturn(Op.getNode(), RetCC_XCore); + // Analize return values. + CCInfo.AnalyzeReturn(Outs, RetCC_XCore); // If this is the first return lowered for this function, add // the regs to the liveout set for the function. @@ -963,8 +950,6 @@ LowerRET(SDValue Op, SelectionDAG &DAG) DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); } - // The chain is always operand #0 - SDValue Chain = Op.getOperand(0); SDValue Flag; // Copy the result values into the output registers. @@ -972,10 +957,8 @@ LowerRET(SDValue Op, SelectionDAG &DAG) CCValAssign &VA = RVLocs[i]; assert(VA.isRegLoc() && "Can only return in registers!"); - // ISD::RET => ret chain, (regnum1,val1), ... - // So i*2+1 index only the regnums Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), - Op.getOperand(i*2+1), Flag); + Outs[i].Val, Flag); // guarantee that all emitted copies are // stuck together, avoiding something bad diff --git a/lib/Target/XCore/XCoreISelLowering.h b/lib/Target/XCore/XCoreISelLowering.h index 4b24466..a21744e 100644 --- a/lib/Target/XCore/XCoreISelLowering.h +++ b/lib/Target/XCore/XCoreISelLowering.h @@ -92,10 +92,24 @@ namespace llvm { const XCoreSubtarget &Subtarget; // Lower Operand helpers - SDValue LowerCCCArguments(SDValue Op, SelectionDAG &DAG); - SDValue LowerCCCCallTo(SDValue Op, SelectionDAG &DAG, unsigned CC); - SDNode *LowerCallResult(SDValue Chain, SDValue InFlag, CallSDNode*TheCall, - unsigned CallingConv, SelectionDAG &DAG); + SDValue LowerCCCArguments(SDValue Chain, + unsigned CallConv, + bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + SDValue LowerCCCCallTo(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, + bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + SDValue LowerCallResult(SDValue Chain, SDValue InFlag, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); SDValue getReturnAddressFrameIndex(SelectionDAG &DAG); SDValue getGlobalAddressWrapper(SDValue GA, GlobalValue *GV, SelectionDAG &DAG); @@ -103,9 +117,6 @@ namespace llvm { // Lower Operand specifics SDValue LowerLOAD(SDValue Op, SelectionDAG &DAG); SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG); - SDValue LowerRET(SDValue Op, SelectionDAG &DAG); - SDValue LowerCALL(SDValue Op, SelectionDAG &DAG); - SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG); SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG); SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG); SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG); @@ -124,6 +135,29 @@ namespace llvm { SDValue ExpandADDSUB(SDNode *Op, SelectionDAG &DAG); virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; + + virtual SDValue + LowerFormalArguments(SDValue Chain, + unsigned CallConv, + bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + virtual SDValue + LowerCall(SDValue Chain, SDValue Callee, + unsigned CallConv, bool isVarArg, + bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + virtual SDValue + LowerReturn(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG); }; } |