diff options
author | Dan Gohman <gohman@apple.com> | 2008-09-13 01:54:27 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2008-09-13 01:54:27 +0000 |
commit | 095cc29f321382e1f7d295e262a28197f92c5491 (patch) | |
tree | be6c4833a95fbd06a8315df342c5ee55aef50473 /include | |
parent | e7de7e3574245fe4cdee3ea895c3aeabca04db63 (diff) | |
download | external_llvm-095cc29f321382e1f7d295e262a28197f92c5491.zip external_llvm-095cc29f321382e1f7d295e262a28197f92c5491.tar.gz external_llvm-095cc29f321382e1f7d295e262a28197f92c5491.tar.bz2 |
Define CallSDNode, an SDNode subclass for use with ISD::CALL.
Currently it just holds the calling convention and flags
for isVarArgs and isTailCall.
And it has several utility methods, which eliminate magic
5+2*i and similar index computations in several places.
CallSDNodes are not CSE'd. Teach UpdateNodeOperands to handle
nodes that are not CSE'd gracefully.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@56183 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r-- | include/llvm/CodeGen/CallingConvLower.h | 4 | ||||
-rw-r--r-- | include/llvm/CodeGen/SelectionDAG.h | 7 | ||||
-rw-r--r-- | include/llvm/CodeGen/SelectionDAGNodes.h | 50 | ||||
-rw-r--r-- | include/llvm/Target/TargetLowering.h | 14 |
4 files changed, 64 insertions, 11 deletions
diff --git a/include/llvm/CodeGen/CallingConvLower.h b/include/llvm/CodeGen/CallingConvLower.h index 6773c49..2a57cc1 100644 --- a/include/llvm/CodeGen/CallingConvLower.h +++ b/include/llvm/CodeGen/CallingConvLower.h @@ -143,7 +143,7 @@ public: /// AnalyzeCallOperands - Analyze an ISD::CALL node, incorporating info /// about the passed values into this state. - void AnalyzeCallOperands(SDNode *TheCall, CCAssignFn Fn); + void AnalyzeCallOperands(CallSDNode *TheCall, CCAssignFn Fn); /// AnalyzeCallOperands - Same as above except it takes vectors of types /// and argument flags. @@ -153,7 +153,7 @@ public: /// AnalyzeCallResult - Analyze the return values of an ISD::CALL node, /// incorporating info about the passed values into this state. - void AnalyzeCallResult(SDNode *TheCall, CCAssignFn Fn); + void AnalyzeCallResult(CallSDNode *TheCall, 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 52c67c0..15d0edc 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -463,6 +463,11 @@ public: return getNode(ISD::MERGE_VALUES, VTs, Ops, NumOps); } + /// getCall - Create a CALL node from the given information. + /// + SDValue getCall(unsigned CallingConv, bool IsVarArgs, bool IsTailCall, + SDVTList VTs, const SDValue *Operands, unsigned NumOperands); + /// 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. /// @@ -731,7 +736,7 @@ public: SDValue getShuffleScalarElt(const SDNode *N, unsigned Idx); private: - void RemoveNodeFromCSEMaps(SDNode *N); + bool RemoveNodeFromCSEMaps(SDNode *N); SDNode *AddNonLeafNodeToCSEMaps(SDNode *N); SDNode *FindModifiedNodeSlot(SDNode *N, SDValue Op, void *&InsertPos); SDNode *FindModifiedNodeSlot(SDNode *N, SDValue Op1, SDValue Op2, diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 7d6a177..85c4649 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -179,7 +179,7 @@ namespace ISD { /// FORMAL_ARGUMENTS, - /// RV1, RV2...RVn, CHAIN = CALL(CHAIN, CC#, ISVARARG, ISTAILCALL, CALLEE, + /// 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 @@ -194,6 +194,11 @@ namespace ISD { /// 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 @@ -2181,6 +2186,49 @@ public: } }; +/// CallSDNode - Node for calls -- ISD::CALL. +class CallSDNode : public SDNode { + unsigned CallingConv; + bool IsVarArg; + bool IsTailCall; + virtual void ANCHOR(); // Out-of-line virtual method to give class a home. +protected: + friend class SelectionDAG; + CallSDNode(unsigned cc, bool isvararg, bool istailcall, + SDVTList VTs, const SDValue *Operands, unsigned numOperands) + : SDNode(ISD::CALL, VTs, Operands, numOperands), + CallingConv(cc), IsVarArg(isvararg), IsTailCall(istailcall) {} +public: + unsigned getCallingConv() const { return CallingConv; } + unsigned isVarArg() const { return IsVarArg; } + unsigned isTailCall() const { return IsTailCall; } + + /// 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 CSE 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; } + 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); } + + static bool classof(const CallSDNode *) { return true; } + static bool classof(const SDNode *N) { + return N->getOpcode() == ISD::CALL; + } +}; + /// VTSDNode - This class is used to represent MVT's, which are used /// to parameterize some operations. class VTSDNode : public SDNode { diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 85279bb..af56416 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -1075,7 +1075,7 @@ 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(SDValue Call, + virtual bool IsEligibleForTailCallOptimization(CallSDNode *Call, SDValue Ret, SelectionDAG &DAG) const { return false; @@ -1085,15 +1085,15 @@ public: /// 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(SDValue Call, SDValue Ret) { + static bool CheckTailCallReturnConstraints(CallSDNode *TheCall, SDValue Ret) { unsigned NumOps = Ret.getNumOperands(); if ((NumOps == 1 && - (Ret.getOperand(0) == SDValue(Call.getNode(),1) || - Ret.getOperand(0) == SDValue(Call.getNode(),0))) || + (Ret.getOperand(0) == SDValue(TheCall,1) || + Ret.getOperand(0) == SDValue(TheCall,0))) || (NumOps > 1 && - Ret.getOperand(0) == SDValue(Call.getNode(), - Call.getNode()->getNumValues()-1) && - Ret.getOperand(1) == SDValue(Call.getNode(),0))) + Ret.getOperand(0) == SDValue(TheCall, + TheCall->getNumValues()-1) && + Ret.getOperand(1) == SDValue(TheCall,0))) return true; return false; } |