summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp32
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.h3
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,
OpenPOWER on IntegriCloud