diff options
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 32 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.h | 3 |
2 files changed, 30 insertions, 5 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 6e6447574e4..eb7f4815915 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// +#define DEBUG_TYPE "x86-isel" #include "X86.h" #include "X86InstrBuilder.h" #include "X86ISelLowering.h" @@ -39,6 +40,7 @@ #include "llvm/MC/MCSymbol.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/VectorExtras.h" #include "llvm/Support/CommandLine.h" @@ -48,6 +50,8 @@ #include "llvm/Support/raw_ostream.h" using namespace llvm; +STATISTIC(NumTailCalls, "Number of tail calls"); + static cl::opt<bool> DisableMMX("disable-mmx", cl::Hidden, cl::desc("Disable use of MMX")); @@ -1788,7 +1792,7 @@ X86TargetLowering::LowerCall(SDValue Chain, SDValue Callee, if (isTailCall) // Check if it's really possible to do a tail call. isTailCall = IsEligibleForTailCallOptimization(Callee, CallConv, isVarArg, - Ins, DAG); + Outs, Ins, DAG); assert(!(isVarArg && CallConv == CallingConv::Fast) && "Var args not supported with calling convention fastcc"); @@ -1806,6 +1810,8 @@ X86TargetLowering::LowerCall(SDValue Chain, SDValue Callee, int FPDiff = 0; if (isTailCall) { + ++NumTailCalls; + // Lower arguments at fp - stackoffset + fpdiff. unsigned NumBytesCallerPushed = MF.getInfo<X86MachineFunctionInfo>()->getBytesToPopOnReturn(); @@ -2237,11 +2243,29 @@ bool X86TargetLowering::IsEligibleForTailCallOptimization(SDValue Callee, CallingConv::ID CalleeCC, bool isVarArg, - const SmallVectorImpl<ISD::InputArg> &Ins, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, SelectionDAG& DAG) const { - if (CalleeCC == CallingConv::Fast && - DAG.getMachineFunction().getFunction()->getCallingConv() == CalleeCC) + // If -tailcallopt is specified, make fastcc functions tail-callable. + const Function *F = DAG.getMachineFunction().getFunction(); + if (PerformTailCallOpt && + CalleeCC == CallingConv::Fast && F->getCallingConv() == CalleeCC) return true; + + if (CalleeCC != CallingConv::Fast && + CalleeCC != CallingConv::C) + return false; + + // Look for obvious safe cases to perform tail call optimization. + // For now, only consider callees which take no arguments and no return + // values. + if (!Outs.empty()) + return false; + + if (Ins.empty()) + // If the caller does not return a value, then this is obviously safe. + return F->getReturnType()->isVoidTy(); + return false; } diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h index 0642b392dd4..193ef054c99 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.h +++ b/llvm/lib/Target/X86/X86ISelLowering.h @@ -630,7 +630,8 @@ namespace llvm { bool IsEligibleForTailCallOptimization(SDValue Callee, CallingConv::ID CalleeCC, bool isVarArg, - const SmallVectorImpl<ISD::InputArg> &Ins, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, SelectionDAG& DAG) const; bool IsCalleePop(bool isVarArg, CallingConv::ID CallConv); SDValue EmitTailCallLoadRetAddr(SelectionDAG &DAG, SDValue &OutRetAddr, |