From 297a494f557ba268535a18dfc47dbc18613e13c1 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Fri, 29 Jan 2010 06:45:59 +0000 Subject: Catch more trivial tail call opportunities: no inputs and output types match. llvm-svn: 94804 --- llvm/lib/Target/X86/X86ISelLowering.cpp | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) (limited to 'llvm/lib/Target/X86/X86ISelLowering.cpp') diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index f868b75bd8b..5dbe0bb8f0a 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -2246,27 +2246,35 @@ X86TargetLowering::IsEligibleForTailCallOptimization(SDValue Callee, const SmallVectorImpl &Outs, const SmallVectorImpl &Ins, SelectionDAG& DAG) const { - // 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; + // If -tailcallopt is specified, make fastcc functions tail-callable. + const Function *CallerF = DAG.getMachineFunction().getFunction(); + if (PerformTailCallOpt && + CalleeCC == CallingConv::Fast && + CallerF->getCallingConv() == CalleeCC) + return true; + // Look for obvious safe cases to perform tail call optimization. - // For now, only consider callees which take no arguments and no return - // values. + // For now, only consider callees which take no arguments. 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(); + // If the caller does not return a value, then this is obviously safe. + // This is one case where it's safe to perform this optimization even + // if the return types do not match. + const Type *CallerRetTy = CallerF->getReturnType(); + if (CallerRetTy->isVoidTy()) + return true; - return false; + // If the return types match, then it's safe. + GlobalAddressSDNode *G = dyn_cast(Callee); + if (!G) return false; // FIXME: common external symbols? + Function *CalleeF = cast(G->getGlobal()); + const Type *CalleeRetTy = CalleeF->getReturnType(); + return CallerRetTy == CalleeRetTy; } FastISel * -- cgit v1.2.3