summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2008-09-13 01:54:27 +0000
committerDan Gohman <gohman@apple.com>2008-09-13 01:54:27 +0000
commit095cc29f321382e1f7d295e262a28197f92c5491 (patch)
treebe6c4833a95fbd06a8315df342c5ee55aef50473 /include
parente7de7e3574245fe4cdee3ea895c3aeabca04db63 (diff)
downloadllvm-095cc29f321382e1f7d295e262a28197f92c5491.tar.gz
llvm-095cc29f321382e1f7d295e262a28197f92c5491.tar.bz2
llvm-095cc29f321382e1f7d295e262a28197f92c5491.tar.xz
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.h4
-rw-r--r--include/llvm/CodeGen/SelectionDAG.h7
-rw-r--r--include/llvm/CodeGen/SelectionDAGNodes.h50
-rw-r--r--include/llvm/Target/TargetLowering.h14
4 files changed, 64 insertions, 11 deletions
diff --git a/include/llvm/CodeGen/CallingConvLower.h b/include/llvm/CodeGen/CallingConvLower.h
index 6773c494bd..2a57cc183d 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 52c67c0c76..15d0edc3d8 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 7d6a1776aa..85c464965d 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 85279bb581..af5641674c 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;
}