FastISel doesn't yet handle callee-pop functions.

To support this, move IsCalleePop from X86ISelLowering to X86Subtarget.

llvm-svn: 104866
This commit is contained in:
Dan Gohman 2010-05-27 18:43:40 +00:00
parent 9c84d4a8a0
commit dc53f1cb5c
4 changed files with 33 additions and 25 deletions

View File

@ -1314,6 +1314,10 @@ bool X86FastISel::X86SelectCall(const Instruction *I) {
if (FTy->isVarArg())
return false;
// Fast-isel doesn't know about callee-pop yet.
if (Subtarget->IsCalleePop(FTy->isVarArg(), CC))
return false;
// Handle *simple* calls for now.
const Type *RetTy = CS.getType();
EVT RetVT;

View File

@ -1383,29 +1383,6 @@ ArgsAreStructReturn(const SmallVectorImpl<ISD::InputArg> &Ins) {
return Ins[0].Flags.isSRet();
}
/// IsCalleePop - Determines whether the callee is required to pop its
/// own arguments. Callee pop is necessary to support tail calls.
bool X86TargetLowering::IsCalleePop(bool IsVarArg,
CallingConv::ID CallingConv) const {
if (IsVarArg)
return false;
switch (CallingConv) {
default:
return false;
case CallingConv::X86_StdCall:
return !Subtarget->is64Bit();
case CallingConv::X86_FastCall:
return !Subtarget->is64Bit();
case CallingConv::X86_ThisCall:
return !Subtarget->is64Bit();
case CallingConv::Fast:
return GuaranteedTailCallOpt;
case CallingConv::GHC:
return GuaranteedTailCallOpt;
}
}
/// CCAssignFnForNode - Selects the correct CCAssignFn for a the
/// given CallingConvention value.
CCAssignFn *X86TargetLowering::CCAssignFnForNode(CallingConv::ID CC) const {
@ -1722,7 +1699,7 @@ X86TargetLowering::LowerFormalArguments(SDValue Chain,
}
// Some CCs need callee pop.
if (IsCalleePop(isVarArg, CallConv)) {
if (Subtarget->IsCalleePop(isVarArg, CallConv)) {
FuncInfo->setBytesToPopOnReturn(StackSize); // Callee pops everything.
} else {
FuncInfo->setBytesToPopOnReturn(0); // Callee pops nothing.
@ -2173,7 +2150,7 @@ X86TargetLowering::LowerCall(SDValue Chain, SDValue Callee,
// Create the CALLSEQ_END node.
unsigned NumBytesForCalleeToPush;
if (IsCalleePop(isVarArg, CallConv))
if (Subtarget->IsCalleePop(isVarArg, CallConv))
NumBytesForCalleeToPush = NumBytes; // Callee pops everything
else if (!Is64Bit && !IsTailCallConvention(CallConv) && IsStructRet)
// If this is a call to a struct-return function, the callee

View File

@ -372,3 +372,26 @@ X86Subtarget::X86Subtarget(const std::string &TT, const std::string &FS,
if (StackAlignment)
stackAlignment = StackAlignment;
}
/// IsCalleePop - Determines whether the callee is required to pop its
/// own arguments. Callee pop is necessary to support tail calls.
bool X86Subtarget::IsCalleePop(bool IsVarArg,
CallingConv::ID CallingConv) const {
if (IsVarArg)
return false;
switch (CallingConv) {
default:
return false;
case CallingConv::X86_StdCall:
return !is64Bit();
case CallingConv::X86_FastCall:
return !is64Bit();
case CallingConv::X86_ThisCall:
return !is64Bit();
case CallingConv::Fast:
return GuaranteedTailCallOpt;
case CallingConv::GHC:
return GuaranteedTailCallOpt;
}
}

View File

@ -15,6 +15,7 @@
#define X86SUBTARGET_H
#include "llvm/Target/TargetSubtarget.h"
#include "llvm/CallingConv.h"
#include <string>
namespace llvm {
@ -237,6 +238,9 @@ public:
/// indicating the number of scheduling cycles of backscheduling that
/// should be attempted.
unsigned getSpecialAddressLatency() const;
/// IsCalleePop - Test whether a function should pop its own arguments.
bool IsCalleePop(bool isVarArg, CallingConv::ID CallConv) const;
};
} // End llvm namespace