Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /// Test if the given instruction is in a position to be optimized
- /// with a tail-call. This roughly means that it's in a block with
- /// a return and there's nothing that needs to be scheduled
- /// between it and the return.
- ///
- /// This function only tests target-independent requirements.
- bool llvm::isInTailCallPosition(const CallBase &Call, const TargetMachine &TM) {
- const BasicBlock *ExitBB = Call.getParent();
- const Instruction *Term = ExitBB->getTerminator();
- const ReturnInst *Ret = dyn_cast<ReturnInst>(Term);
- // The block must end in a return statement or unreachable.
- //
- // FIXME: Decline tailcall if it's not guaranteed and if the block ends in
- // an unreachable, for now. The way tailcall optimization is currently
- // implemented means it will add an epilogue followed by a jump. That is
- // not profitable. Also, if the callee is a special function (e.g.
- // longjmp on x86), it can end up causing miscompilation that has not
- // been fully understood.
- if (!Ret &&
- ((!TM.Options.GuaranteedTailCallOpt &&
- Call.getCallingConv() != CallingConv::Tail) || !isa<UnreachableInst>(Term)))
- 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 (Call.mayHaveSideEffects() || Call.mayReadFromMemory() ||
- !isSafeToSpeculativelyExecute(&Call))
- for (BasicBlock::const_iterator BBI = std::prev(ExitBB->end(), 2);; --BBI) {
- if (&*BBI == &Call)
- break;
- // Debug info intrinsics do not get in the way of tail call optimization.
- if (isa<DbgInfoIntrinsic>(BBI))
- continue;
- // A lifetime end or assume intrinsic should not stop tail call
- // optimization.
- if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(BBI))
- if (II->getIntrinsicID() == Intrinsic::lifetime_end ||
- II->getIntrinsicID() == Intrinsic::assume)
- continue;
- if (BBI->mayHaveSideEffects() || BBI->mayReadFromMemory() ||
- !isSafeToSpeculativelyExecute(&*BBI))
- return false;
- }
- const Function *F = ExitBB->getParent();
- return returnTypeIsEligibleForTailCall(
- F, &Call, Ret, *TM.getSubtargetImpl(*F)->getTargetLowering());
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement