diff options
Diffstat (limited to 'llvm/lib/Target')
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index c0ebade2dcd..e27d93cf7c8 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -2252,10 +2252,26 @@ X86TargetLowering::IsEligibleForTailCallOptimization(SDValue Callee, // 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; + if (PerformTailCallOpt) { + if (CalleeCC == CallingConv::Fast && + CallerF->getCallingConv() == CalleeCC) + return true; + return false; + } + + // Do not tail call optimize vararg calls for now. + if (isVarArg) + return false; + + // Don't tail call optimize recursive call. + GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee); + const Function *CalleeF = G ? cast<Function>(G->getGlobal()) : 0; + if (CallerF == CalleeF) + return false; + // If it's an indirect call, conversatively return false if the caller's + // address is taken. + if (!isa<ExternalSymbolSDNode>(Callee) && CallerF->hasAddressTaken()) + return false; // Look for obvious safe cases to perform tail call optimization. // If the callee takes no arguments then go on to check the results of the @@ -2279,9 +2295,7 @@ X86TargetLowering::IsEligibleForTailCallOptimization(SDValue Callee, return true; // If the return types match, then it's safe. - GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee); if (!G) return false; // FIXME: common external symbols? - Function *CalleeF = cast<Function>(G->getGlobal()); const Type *CalleeRetTy = CalleeF->getReturnType(); return CallerRetTy == CalleeRetTy; } |

