diff options
Diffstat (limited to 'include/llvm')
-rw-r--r-- | include/llvm/CodeGen/CallingConvLower.h | 22 | ||||
-rw-r--r-- | include/llvm/CodeGen/SelectionDAG.h | 14 | ||||
-rw-r--r-- | include/llvm/CodeGen/SelectionDAGNodes.h | 147 | ||||
-rw-r--r-- | include/llvm/Target/TargetLowering.h | 85 | ||||
-rw-r--r-- | include/llvm/Target/TargetSelectionDAG.td | 1 |
5 files changed, 119 insertions, 150 deletions
diff --git a/include/llvm/CodeGen/CallingConvLower.h b/include/llvm/CodeGen/CallingConvLower.h index 11f6e80..02a2bf5 100644 --- a/include/llvm/CodeGen/CallingConvLower.h +++ b/include/llvm/CodeGen/CallingConvLower.h @@ -172,17 +172,20 @@ public: return UsedRegs[Reg/32] & (1 << (Reg&31)); } - /// AnalyzeFormalArguments - Analyze an ISD::FORMAL_ARGUMENTS node, + /// AnalyzeFormalArguments - Analyze an array of argument values, /// incorporating info about the formals into this state. - void AnalyzeFormalArguments(SDNode *TheArgs, CCAssignFn Fn); + void AnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins, + CCAssignFn Fn); - /// AnalyzeReturn - Analyze the returned values of an ISD::RET node, + /// AnalyzeReturn - Analyze the returned values of a return, /// incorporating info about the result values into this state. - void AnalyzeReturn(SDNode *TheRet, CCAssignFn Fn); + void AnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs, + CCAssignFn Fn); - /// AnalyzeCallOperands - Analyze an ISD::CALL node, incorporating info - /// about the passed values into this state. - void AnalyzeCallOperands(CallSDNode *TheCall, CCAssignFn Fn); + /// AnalyzeCallOperands - Analyze the outgoing arguments to a call, + /// incorporating info about the passed values into this state. + void AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs, + CCAssignFn Fn); /// AnalyzeCallOperands - Same as above except it takes vectors of types /// and argument flags. @@ -190,9 +193,10 @@ public: SmallVectorImpl<ISD::ArgFlagsTy> &Flags, CCAssignFn Fn); - /// AnalyzeCallResult - Analyze the return values of an ISD::CALL node, + /// AnalyzeCallResult - Analyze the return values of a call, /// incorporating info about the passed values into this state. - void AnalyzeCallResult(CallSDNode *TheCall, CCAssignFn Fn); + void AnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> &Ins, + CCAssignFn Fn); /// AnalyzeCallResult - Same as above except it's specialized for calls which /// produce a single value. diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index dc93f12..6d3fdc4 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -319,7 +319,6 @@ public: SDValue getExternalSymbol(const char *Sym, DebugLoc dl, MVT VT); SDValue getTargetExternalSymbol(const char *Sym, MVT VT, unsigned char TargetFlags = 0); - SDValue getArgFlags(ISD::ArgFlagsTy Flags); SDValue getValueType(MVT); SDValue getRegister(unsigned Reg, MVT VT); SDValue getDbgStopPoint(DebugLoc DL, SDValue Root, @@ -460,6 +459,12 @@ public: SDValue N1, SDValue N2, SDValue N3, SDValue N4, SDValue N5); + /// getStackArgumentTokenFactor - Compute a TokenFactor to force all + /// the incoming stack arguments to be loaded from the stack. This is + /// used in tail call lowering to protect stack arguments from being + /// clobbered. + SDValue getStackArgumentTokenFactor(SDValue Chain); + SDValue getMemcpy(SDValue Chain, DebugLoc dl, SDValue Dst, SDValue Src, SDValue Size, unsigned Align, bool AlwaysInline, const Value *DstSV, uint64_t DstSVOff, @@ -534,13 +539,6 @@ public: /// getMergeValues - Create a MERGE_VALUES node from the given operands. SDValue getMergeValues(const SDValue *Ops, unsigned NumOps, DebugLoc dl); - /// getCall - Create a CALL node from the given information. - /// - SDValue getCall(unsigned CallingConv, DebugLoc dl, bool IsVarArgs, - bool IsTailCall, bool isInreg, SDVTList VTs, - const SDValue *Operands, unsigned NumOperands, - unsigned NumFixedArgs); - /// getLoad - Loads are not normal binary operators: their result type is not /// determined by their operands, and they produce a value AND a token chain. /// diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 6dc55ff..9749d8f 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -97,7 +97,7 @@ namespace ISD { AssertSext, AssertZext, // Various leaf nodes. - BasicBlock, VALUETYPE, ARG_FLAGS, CONDCODE, Register, + BasicBlock, VALUETYPE, CONDCODE, Register, Constant, ConstantFP, GlobalAddress, GlobalTLSAddress, FrameIndex, JumpTable, ConstantPool, ExternalSymbol, @@ -180,38 +180,6 @@ namespace ISD { // UNDEF - An undefined node UNDEF, - /// 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. It must be custom legalized. See description of CALL node for - /// FLAG argument contents explanation. - /// - FORMAL_ARGUMENTS, - - /// RV1, RV2...RVn, CHAIN = CALL(CHAIN, CALLEE, - /// ARG0, FLAG0, ARG1, FLAG1, ... ARGn, FLAGn) - /// This node represents a fully general function call, before the legalizer - /// runs. This has one result value for each argument / flag pair, plus - /// a chain result. It must be custom legalized. Flag argument indicates - /// misc. argument attributes. Currently: - /// Bit 0 - signness - /// Bit 1 - 'inreg' attribute - /// Bit 2 - 'sret' attribute - /// Bit 4 - 'byval' attribute - /// Bit 5 - 'nest' attribute - /// Bit 6-9 - alignment of byval structures - /// Bit 10-26 - size of byval structures - /// Bits 31:27 - argument ABI alignment in the first argument piece and - /// alignment '1' in other argument pieces. - /// - /// CALL nodes use the CallSDNode subclass of SDNode, which - /// additionally carries information about the calling convention, - /// whether the call is varargs, and if it's marked as a tail call. - /// - CALL, - // EXTRACT_ELEMENT - This is used to get the lower or upper (determined by // a Constant, which is required to be operand #1) half of the integer or // float value specified as operand #0. This is only for use before @@ -515,12 +483,6 @@ namespace ISD { // chain, cc, lhs, rhs, block to branch to if condition is true. BR_CC, - // RET - Return from function. The first operand is the chain, - // and any subsequent operands are pairs of return value and return value - // attributes (see CALL for description of attributes) for the function. - // This operation can have variable number of operands. - RET, - // INLINEASM - Represents an inline asm block. This node always has two // return values: a chain and a flag result. The inputs are as follows: // Operand #0 : Input chain. @@ -2234,80 +2196,41 @@ namespace ISD { /// getRawBits - Represent the flags as a bunch of bits. uint64_t getRawBits() const { return Flags; } }; -} - -/// ARG_FLAGSSDNode - Leaf node holding parameter flags. -class ARG_FLAGSSDNode : public SDNode { - ISD::ArgFlagsTy TheFlags; - friend class SelectionDAG; - explicit ARG_FLAGSSDNode(ISD::ArgFlagsTy Flags) - : SDNode(ISD::ARG_FLAGS, DebugLoc::getUnknownLoc(), - getSDVTList(MVT::Other)), TheFlags(Flags) { - } -public: - ISD::ArgFlagsTy getArgFlags() const { return TheFlags; } - - static bool classof(const ARG_FLAGSSDNode *) { return true; } - static bool classof(const SDNode *N) { - return N->getOpcode() == ISD::ARG_FLAGS; - } -}; - -/// CallSDNode - Node for calls -- ISD::CALL. -class CallSDNode : public SDNode { - unsigned CallingConv; - bool IsVarArg; - bool IsTailCall; - unsigned NumFixedArgs; - // We might eventually want a full-blown Attributes for the result; that - // will expand the size of the representation. At the moment we only - // need Inreg. - bool Inreg; - friend class SelectionDAG; - CallSDNode(unsigned cc, DebugLoc dl, bool isvararg, bool istailcall, - bool isinreg, SDVTList VTs, const SDValue *Operands, - unsigned numOperands, unsigned numFixedArgs) - : SDNode(ISD::CALL, dl, VTs, Operands, numOperands), - CallingConv(cc), IsVarArg(isvararg), IsTailCall(istailcall), - NumFixedArgs(numFixedArgs), Inreg(isinreg) {} -public: - unsigned getCallingConv() const { return CallingConv; } - unsigned isVarArg() const { return IsVarArg; } - unsigned isTailCall() const { return IsTailCall; } - unsigned isInreg() const { return Inreg; } - /// Set this call to not be marked as a tail call. Normally setter - /// methods in SDNodes are unsafe because it breaks the CSE map, - /// but we don't include the tail call flag for calls so it's ok - /// in this case. - void setNotTailCall() { IsTailCall = false; } - - SDValue getChain() const { return getOperand(0); } - SDValue getCallee() const { return getOperand(1); } - - unsigned getNumArgs() const { return (getNumOperands() - 2) / 2; } - unsigned getNumFixedArgs() const { - if (isVarArg()) - return NumFixedArgs; - else - return getNumArgs(); - } - SDValue getArg(unsigned i) const { return getOperand(2+2*i); } - SDValue getArgFlagsVal(unsigned i) const { - return getOperand(3+2*i); - } - ISD::ArgFlagsTy getArgFlags(unsigned i) const { - return cast<ARG_FLAGSSDNode>(getArgFlagsVal(i).getNode())->getArgFlags(); - } - - unsigned getNumRetVals() const { return getNumValues() - 1; } - MVT getRetValType(unsigned i) const { return getValueType(i); } + /// InputArg - This struct carries flags and type information about a + /// single incoming (formal) argument or incoming (from the perspective + /// of the caller) return value virtual register. + /// + struct InputArg { + ArgFlagsTy Flags; + MVT VT; + bool Used; + + InputArg() : VT(MVT::Other), Used(false) {} + InputArg(ISD::ArgFlagsTy flags, MVT vt, bool used) + : Flags(flags), VT(vt), Used(used) { + assert(VT.isSimple() && + "InputArg value type must be Simple!"); + } + }; - static bool classof(const CallSDNode *) { return true; } - static bool classof(const SDNode *N) { - return N->getOpcode() == ISD::CALL; - } -}; + /// OutputArg - This struct carries flags and a value for a + /// single outgoing (actual) argument or outgoing (from the perspective + /// of the caller) return value virtual register. + /// + struct OutputArg { + ArgFlagsTy Flags; + SDValue Val; + bool IsFixed; + + OutputArg() : IsFixed(false) {} + OutputArg(ISD::ArgFlagsTy flags, SDValue val, bool isfixed) + : Flags(flags), Val(val), IsFixed(isfixed) { + assert(Val.getValueType().isSimple() && + "OutputArg value type must be Simple!"); + } + }; +} /// VTSDNode - This class is used to represent MVT's, which are used /// to parameterize some operations. @@ -2491,7 +2414,7 @@ typedef LoadSDNode LargestSDNode; /// MostAlignedSDNode - The SDNode class with the greatest alignment /// requirement. /// -typedef ARG_FLAGSSDNode MostAlignedSDNode; +typedef GlobalAddressSDNode MostAlignedSDNode; namespace ISD { /// isNormalLoad - Returns true if the specified node is a non-extending diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 8e5844e..47c1ba5 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -1091,16 +1091,27 @@ public: // the SelectionDAGLowering code knows how to lower these. // - /// LowerArguments - This hook must be implemented to indicate how we should - /// lower the arguments for the specified function, into the specified DAG. - virtual void - LowerArguments(Function &F, SelectionDAG &DAG, - SmallVectorImpl<SDValue>& ArgValues, DebugLoc dl); + /// LowerFormalArguments - This hook must be implemented to lower the + /// incoming (formal) arguments, described by the Ins array, into the + /// specified DAG. The implementation should fill in the InVals array + /// with legal-type argument values, and return the resulting token + /// chain value. + /// + virtual SDValue + LowerFormalArguments(SDValue Chain, + unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + assert(0 && "Not Implemented"); + return SDValue(); // this is here to silence compiler errors + } - /// LowerCallTo - This hook lowers an abstract call to a function into an + /// LowerCallTo - This function lowers an abstract call to a function into an /// actual call. This returns a pair of operands. The first element is the /// return value for the function (if RetTy is not VoidTy). The second - /// element is the outgoing token chain. + /// element is the outgoing token chain. It calls LowerCall to do the actual + /// lowering. struct ArgListEntry { SDValue Node; const Type* Ty; @@ -1116,11 +1127,47 @@ public: isSRet(false), isNest(false), isByVal(false), Alignment(0) { } }; typedef std::vector<ArgListEntry> ArgListTy; - virtual std::pair<SDValue, SDValue> + std::pair<SDValue, SDValue> LowerCallTo(SDValue Chain, const Type *RetTy, bool RetSExt, bool RetZExt, bool isVarArg, bool isInreg, unsigned NumFixedArgs, - unsigned CallingConv, bool isTailCall, SDValue Callee, - ArgListTy &Args, SelectionDAG &DAG, DebugLoc dl); + unsigned CallConv, bool isTailCall, bool isReturnValueUsed, + SDValue Callee, ArgListTy &Args, SelectionDAG &DAG, DebugLoc dl); + + /// LowerCall - This hook must be implemented to lower calls into the + /// the specified DAG. The outgoing arguments to the call are described + /// by the Outs array, and the values to be returned by the call are + /// described by the Ins array. The implementation should fill in the + /// InVals array with legal-type return values from the call, and return + /// the resulting token chain value. + /// + /// The isTailCall flag here is normative. If it is true, the + /// implementation must emit a tail call. The + /// IsEligibleForTailCallOptimization hook should be used to catch + /// cases that cannot be handled. + /// + 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) { + assert(0 && "Not Implemented"); + return SDValue(); // this is here to silence compiler errors + } + + /// LowerReturn - This hook must be implemented to lower outgoing + /// return values, described by the Outs array, into the specified + /// DAG. The implementation should return the resulting token chain + /// value. + /// + virtual SDValue + LowerReturn(SDValue Chain, unsigned CallConv, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG) { + assert(0 && "Not Implemented"); + return SDValue(); // this is here to silence compiler errors + } /// EmitTargetCodeForMemcpy - Emit target-specific code that performs a /// memcpy. This can be used by targets to provide code sequences for cases @@ -1216,19 +1263,17 @@ public: /// IsEligibleForTailCallOptimization - Check whether the call is eligible for /// tail call optimization. Targets which want to do tail call optimization - /// should override this function. - virtual bool IsEligibleForTailCallOptimization(CallSDNode *Call, - SDValue Ret, - SelectionDAG &DAG) const { + /// should override this function. + virtual bool + IsEligibleForTailCallOptimization(SDValue Callee, + unsigned CalleeCC, + bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + SelectionDAG& DAG) const { + // Conservative default: no calls are eligible. return false; } - /// CheckTailCallReturnConstraints - Check whether CALL node immediatly - /// preceeds the RET node and whether the return uses the result of the node - /// or is a void return. This function can be used by the target to determine - /// eligiblity of tail call optimization. - static bool CheckTailCallReturnConstraints(CallSDNode *TheCall, SDValue Ret); - /// GetPossiblePreceedingTailCall - Get preceeding TailCallNodeOpCode node if /// it exists. Skip a possible ISD::TokenFactor. static SDValue GetPossiblePreceedingTailCall(SDValue Chain, diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td index 364d4d0..9a9125e 100644 --- a/include/llvm/Target/TargetSelectionDAG.td +++ b/include/llvm/Target/TargetSelectionDAG.td @@ -345,7 +345,6 @@ def vsetcc : SDNode<"ISD::VSETCC" , SDTSetCC>; def brcond : SDNode<"ISD::BRCOND" , SDTBrcond, [SDNPHasChain]>; def brind : SDNode<"ISD::BRIND" , SDTBrind, [SDNPHasChain]>; def br : SDNode<"ISD::BR" , SDTBr, [SDNPHasChain]>; -def ret : SDNode<"ISD::RET" , SDTNone, [SDNPHasChain]>; def trap : SDNode<"ISD::TRAP" , SDTNone, [SDNPHasChain, SDNPSideEffect]>; |