mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 21:00:29 +00:00
Add "inreg" field to CallSDNode (doesn't increase
its size). Adjust various lowering functions to pass this info through from CallInst. Use it to implement sseregparm returns on X86. Remove X86_ssecall calling convention. llvm-svn: 56677
This commit is contained in:
parent
56b0c33a9d
commit
3f62c40108
@ -57,11 +57,7 @@ namespace CallingConv {
|
||||
/// X86_FastCall - 'fast' analog of X86_StdCall. Passes first two arguments
|
||||
/// in ECX:EDX registers, others - via stack. Callee is responsible for
|
||||
/// stack cleaning.
|
||||
X86_FastCall = 65,
|
||||
|
||||
/// X86_SSEreg - The standard convention except that float and double
|
||||
/// values are returned in XMM0 if SSE support is available.
|
||||
X86_SSECall = 66
|
||||
X86_FastCall = 65
|
||||
};
|
||||
} // End CallingConv namespace
|
||||
|
||||
|
@ -467,7 +467,8 @@ public:
|
||||
/// getCall - Create a CALL node from the given information.
|
||||
///
|
||||
SDValue getCall(unsigned CallingConv, bool IsVarArgs, bool IsTailCall,
|
||||
SDVTList VTs, const SDValue *Operands, unsigned NumOperands);
|
||||
bool isInreg, 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.
|
||||
|
@ -2191,17 +2191,23 @@ class CallSDNode : public SDNode {
|
||||
unsigned CallingConv;
|
||||
bool IsVarArg;
|
||||
bool IsTailCall;
|
||||
// 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;
|
||||
virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
|
||||
protected:
|
||||
friend class SelectionDAG;
|
||||
CallSDNode(unsigned cc, bool isvararg, bool istailcall,
|
||||
CallSDNode(unsigned cc, bool isvararg, bool istailcall, bool isinreg,
|
||||
SDVTList VTs, const SDValue *Operands, unsigned numOperands)
|
||||
: SDNode(ISD::CALL, VTs, Operands, numOperands),
|
||||
CallingConv(cc), IsVarArg(isvararg), IsTailCall(istailcall) {}
|
||||
CallingConv(cc), IsVarArg(isvararg), IsTailCall(istailcall),
|
||||
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,
|
||||
|
@ -994,9 +994,9 @@ public:
|
||||
typedef std::vector<ArgListEntry> ArgListTy;
|
||||
virtual std::pair<SDValue, SDValue>
|
||||
LowerCallTo(SDValue Chain, const Type *RetTy, bool RetSExt, bool RetZExt,
|
||||
bool isVarArg, unsigned CallingConv, bool isTailCall,
|
||||
SDValue Callee, ArgListTy &Args, SelectionDAG &DAG);
|
||||
|
||||
bool isVarArg, bool isInreg, unsigned CallingConv,
|
||||
bool isTailCall, SDValue Callee, ArgListTy &Args,
|
||||
SelectionDAG &DAG);
|
||||
|
||||
/// EmitTargetCodeForMemcpy - Emit target-specific code that performs a
|
||||
/// memcpy. This can be used by targets to provide code sequences for cases
|
||||
|
@ -483,7 +483,6 @@ int LLLexer::LexIdentifier() {
|
||||
KEYWORD("coldcc", COLDCC_TOK);
|
||||
KEYWORD("x86_stdcallcc", X86_STDCALLCC_TOK);
|
||||
KEYWORD("x86_fastcallcc", X86_FASTCALLCC_TOK);
|
||||
KEYWORD("x86_ssecallcc", X86_SSECALLCC_TOK);
|
||||
|
||||
KEYWORD("signext", SIGNEXT);
|
||||
KEYWORD("zeroext", ZEROEXT);
|
||||
|
@ -1085,7 +1085,6 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
|
||||
%token OPAQUE EXTERNAL TARGET TRIPLE ALIGN ADDRSPACE
|
||||
%token DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT
|
||||
%token CC_TOK CCC_TOK FASTCC_TOK COLDCC_TOK X86_STDCALLCC_TOK X86_FASTCALLCC_TOK
|
||||
%token X86_SSECALLCC_TOK
|
||||
%token DATALAYOUT
|
||||
%type <UIntVal> OptCallingConv LocalNumber
|
||||
%type <Attributes> OptAttributes Attribute
|
||||
@ -1252,7 +1251,6 @@ OptCallingConv : /*empty*/ { $$ = CallingConv::C; } |
|
||||
COLDCC_TOK { $$ = CallingConv::Cold; } |
|
||||
X86_STDCALLCC_TOK { $$ = CallingConv::X86_StdCall; } |
|
||||
X86_FASTCALLCC_TOK { $$ = CallingConv::X86_FastCall; } |
|
||||
X86_SSECALLCC_TOK { $$ = CallingConv::X86_SSECall; } |
|
||||
CC_TOK EUINT64VAL {
|
||||
if ((unsigned)$2 != $2)
|
||||
GEN_ERROR("Calling conv too large");
|
||||
|
@ -126,7 +126,10 @@ void CCState::AnalyzeCallOperands(SmallVectorImpl<MVT> &ArgVTs,
|
||||
void CCState::AnalyzeCallResult(CallSDNode *TheCall, CCAssignFn Fn) {
|
||||
for (unsigned i = 0, e = TheCall->getNumRetVals(); i != e; ++i) {
|
||||
MVT VT = TheCall->getRetValType(i);
|
||||
if (Fn(i, VT, VT, CCValAssign::Full, ISD::ArgFlagsTy(), *this)) {
|
||||
ISD::ArgFlagsTy Flags = ISD::ArgFlagsTy();
|
||||
if (TheCall->isInreg())
|
||||
Flags.setInReg();
|
||||
if (Fn(i, VT, VT, CCValAssign::Full, Flags, *this)) {
|
||||
cerr << "Call result #" << i << " has unhandled type "
|
||||
<< VT.getMVTString() << "\n";
|
||||
abort();
|
||||
|
@ -3979,7 +3979,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
|
||||
TargetLowering::ArgListTy Args;
|
||||
std::pair<SDValue,SDValue> CallResult =
|
||||
TLI.LowerCallTo(Tmp1, Type::VoidTy,
|
||||
false, false, false, CallingConv::C, false,
|
||||
false, false, false, false, CallingConv::C, false,
|
||||
DAG.getExternalSymbol("abort", TLI.getPointerTy()),
|
||||
Args, DAG);
|
||||
Result = CallResult.second;
|
||||
@ -5302,8 +5302,8 @@ SDValue SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, SDNode *Node,
|
||||
// Splice the libcall in wherever FindInputOutputChains tells us to.
|
||||
const Type *RetTy = Node->getValueType(0).getTypeForMVT();
|
||||
std::pair<SDValue,SDValue> CallInfo =
|
||||
TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, CallingConv::C,
|
||||
false, Callee, Args, DAG);
|
||||
TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false,
|
||||
CallingConv::C, false, Callee, Args, DAG);
|
||||
|
||||
// Legalize the call sequence, starting with the chain. This will advance
|
||||
// the LastCALLSEQ_END to the legalized version of the CALLSEQ_END node that
|
||||
|
@ -629,7 +629,7 @@ SDValue DAGTypeLegalizer::MakeLibCall(RTLIB::Libcall LC, MVT RetVT,
|
||||
const Type *RetTy = RetVT.getTypeForMVT();
|
||||
std::pair<SDValue,SDValue> CallInfo =
|
||||
TLI.LowerCallTo(DAG.getEntryNode(), RetTy, isSigned, !isSigned, false,
|
||||
CallingConv::C, false, Callee, Args, DAG);
|
||||
false, CallingConv::C, false, Callee, Args, DAG);
|
||||
return CallInfo.first;
|
||||
}
|
||||
|
||||
|
@ -3114,7 +3114,7 @@ SDValue SelectionDAG::getMemcpy(SDValue Chain, SDValue Dst,
|
||||
Entry.Node = Size; Args.push_back(Entry);
|
||||
std::pair<SDValue,SDValue> CallResult =
|
||||
TLI.LowerCallTo(Chain, Type::VoidTy,
|
||||
false, false, false, CallingConv::C, false,
|
||||
false, false, false, false, CallingConv::C, false,
|
||||
getExternalSymbol("memcpy", TLI.getPointerTy()),
|
||||
Args, *this);
|
||||
return CallResult.second;
|
||||
@ -3159,7 +3159,7 @@ SDValue SelectionDAG::getMemmove(SDValue Chain, SDValue Dst,
|
||||
Entry.Node = Size; Args.push_back(Entry);
|
||||
std::pair<SDValue,SDValue> CallResult =
|
||||
TLI.LowerCallTo(Chain, Type::VoidTy,
|
||||
false, false, false, CallingConv::C, false,
|
||||
false, false, false, false, CallingConv::C, false,
|
||||
getExternalSymbol("memmove", TLI.getPointerTy()),
|
||||
Args, *this);
|
||||
return CallResult.second;
|
||||
@ -3210,7 +3210,7 @@ SDValue SelectionDAG::getMemset(SDValue Chain, SDValue Dst,
|
||||
Args.push_back(Entry);
|
||||
std::pair<SDValue,SDValue> CallResult =
|
||||
TLI.LowerCallTo(Chain, Type::VoidTy,
|
||||
false, false, false, CallingConv::C, false,
|
||||
false, false, false, false, CallingConv::C, false,
|
||||
getExternalSymbol("memset", TLI.getPointerTy()),
|
||||
Args, *this);
|
||||
return CallResult.second;
|
||||
@ -3329,7 +3329,7 @@ SDValue SelectionDAG::getMergeValues(const SDValue *Ops, unsigned NumOps,
|
||||
|
||||
SDValue
|
||||
SelectionDAG::getCall(unsigned CallingConv, bool IsVarArgs, bool IsTailCall,
|
||||
SDVTList VTs,
|
||||
bool IsInreg, SDVTList VTs,
|
||||
const SDValue *Operands, unsigned NumOperands) {
|
||||
// Do not include isTailCall in the folding set profile.
|
||||
FoldingSetNodeID ID;
|
||||
@ -3345,7 +3345,7 @@ SelectionDAG::getCall(unsigned CallingConv, bool IsVarArgs, bool IsTailCall,
|
||||
return SDValue(E, 0);
|
||||
}
|
||||
SDNode *N = NodeAllocator.Allocate<CallSDNode>();
|
||||
new (N) CallSDNode(CallingConv, IsVarArgs, IsTailCall,
|
||||
new (N) CallSDNode(CallingConv, IsVarArgs, IsTailCall, IsInreg,
|
||||
VTs, Operands, NumOperands);
|
||||
CSEMap.InsertNode(N, IP);
|
||||
AllNodes.push_back(N);
|
||||
|
@ -4123,8 +4123,9 @@ void SelectionDAGLowering::LowerCallTo(CallSite CS, SDValue Callee,
|
||||
std::pair<SDValue,SDValue> Result =
|
||||
TLI.LowerCallTo(getRoot(), CS.getType(),
|
||||
CS.paramHasAttr(0, Attribute::SExt),
|
||||
CS.paramHasAttr(0, Attribute::ZExt),
|
||||
FTy->isVarArg(), CS.getCallingConv(),
|
||||
CS.paramHasAttr(0, Attribute::ZExt), FTy->isVarArg(),
|
||||
CS.paramHasAttr(0, Attribute::InReg),
|
||||
CS.getCallingConv(),
|
||||
IsTailCall && PerformTailCallOpt,
|
||||
Callee, Args, DAG);
|
||||
if (CS.getType() != Type::VoidTy)
|
||||
@ -5050,8 +5051,9 @@ void SelectionDAGLowering::visitMalloc(MallocInst &I) {
|
||||
Args.push_back(Entry);
|
||||
|
||||
std::pair<SDValue,SDValue> Result =
|
||||
TLI.LowerCallTo(getRoot(), I.getType(), false, false, false, CallingConv::C,
|
||||
PerformTailCallOpt, DAG.getExternalSymbol("malloc", IntPtr),
|
||||
TLI.LowerCallTo(getRoot(), I.getType(), false, false, false, false,
|
||||
CallingConv::C, PerformTailCallOpt,
|
||||
DAG.getExternalSymbol("malloc", IntPtr),
|
||||
Args, DAG);
|
||||
setValue(&I, Result.first); // Pointers always fit in registers
|
||||
DAG.setRoot(Result.second);
|
||||
@ -5065,7 +5067,7 @@ void SelectionDAGLowering::visitFree(FreeInst &I) {
|
||||
Args.push_back(Entry);
|
||||
MVT IntPtr = TLI.getPointerTy();
|
||||
std::pair<SDValue,SDValue> Result =
|
||||
TLI.LowerCallTo(getRoot(), Type::VoidTy, false, false, false,
|
||||
TLI.LowerCallTo(getRoot(), Type::VoidTy, false, false, false, false,
|
||||
CallingConv::C, PerformTailCallOpt,
|
||||
DAG.getExternalSymbol("free", IntPtr), Args, DAG);
|
||||
DAG.setRoot(Result.second);
|
||||
@ -5234,6 +5236,7 @@ void TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG,
|
||||
std::pair<SDValue, SDValue>
|
||||
TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
|
||||
bool RetSExt, bool RetZExt, bool isVarArg,
|
||||
bool isInreg,
|
||||
unsigned CallingConv, bool isTailCall,
|
||||
SDValue Callee,
|
||||
ArgListTy &Args, SelectionDAG &DAG) {
|
||||
@ -5326,10 +5329,11 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
|
||||
LoweredRetTys.push_back(MVT::Other); // Always has a chain.
|
||||
|
||||
// Create the CALL node.
|
||||
SDValue Res = DAG.getCall(CallingConv, isVarArg, isTailCall,
|
||||
SDValue Res = DAG.getCall(CallingConv, isVarArg, isTailCall, isInreg,
|
||||
DAG.getVTList(&LoweredRetTys[0],
|
||||
LoweredRetTys.size()),
|
||||
&Ops[0], Ops.size());
|
||||
&Ops[0], Ops.size()
|
||||
);
|
||||
Chain = Res.getValue(LoweredRetTys.size() - 1);
|
||||
|
||||
// Gather up the call result into a single value.
|
||||
|
@ -748,7 +748,7 @@ ARMTargetLowering::LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
|
||||
Entry.Ty = (const Type *) Type::Int32Ty;
|
||||
Args.push_back(Entry);
|
||||
std::pair<SDValue, SDValue> CallResult =
|
||||
LowerCallTo(Chain, (const Type *) Type::Int32Ty, false, false, false,
|
||||
LowerCallTo(Chain, (const Type *) Type::Int32Ty, false, false, false, false,
|
||||
CallingConv::C, false,
|
||||
DAG.getExternalSymbol("__tls_get_addr", PtrVT), Args, DAG);
|
||||
return CallResult.first;
|
||||
|
@ -318,9 +318,9 @@ static SDValue LowerRET(SDValue Op, SelectionDAG &DAG) {
|
||||
std::pair<SDValue, SDValue>
|
||||
AlphaTargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
|
||||
bool RetSExt, bool RetZExt, bool isVarArg,
|
||||
unsigned CallingConv, bool isTailCall,
|
||||
SDValue Callee, ArgListTy &Args,
|
||||
SelectionDAG &DAG) {
|
||||
bool isInreg, unsigned CallingConv,
|
||||
bool isTailCall, SDValue Callee,
|
||||
ArgListTy &Args, SelectionDAG &DAG) {
|
||||
int NumBytes = 0;
|
||||
if (Args.size() > 6)
|
||||
NumBytes = (Args.size() - 6) * 8;
|
||||
|
@ -81,8 +81,8 @@ namespace llvm {
|
||||
/// actual call.
|
||||
virtual std::pair<SDValue, SDValue>
|
||||
LowerCallTo(SDValue Chain, const Type *RetTy, bool RetSExt, bool RetZExt,
|
||||
bool isVarArg, unsigned CC, bool isTailCall, SDValue Callee,
|
||||
ArgListTy &Args, SelectionDAG &DAG);
|
||||
bool isVarArg, bool isInreg, unsigned CC, bool isTailCall,
|
||||
SDValue Callee, ArgListTy &Args, SelectionDAG &DAG);
|
||||
|
||||
ConstraintType getConstraintType(const std::string &Constraint) const;
|
||||
|
||||
|
@ -304,8 +304,8 @@ void IA64TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG,
|
||||
|
||||
std::pair<SDValue, SDValue>
|
||||
IA64TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
|
||||
bool RetSExt, bool RetZExt,
|
||||
bool isVarArg, unsigned CallingConv,
|
||||
bool RetSExt, bool RetZExt, bool isVarArg,
|
||||
bool isInreg, unsigned CallingConv,
|
||||
bool isTailCall, SDValue Callee,
|
||||
ArgListTy &Args, SelectionDAG &DAG) {
|
||||
|
||||
|
@ -60,7 +60,7 @@ namespace llvm {
|
||||
/// actual call.
|
||||
virtual std::pair<SDValue, SDValue>
|
||||
LowerCallTo(SDValue Chain, const Type *RetTy,
|
||||
bool RetSExt, bool RetZExt, bool isVarArg,
|
||||
bool RetSExt, bool RetZExt, bool isVarArg, bool isInreg,
|
||||
unsigned CC, bool isTailCall,
|
||||
SDValue Callee, ArgListTy &Args, SelectionDAG &DAG);
|
||||
|
||||
|
@ -1240,7 +1240,7 @@ SDValue PPCTargetLowering::LowerTRAMPOLINE(SDValue Op, SelectionDAG &DAG) {
|
||||
// Lower to a call to __trampoline_setup(Trmp, TrampSize, FPtr, ctx_reg)
|
||||
std::pair<SDValue, SDValue> CallResult =
|
||||
LowerCallTo(Chain, Op.getValueType().getTypeForMVT(), false, false,
|
||||
false, CallingConv::C, false,
|
||||
false, false, CallingConv::C, false,
|
||||
DAG.getExternalSymbol("__trampoline_setup", PtrVT),
|
||||
Args, DAG);
|
||||
|
||||
|
@ -65,15 +65,6 @@ def RetCC_X86_32_Fast : CallingConv<[
|
||||
CCDelegateTo<RetCC_X86Common>
|
||||
]>;
|
||||
|
||||
// X86-32 SSEregparm return-value convention.
|
||||
def RetCC_X86_32_SSE : CallingConv<[
|
||||
// The X86-32 sseregparm calling convention returns FP values in XMM0 if the
|
||||
// target has SSE2, otherwise it is the C calling convention.
|
||||
CCIfType<[f32], CCIfSubtarget<"hasSSE2()", CCAssignToReg<[XMM0, XMM1]>>>,
|
||||
CCIfType<[f64], CCIfSubtarget<"hasSSE2()", CCAssignToReg<[XMM0, XMM1]>>>,
|
||||
CCDelegateTo<RetCC_X86Common>
|
||||
]>;
|
||||
|
||||
// X86-64 C return-value convention.
|
||||
def RetCC_X86_64_C : CallingConv<[
|
||||
// The X86-64 calling convention always returns FP values in XMM0.
|
||||
@ -103,8 +94,6 @@ def RetCC_X86_Win64_C : CallingConv<[
|
||||
def RetCC_X86_32 : CallingConv<[
|
||||
// If FastCC, use RetCC_X86_32_Fast.
|
||||
CCIfCC<"CallingConv::Fast", CCDelegateTo<RetCC_X86_32_Fast>>,
|
||||
// If SSECC, use RetCC_X86_32_SSE.
|
||||
CCIfCC<"CallingConv::X86_SSECall", CCDelegateTo<RetCC_X86_32_SSE>>,
|
||||
// Otherwise, use RetCC_X86_32_C.
|
||||
CCDelegateTo<RetCC_X86_32_C>
|
||||
]>;
|
||||
|
@ -5157,9 +5157,9 @@ X86TargetLowering::EmitTargetCodeForMemset(SelectionDAG &DAG,
|
||||
Entry.Node = Size;
|
||||
Args.push_back(Entry);
|
||||
std::pair<SDValue,SDValue> CallResult =
|
||||
LowerCallTo(Chain, Type::VoidTy, false, false, false, CallingConv::C,
|
||||
false, DAG.getExternalSymbol(bzeroEntry, IntPtr),
|
||||
Args, DAG);
|
||||
LowerCallTo(Chain, Type::VoidTy, false, false, false, false,
|
||||
CallingConv::C, false,
|
||||
DAG.getExternalSymbol(bzeroEntry, IntPtr), Args, DAG);
|
||||
return CallResult.second;
|
||||
}
|
||||
|
||||
|
@ -1351,7 +1351,6 @@ void AssemblyWriter::printFunction(const Function *F) {
|
||||
case CallingConv::Cold: Out << "coldcc "; break;
|
||||
case CallingConv::X86_StdCall: Out << "x86_stdcallcc "; break;
|
||||
case CallingConv::X86_FastCall: Out << "x86_fastcallcc "; break;
|
||||
case CallingConv::X86_SSECall: Out << "x86_ssecallcc "; break;
|
||||
default: Out << "cc" << F->getCallingConv() << " "; break;
|
||||
}
|
||||
|
||||
@ -1635,7 +1634,6 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
|
||||
case CallingConv::Cold: Out << " coldcc"; break;
|
||||
case CallingConv::X86_StdCall: Out << " x86_stdcallcc"; break;
|
||||
case CallingConv::X86_FastCall: Out << " x86_fastcallcc"; break;
|
||||
case CallingConv::X86_SSECall: Out << " x86_ssecallcc"; break;
|
||||
default: Out << " cc" << CI->getCallingConv(); break;
|
||||
}
|
||||
|
||||
@ -1680,7 +1678,6 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
|
||||
case CallingConv::Cold: Out << " coldcc"; break;
|
||||
case CallingConv::X86_StdCall: Out << " x86_stdcallcc"; break;
|
||||
case CallingConv::X86_FastCall: Out << " x86_fastcallcc"; break;
|
||||
case CallingConv::X86_SSECall: Out << " x86_ssecallcc"; break;
|
||||
default: Out << " cc" << II->getCallingConv(); break;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user