Add NumFixedArgs attribute to CallSDNode which indicates the number of fixed arguments in a vararg call.

With the SVR4 ABI on PowerPC, vector arguments for vararg calls are passed differently depending on whether they are a fixed or a variable argument. Variable vector arguments always go into memory, fixed vector arguments are put 
into vector registers. If there are no free vector registers available, fixed vector arguments are put on the stack.

The NumFixedArgs attribute allows to decide for an argument in a vararg call whether it belongs to the fixed or variable portion of the parameter list.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74764 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Tilmann Scheller 2009-07-03 06:44:53 +00:00
parent 667ee3cb43
commit 6b61cd185e
16 changed files with 43 additions and 31 deletions

View File

@ -536,7 +536,8 @@ public:
/// ///
SDValue getCall(unsigned CallingConv, DebugLoc dl, bool IsVarArgs, SDValue getCall(unsigned CallingConv, DebugLoc dl, bool IsVarArgs,
bool IsTailCall, bool isInreg, SDVTList VTs, bool IsTailCall, bool isInreg, SDVTList VTs,
const SDValue *Operands, unsigned NumOperands); const SDValue *Operands, unsigned NumOperands,
unsigned NumFixedArgs);
/// getLoad - Loads are not normal binary operators: their result type is not /// 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. /// determined by their operands, and they produce a value AND a token chain.

View File

