diff options
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 32 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.h | 3 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/pic.ll | 2 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/tailcall1.ll | 4 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/tailcall2.ll | 12 |
5 files changed, 45 insertions, 8 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, diff --git a/llvm/test/CodeGen/X86/pic.ll b/llvm/test/CodeGen/X86/pic.ll index e886ba06b70..d3c28a055ae 100644 --- a/llvm/test/CodeGen/X86/pic.ll +++ b/llvm/test/CodeGen/X86/pic.ll @@ -190,7 +190,7 @@ bb12: ; LINUX: .L8$pb: ; LINUX: addl $_GLOBAL_OFFSET_TABLE_+(.Lpicbaseref8-.L8$pb), ; LINUX: addl .LJTI8_0@GOTOFF( -; LINUX: jmpl *%ecx +; LINUX: jmpl * ; LINUX: .LJTI8_0: ; LINUX: .long .LBB8_2@GOTOFF diff --git a/llvm/test/CodeGen/X86/tailcall1.ll b/llvm/test/CodeGen/X86/tailcall1.ll index 42f8cdd3841..96c4cad9799 100644 --- a/llvm/test/CodeGen/X86/tailcall1.ll +++ b/llvm/test/CodeGen/X86/tailcall1.ll @@ -4,8 +4,8 @@ declare fastcc i32 @tailcallee(i32 %a1, i32 %a2, i32 %a3, i32 %a4) define fastcc i32 @tailcaller(i32 %in1, i32 %in2) nounwind { entry: - %tmp11 = tail call fastcc i32 @tailcallee(i32 %in1, i32 %in2, i32 %in1, i32 %in2) - ret i32 %tmp11 + %tmp11 = tail call fastcc i32 @tailcallee(i32 %in1, i32 %in2, i32 %in1, i32 %in2) + ret i32 %tmp11 } declare fastcc i8* @alias_callee() diff --git a/llvm/test/CodeGen/X86/tailcall2.ll b/llvm/test/CodeGen/X86/tailcall2.ll new file mode 100644 index 00000000000..f1eb1529c12 --- /dev/null +++ b/llvm/test/CodeGen/X86/tailcall2.ll @@ -0,0 +1,12 @@ +; RUN: llc < %s -march=x86 -asm-verbose=false | FileCheck %s +; RUN: llc < %s -march=x86-64 -asm-verbose=false | FileCheck %s + +define void @bar(i32 %x) nounwind ssp { +entry: +; CHECK: bar: +; CHECK: jmp _foo + tail call void @foo() nounwind + ret void +} + +declare void @foo() |