diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 13 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 18 |
2 files changed, 10 insertions, 21 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 284b984f0a..495418d999 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -4197,8 +4197,9 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { /// /// This function only tests target-independent requirements. static bool -isInTailCallPosition(const Instruction *I, Attributes CalleeRetAttr, +isInTailCallPosition(CallSite CS, Attributes CalleeRetAttr, const TargetLowering &TLI) { + const Instruction *I = CS.getInstruction(); const BasicBlock *ExitBB = I->getParent(); const TerminatorInst *Term = ExitBB->getTerminator(); const ReturnInst *Ret = dyn_cast<ReturnInst>(Term); @@ -4207,6 +4208,12 @@ isInTailCallPosition(const Instruction *I, Attributes CalleeRetAttr, // The block must end in a return statement or an unreachable. if (!Ret && !isa<UnreachableInst>(Term)) return false; + // Unless we are explicitly forcing tailcall optimization do not tailcall if + // the called function is bitcast'ed. The analysis may not be entirely + // accurate. + if (!PerformTailCallOpt && isa<BitCastInst>(CS.getCalledValue())) + return false; + // If I will have a chain, make sure no other instruction that will have a // chain interposes between I and the return. if (I->mayHaveSideEffects() || I->mayReadFromMemory() || @@ -4348,9 +4355,7 @@ void SelectionDAGBuilder::LowerCallTo(CallSite CS, SDValue Callee, // Check if target-independent constraints permit a tail call here. // Target-dependent constraints are checked within TLI.LowerCallTo. if (isTailCall && - !isInTailCallPosition(CS.getInstruction(), - CS.getAttributes().getRetAttributes(), - TLI)) + !isInTailCallPosition(CS, CS.getAttributes().getRetAttributes(), TLI)) isTailCall = false; std::pair<SDValue,SDValue> Result = diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 6f710ecbe1..9d6b5a39b2 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -2269,7 +2269,6 @@ X86TargetLowering::IsEligibleForTailCallOptimization(SDValue Callee, return false; } - // Look for obvious safe cases to perform tail call optimization that does not // requite ABI changes. This is what gcc calls sibcall. @@ -2324,22 +2323,7 @@ X86TargetLowering::IsEligibleForTailCallOptimization(SDValue Callee, } } - // 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; - - // If the return types match, then it's safe. - // Don't tail call optimize recursive call. - GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee); - if (!G) return false; // FIXME: common external symbols? - if (const Function *CalleeF = dyn_cast<Function>(G->getGlobal())) { - const Type *CalleeRetTy = CalleeF->getReturnType(); - return CallerRetTy == CalleeRetTy; - } - return false; + return true; } FastISel * |