@ -2257,6 +2257,7 @@ class CallSDNode : public SDNode {
unsigned CallingConv; unsigned CallingConv;
bool IsVarArg; bool IsVarArg;
bool IsTailCall; bool IsTailCall;
unsigned NumFixedArgs;
// We might eventually want a full-blown Attributes for the result; that // We might eventually want a full-blown Attributes for the result; that
// will expand the size of the representation. At the moment we only // will expand the size of the representation. At the moment we only
// need Inreg. // need Inreg.
@ -2264,10 +2265,10 @@ class CallSDNode : public SDNode {
friend class SelectionDAG; friend class SelectionDAG;
CallSDNode(unsigned cc, DebugLoc dl, bool isvararg, bool istailcall, CallSDNode(unsigned cc, DebugLoc dl, bool isvararg, bool istailcall,
bool isinreg, SDVTList VTs, const SDValue *Operands, bool isinreg, SDVTList VTs, const SDValue *Operands,
unsigned numOperands) unsigned numOperands, unsigned numFixedArgs)
: SDNode(ISD::CALL, dl, VTs, Operands, numOperands), : SDNode(ISD::CALL, dl, VTs, Operands, numOperands),
CallingConv(cc), IsVarArg(isvararg), IsTailCall(istailcall), CallingConv(cc), IsVarArg(isvararg), IsTailCall(istailcall),
Inreg(isinreg) {} NumFixedArgs(numFixedArgs), Inreg(isinreg) {}
public: public:
unsigned getCallingConv() const { return CallingConv; } unsigned getCallingConv() const { return CallingConv; }
unsigned isVarArg() const { return IsVarArg; } unsigned isVarArg() const { return IsVarArg; }
@ -2284,6 +2285,12 @@ public:
SDValue getCallee() const { return getOperand(1); } SDValue getCallee() const { return getOperand(1); }
unsigned getNumArgs() const { return (getNumOperands() - 2) / 2; } 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 getArg(unsigned i) const { return getOperand(2+2*i); }
SDValue getArgFlagsVal(unsigned i) const { SDValue getArgFlagsVal(unsigned i) const {
return getOperand(3+2*i); return getOperand(3+2*i);

View File

@ -1122,9 +1122,9 @@ public:
typedef std::vector<ArgListEntry> ArgListTy; typedef std::vector<ArgListEntry> ArgListTy;
virtual std::pair<SDValue, SDValue> virtual std::pair<SDValue, SDValue>
LowerCallTo(SDValue Chain, const Type *RetTy, bool RetSExt, bool RetZExt, LowerCallTo(SDValue Chain, const Type *RetTy, bool RetSExt, bool RetZExt,
bool isVarArg, bool isInreg, unsigned CallingConv, bool isVarArg, bool isInreg, unsigned NumFixedArgs,
bool isTailCall, SDValue Callee, ArgListTy &Args, unsigned CallingConv, bool isTailCall, SDValue Callee,
SelectionDAG &DAG, DebugLoc dl); ArgListTy &Args, SelectionDAG &DAG, DebugLoc dl);
/// EmitTargetCodeForMemcpy - Emit target-specific code that performs a /// EmitTargetCodeForMemcpy - Emit target-specific code that performs a
/// memcpy. This can be used by targets to provide code sequences for cases /// memcpy. This can be used by targets to provide code sequences for cases

View File

@ -1900,7 +1900,7 @@ SDValue SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, SDNode *Node,
const Type *RetTy = Node->getValueType(0).getTypeForMVT(); const Type *RetTy = Node->getValueType(0).getTypeForMVT();
std::pair<SDValue, SDValue> CallInfo = std::pair<SDValue, SDValue> CallInfo =
TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false, TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false,
CallingConv::C, false, Callee, Args, DAG, 0, CallingConv::C, false, Callee, Args, DAG,
Node->getDebugLoc()); Node->getDebugLoc());
// Legalize the call sequence, starting with the chain. This will advance // Legalize the call sequence, starting with the chain. This will advance
@ -2305,7 +2305,7 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node,
TargetLowering::ArgListTy Args; TargetLowering::ArgListTy Args;
std::pair<SDValue, SDValue> CallResult = std::pair<SDValue, SDValue> CallResult =
TLI.LowerCallTo(Node->getOperand(0), Type::VoidTy, TLI.LowerCallTo(Node->getOperand(0), Type::VoidTy,
false, false, false, false, CallingConv::C, false, false, false, false, false, 0, CallingConv::C, false,
DAG.getExternalSymbol("abort", TLI.getPointerTy()), DAG.getExternalSymbol("abort", TLI.getPointerTy()),
Args, DAG, dl); Args, DAG, dl);
Results.push_back(CallResult.second); Results.push_back(CallResult.second);

View File

@ -1006,7 +1006,7 @@ SDValue DAGTypeLegalizer::MakeLibCall(RTLIB::Libcall LC, MVT RetVT,
const Type *RetTy = RetVT.getTypeForMVT(); const Type *RetTy = RetVT.getTypeForMVT();
std::pair<SDValue,SDValue> CallInfo = std::pair<SDValue,SDValue> CallInfo =
TLI.LowerCallTo(DAG.getEntryNode(), RetTy, isSigned, !isSigned, false, TLI.LowerCallTo(DAG.getEntryNode(), RetTy, isSigned, !isSigned, false,
false, CallingConv::C, false, Callee, Args, DAG, dl); false, 0, CallingConv::C, false, Callee, Args, DAG, dl);
return CallInfo.first; return CallInfo.first;
} }

View File

@ -3375,7 +3375,7 @@ SDValue SelectionDAG::getMemcpy(SDValue Chain, DebugLoc dl, SDValue Dst,
// FIXME: pass in DebugLoc // FIXME: pass in DebugLoc
std::pair<SDValue,SDValue> CallResult = std::pair<SDValue,SDValue> CallResult =
TLI.LowerCallTo(Chain, Type::VoidTy, TLI.LowerCallTo(Chain, Type::VoidTy,
false, false, false, false, CallingConv::C, false, false, false, false, false, 0, CallingConv::C, false,
getExternalSymbol("memcpy", TLI.getPointerTy()), getExternalSymbol("memcpy", TLI.getPointerTy()),
Args, *this, dl); Args, *this, dl);
return CallResult.second; return CallResult.second;
@ -3421,7 +3421,7 @@ SDValue SelectionDAG::getMemmove(SDValue Chain, DebugLoc dl, SDValue Dst,
// FIXME: pass in DebugLoc // FIXME: pass in DebugLoc
std::pair<SDValue,SDValue> CallResult = std::pair<SDValue,SDValue> CallResult =
TLI.LowerCallTo(Chain, Type::VoidTy, TLI.LowerCallTo(Chain, Type::VoidTy,
false, false, false, false, CallingConv::C, false, false, false, false, false, 0, CallingConv::C, false,
getExternalSymbol("memmove", TLI.getPointerTy()), getExternalSymbol("memmove", TLI.getPointerTy()),
Args, *this, dl); Args, *this, dl);
return CallResult.second; return CallResult.second;
@ -3473,7 +3473,7 @@ SDValue SelectionDAG::getMemset(SDValue Chain, DebugLoc dl, SDValue Dst,
// FIXME: pass in DebugLoc // FIXME: pass in DebugLoc
std::pair<SDValue,SDValue> CallResult = std::pair<SDValue,SDValue> CallResult =
TLI.LowerCallTo(Chain, Type::VoidTy, TLI.LowerCallTo(Chain, Type::VoidTy,
false, false, false, false, CallingConv::C, false, false, false, false, false, 0, CallingConv::C, false,
getExternalSymbol("memset", TLI.getPointerTy()), getExternalSymbol("memset", TLI.getPointerTy()),
Args, *this, dl); Args, *this, dl);
return CallResult.second; return CallResult.second;
@ -3605,7 +3605,8 @@ SelectionDAG::getMemIntrinsicNode(unsigned Opcode, DebugLoc dl, SDVTList VTList,
SDValue SDValue
SelectionDAG::getCall(unsigned CallingConv, DebugLoc dl, bool IsVarArgs, SelectionDAG::getCall(unsigned CallingConv, DebugLoc dl, bool IsVarArgs,
bool IsTailCall, bool IsInreg, SDVTList VTs, bool IsTailCall, bool IsInreg, SDVTList VTs,
const SDValue *Operands, unsigned NumOperands) { const SDValue *Operands, unsigned NumOperands,
unsigned NumFixedArgs) {
// Do not include isTailCall in the folding set profile. // Do not include isTailCall in the folding set profile.
FoldingSetNodeID ID; FoldingSetNodeID ID;
AddNodeIDNode(ID, ISD::CALL, VTs, Operands, NumOperands); AddNodeIDNode(ID, ISD::CALL, VTs, Operands, NumOperands);
@ -3621,7 +3622,7 @@ SelectionDAG::getCall(unsigned CallingConv, DebugLoc dl, bool IsVarArgs,
} }
SDNode *N = NodeAllocator.Allocate<CallSDNode>(); SDNode *N = NodeAllocator.Allocate<CallSDNode>();
new (N) CallSDNode(CallingConv, dl, IsVarArgs, IsTailCall, IsInreg, new (N) CallSDNode(CallingConv, dl, IsVarArgs, IsTailCall, IsInreg,
VTs, Operands, NumOperands); VTs, Operands, NumOperands, NumFixedArgs);
CSEMap.InsertNode(N, IP); CSEMap.InsertNode(N, IP);
AllNodes.push_back(N); AllNodes.push_back(N);
return SDValue(N, 0); return SDValue(N, 0);

View File

@ -4416,7 +4416,7 @@ void SelectionDAGLowering::LowerCallTo(CallSite CS, SDValue Callee,
TLI.LowerCallTo(getRoot(), CS.getType(), TLI.LowerCallTo(getRoot(), CS.getType(),
CS.paramHasAttr(0, Attribute::SExt), CS.paramHasAttr(0, Attribute::SExt),
CS.paramHasAttr(0, Attribute::ZExt), FTy->isVarArg(), CS.paramHasAttr(0, Attribute::ZExt), FTy->isVarArg(),
CS.paramHasAttr(0, Attribute::InReg), CS.paramHasAttr(0, Attribute::InReg), FTy->getNumParams(),
CS.getCallingConv(), CS.getCallingConv(),
IsTailCall && PerformTailCallOpt, IsTailCall && PerformTailCallOpt,
Callee, Args, DAG, getCurDebugLoc()); Callee, Args, DAG, getCurDebugLoc());
@ -5468,7 +5468,7 @@ void SelectionDAGLowering::visitMalloc(MallocInst &I) {
std::pair<SDValue,SDValue> Result = std::pair<SDValue,SDValue> Result =
TLI.LowerCallTo(getRoot(), I.getType(), false, false, false, false, TLI.LowerCallTo(getRoot(), I.getType(), false, false, false, false,
CallingConv::C, PerformTailCallOpt, 0, CallingConv::C, PerformTailCallOpt,
DAG.getExternalSymbol("malloc", IntPtr), DAG.getExternalSymbol("malloc", IntPtr),
Args, DAG, getCurDebugLoc()); Args, DAG, getCurDebugLoc());
setValue(&I, Result.first); // Pointers always fit in registers setValue(&I, Result.first); // Pointers always fit in registers
@ -5484,7 +5484,7 @@ void SelectionDAGLowering::visitFree(FreeInst &I) {
MVT IntPtr = TLI.getPointerTy(); MVT IntPtr = TLI.getPointerTy();
std::pair<SDValue,SDValue> Result = std::pair<SDValue,SDValue> Result =
TLI.LowerCallTo(getRoot(), Type::VoidTy, false, false, false, false, TLI.LowerCallTo(getRoot(), Type::VoidTy, false, false, false, false,
CallingConv::C, PerformTailCallOpt, 0, CallingConv::C, PerformTailCallOpt,
DAG.getExternalSymbol("free", IntPtr), Args, DAG, DAG.getExternalSymbol("free", IntPtr), Args, DAG,
getCurDebugLoc()); getCurDebugLoc());
DAG.setRoot(Result.second); DAG.setRoot(Result.second);
@ -5657,7 +5657,7 @@ void TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG,
std::pair<SDValue, SDValue> std::pair<SDValue, SDValue>
TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy, TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
bool RetSExt, bool RetZExt, bool isVarArg, bool RetSExt, bool RetZExt, bool isVarArg,
bool isInreg, bool isInreg, unsigned NumFixedArgs,
unsigned CallingConv, bool isTailCall, unsigned CallingConv, bool isTailCall,
SDValue Callee, SDValue Callee,
ArgListTy &Args, SelectionDAG &DAG, DebugLoc dl) { ArgListTy &Args, SelectionDAG &DAG, DebugLoc dl) {
@ -5755,7 +5755,7 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
isVarArg, isTailCall, isInreg, isVarArg, isTailCall, isInreg,
DAG.getVTList(&LoweredRetTys[0], DAG.getVTList(&LoweredRetTys[0],
LoweredRetTys.size()), LoweredRetTys.size()),
&Ops[0], Ops.size() &Ops[0], Ops.size(), NumFixedArgs
); );
Chain = Res.getValue(LoweredRetTys.size() - 1); Chain = Res.getValue(LoweredRetTys.size() - 1);

View File

@ -1159,7 +1159,7 @@ ARMTargetLowering::LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
// FIXME: is there useful debug info available here? // FIXME: is there useful debug info available here?
std::pair<SDValue, SDValue> CallResult = std::pair<SDValue, SDValue> CallResult =
LowerCallTo(Chain, (const Type *) Type::Int32Ty, false, false, false, false, LowerCallTo(Chain, (const Type *) Type::Int32Ty, false, false, false, false,
CallingConv::C, false, 0, CallingConv::C, false,
DAG.getExternalSymbol("__tls_get_addr", PtrVT), Args, DAG, dl); DAG.getExternalSymbol("__tls_get_addr", PtrVT), Args, DAG, dl);
return CallResult.first; return CallResult.first;
} }

View File

@ -365,7 +365,8 @@ static SDValue LowerRET(SDValue Op, SelectionDAG &DAG) {
std::pair<SDValue, SDValue> std::pair<SDValue, SDValue>
AlphaTargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy, AlphaTargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
bool RetSExt, bool RetZExt, bool isVarArg, bool RetSExt, bool RetZExt, bool isVarArg,
bool isInreg, unsigned CallingConv, bool isInreg, unsigned NumFixedArgs,
unsigned CallingConv,
bool isTailCall, SDValue Callee, bool isTailCall, SDValue Callee,
ArgListTy &Args, SelectionDAG &DAG, ArgListTy &Args, SelectionDAG &DAG,
DebugLoc dl) { DebugLoc dl) {

View File

@ -86,9 +86,9 @@ namespace llvm {
/// actual call. /// actual call.
virtual std::pair<SDValue, SDValue> virtual std::pair<SDValue, SDValue>
LowerCallTo(SDValue Chain, const Type *RetTy, bool RetSExt, bool RetZExt, LowerCallTo(SDValue Chain, const Type *RetTy, bool RetSExt, bool RetZExt,
bool isVarArg, bool isInreg, unsigned CC, bool isTailCall, bool isVarArg, bool isInreg, unsigned NumFixedArgs, unsigned CC,
SDValue Callee, ArgListTy &Args, SelectionDAG &DAG, bool isTailCall, SDValue Callee, ArgListTy &Args,
DebugLoc dl); SelectionDAG &DAG, DebugLoc dl);
ConstraintType getConstraintType(const std::string &Constraint) const; ConstraintType getConstraintType(const std::string &Constraint) const;

View File

@ -113,7 +113,7 @@ namespace {
const Type *RetTy = Op.getNode()->getValueType(0).getTypeForMVT(); const Type *RetTy = Op.getNode()->getValueType(0).getTypeForMVT();
std::pair<SDValue, SDValue> CallInfo = std::pair<SDValue, SDValue> CallInfo =
TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false, TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false,
CallingConv::C, false, Callee, Args, DAG, 0, CallingConv::C, false, Callee, Args, DAG,
Op.getDebugLoc()); Op.getDebugLoc());
return CallInfo.first; return CallInfo.first;

View File

@ -315,7 +315,8 @@ void IA64TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG,
std::pair<SDValue, SDValue> std::pair<SDValue, SDValue>
IA64TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy, IA64TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
bool RetSExt, bool RetZExt, bool isVarArg, bool RetSExt, bool RetZExt, bool isVarArg,
bool isInreg, unsigned CallingConv, bool isInreg, unsigned NumFixedArgs,
unsigned CallingConv,
bool isTailCall, SDValue Callee, bool isTailCall, SDValue Callee,
ArgListTy &Args, SelectionDAG &DAG, ArgListTy &Args, SelectionDAG &DAG,
DebugLoc dl) { DebugLoc dl) {

View File

@ -62,7 +62,7 @@ namespace llvm {
virtual std::pair<SDValue, SDValue> virtual std::pair<SDValue, SDValue>
LowerCallTo(SDValue Chain, const Type *RetTy, LowerCallTo(SDValue Chain, const Type *RetTy,
bool RetSExt, bool RetZExt, bool isVarArg, bool isInreg, bool RetSExt, bool RetZExt, bool isVarArg, bool isInreg,
unsigned CC, bool isTailCall, unsigned NumFixedArgs, unsigned CC, bool isTailCall,
SDValue Callee, ArgListTy &Args, SelectionDAG &DAG, SDValue Callee, ArgListTy &Args, SelectionDAG &DAG,
DebugLoc dl); DebugLoc dl);

View File

@ -399,7 +399,7 @@ PIC16TargetLowering::MakePIC16Libcall(PIC16ISD::PIC16Libcall Call,
const Type *RetTy = RetVT.getTypeForMVT(); const Type *RetTy = RetVT.getTypeForMVT();
std::pair<SDValue,SDValue> CallInfo = std::pair<SDValue,SDValue> CallInfo =
LowerCallTo(DAG.getEntryNode(), RetTy, isSigned, !isSigned, false, LowerCallTo(DAG.getEntryNode(), RetTy, isSigned, !isSigned, false,
false, CallingConv::C, false, Callee, Args, DAG, dl); false, 0, CallingConv::C, false, Callee, Args, DAG, dl);
return CallInfo.first; return CallInfo.first;
} }
@ -1302,7 +1302,8 @@ SDValue PIC16TargetLowering::LegalizeCALL(SDValue Op, SelectionDAG &DAG) {
// Generate new call with all the operands legal // Generate new call with all the operands legal
return DAG.getCall(TheCall->getCallingConv(), dl, return DAG.getCall(TheCall->getCallingConv(), dl,
TheCall->isVarArg(), TheCall->isTailCall(), TheCall->isVarArg(), TheCall->isTailCall(),
TheCall->isInreg(), VTs, &Ops[0], Ops.size()); TheCall->isInreg(), VTs, &Ops[0], Ops.size(),
TheCall->getNumFixedArgs());
} }
void PIC16TargetLowering:: void PIC16TargetLowering::

View File

@ -1267,7 +1267,7 @@ SDValue PPCTargetLowering::LowerTRAMPOLINE(SDValue Op, SelectionDAG &DAG) {
// Lower to a call to __trampoline_setup(Trmp, TrampSize, FPtr, ctx_reg) // Lower to a call to __trampoline_setup(Trmp, TrampSize, FPtr, ctx_reg)
std::pair<SDValue, SDValue> CallResult = std::pair<SDValue, SDValue> CallResult =
LowerCallTo(Chain, Op.getValueType().getTypeForMVT(), false, false, LowerCallTo(Chain, Op.getValueType().getTypeForMVT(), false, false,
false, false, CallingConv::C, false, false, false, 0, CallingConv::C, false,
DAG.getExternalSymbol("__trampoline_setup", PtrVT), DAG.getExternalSymbol("__trampoline_setup", PtrVT),
Args, DAG, dl); Args, DAG, dl);

View File

@ -5813,7 +5813,7 @@ X86TargetLowering::EmitTargetCodeForMemset(SelectionDAG &DAG, DebugLoc dl,
Args.push_back(Entry); Args.push_back(Entry);
std::pair<SDValue,SDValue> CallResult = std::pair<SDValue,SDValue> CallResult =
LowerCallTo(Chain, Type::VoidTy, false, false, false, false, LowerCallTo(Chain, Type::VoidTy, false, false, false, false,
CallingConv::C, false, 0, CallingConv::C, false,
DAG.getExternalSymbol(bzeroEntry, IntPtr), Args, DAG, dl); DAG.getExternalSymbol(bzeroEntry, IntPtr), Args, DAG, dl);
return CallResult.second; return CallResult.second;
} }