81 #define DEBUG_TYPE "tailcallelim"
83 STATISTIC(NumEliminated,
"Number of tail calls removed");
84 STATISTIC(NumRetDuped,
"Number of return duplicated");
85 STATISTIC(NumAccumAdded,
"Number of accumulators introduced");
102 bool markTails(
Function &
F,
bool &AllCallsAreTailCalls);
105 bool CannotTailCallElimCallsMarkedTail);
108 bool &TailCallsAreMarkedTail,
110 bool CannotTailCallElimCallsMarkedTail);
113 bool &TailCallsAreMarkedTail,
115 bool CannotTailCallElimCallsMarkedTail);
117 bool &TailCallsAreMarkedTail,
119 bool CannotTailCallElimCallsMarkedTail);
127 "Tail Call Elimination",
false,
false)
134 return new TailCallElim();
137 void TailCallElim::getAnalysisUsage(
AnalysisUsage &AU)
const {
148 if (!AI->isStaticAlloca())
157 bool TailCallElim::runOnFunction(
Function &
F) {
158 if (skipOptnoneFunction(F))
164 bool AllCallsAreTailCalls =
false;
165 bool Modified = markTails(F, AllCallsAreTailCalls);
166 if (AllCallsAreTailCalls)
167 Modified |= runTRE(F);
172 struct AllocaDerivedValueTracker {
176 void walk(
Value *Root) {
180 auto AddUsesToWorklist = [&](
Value *V) {
181 for (
auto &U : V->uses()) {
182 if (!Visited.
insert(&U).second)
188 AddUsesToWorklist(Root);
190 while (!Worklist.
empty()) {
196 case Instruction::Invoke: {
198 bool IsNocapture = !
CS.isCallee(U) &&
199 CS.doesNotCapture(
CS.getArgumentNo(U));
200 callUsesLocalStack(
CS, IsNocapture);
214 if (U->getOperandNo() == 0)
215 EscapePoints.insert(I);
218 case Instruction::BitCast:
219 case Instruction::GetElementPtr:
222 case Instruction::AddrSpaceCast:
225 EscapePoints.insert(I);
229 AddUsesToWorklist(I);
233 void callUsesLocalStack(
CallSite CS,
bool IsNocapture) {
251 bool TailCallElim::markTails(
Function &F,
bool &AllCallsAreTailCalls) {
254 AllCallsAreTailCalls =
true;
257 AllocaDerivedValueTracker Tracker;
259 if (Arg.hasByValAttr())
264 if (
AllocaInst *AI = dyn_cast<AllocaInst>(&I))
268 bool Modified =
false;
295 VisitType Escaped = UNESCAPED;
297 for (
auto &I : *BB) {
298 if (Tracker.EscapePoints.count(&I))
313 bool SafeToTail =
true;
315 if (isa<Constant>(Arg.getUser()))
317 if (
Argument *
A = dyn_cast<Argument>(Arg.getUser()))
318 if (!
A->hasByValAttr())
326 "marked this readnone call a tail call candidate");
333 if (Escaped == UNESCAPED && !Tracker.AllocaUsers.count(CI)) {
336 AllCallsAreTailCalls =
false;
341 auto &State = Visited[SuccBB];
342 if (State < Escaped) {
344 if (State == ESCAPED)
351 if (!WorklistEscaped.
empty()) {
356 while (!WorklistUnescaped.
empty()) {
358 if (Visited[NextBB] == UNESCAPED) {
367 for (
CallInst *CI : DeferredTails) {
368 if (Visited[CI->
getParent()] != ESCAPED) {
373 "marked this call a tail call candidate");
377 AllCallsAreTailCalls =
false;
384 bool TailCallElim::runTRE(
Function &F) {
389 TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
391 bool TailCallsAreMarkedTail =
false;
393 bool MadeChange =
false;
398 bool CanTRETailMarkedCall =
CanTRE(F);
409 bool Change = ProcessReturningBlock(
Ret, OldEntry, TailCallsAreMarkedTail,
410 ArgumentPHIs, !CanTRETailMarkedCall);
412 Change = FoldReturnAndProcessPred(BB,
Ret, OldEntry,
413 TailCallsAreMarkedTail, ArgumentPHIs,
414 !CanTRETailMarkedCall);
415 MadeChange |= Change;
424 for (
unsigned i = 0, e = ArgumentPHIs.
size(); i != e; ++i) {
448 if (
LoadInst *L = dyn_cast<LoadInst>(I)) {
479 if (isa<Constant>(V))
return true;
483 if (
Argument *Arg = dyn_cast<Argument>(V)) {
501 if (
SwitchInst *
SI = dyn_cast<SwitchInst>(UniquePred->getTerminator()))
502 if (
SI->getCondition() == V)
514 Value *ReturnedValue =
nullptr;
518 if (RI ==
nullptr || RI == IgnoreRI)
continue;
528 if (ReturnedValue && RetOp != ReturnedValue)
530 ReturnedValue = RetOp;
532 return ReturnedValue;
542 "Associative/commutative operations should have 2 args!");
560 while (isa<DbgInfoIntrinsic>(I))
567 bool CannotTailCallElimCallsMarkedTail) {
571 if (&BB->
front() == TI)
583 if (BBI == BB->
begin())
590 if (CI->
isTailCall() && CannotTailCallElimCallsMarkedTail)
608 for (; I != E && FI != FE; ++
I, ++FI)
609 if (*I != &*FI)
break;
610 if (I == E && FI == FE)
619 bool &TailCallsAreMarkedTail,
621 bool CannotTailCallElimCallsMarkedTail) {
632 Value *AccumulatorRecursionEliminationInitVal =
nullptr;
640 for (++BBI; &*BBI !=
Ret; ++BBI) {
641 if (CanMoveAboveCall(BBI, CI))
continue;
647 if ((AccumulatorRecursionEliminationInitVal =
648 CanTransformAccumulatorRecursion(BBI, CI))) {
651 AccumulatorRecursionInstr = BBI;
663 AccumulatorRecursionEliminationInitVal ==
nullptr &&
673 if (!AccumulatorRecursionEliminationInitVal)
681 "transforming tail recursion to loop");
689 OldEntry->
setName(
"tailrecurse");
695 if (TailCallsAreMarkedTail)
698 NEBI = NewEntry->
begin(); OEBI != E; )
699 if (
AllocaInst *AI = dyn_cast<AllocaInst>(OEBI++))
700 if (isa<ConstantInt>(AI->getArraySize()))
701 AI->moveBefore(NEBI);
711 I->getName() +
".tr", InsertPos);
724 if (TailCallsAreMarkedTail && !CI->
isTailCall())
738 if (AccumulatorRecursionEliminationInitVal) {
739 Instruction *AccRecInstr = AccumulatorRecursionInstr;
744 std::distance(PB, PE) + 1,
745 "accumulator.tr", OldEntry->
begin());
756 AccPN->
addIncoming(AccumulatorRecursionEliminationInitVal, P);
780 if (
ReturnInst *RI = dyn_cast<ReturnInst>(BBI->getTerminator()))
781 RI->setOperand(0, AccPN);
796 bool TailCallElim::FoldReturnAndProcessPred(
BasicBlock *BB,
798 bool &TailCallsAreMarkedTail,
800 bool CannotTailCallElimCallsMarkedTail) {
811 if (
BranchInst *BI = dyn_cast<BranchInst>(PTI))
812 if (BI->isUnconditional())
816 while (!UncondBranchPreds.
empty()) {
819 if (
CallInst *CI = FindTRECandidate(BI, CannotTailCallElimCallsMarkedTail)){
821 <<
"INTO UNCOND BRANCH PRED: " << *Pred);
831 EliminateRecursiveTailCall(CI, RI, OldEntry, TailCallsAreMarkedTail,
833 CannotTailCallElimCallsMarkedTail);
844 bool &TailCallsAreMarkedTail,
846 bool CannotTailCallElimCallsMarkedTail) {
847 CallInst *CI = FindTRECandidate(Ret, CannotTailCallElimCallsMarkedTail);
851 return EliminateRecursiveTailCall(CI, Ret, OldEntry, TailCallsAreMarkedTail,
853 CannotTailCallElimCallsMarkedTail);
ReturnInst - Return a value (possibly void), from a function.
iplist< Instruction >::iterator eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing basic block and deletes it...
void push_back(const T &Elt)
BasicBlock * getUniquePredecessor()
Return the predecessor of this block if it has a unique predecessor block.
void addIncoming(Value *V, BasicBlock *BB)
addIncoming - Add an incoming value to the end of the PHI list
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
LLVM Argument representation.
STATISTIC(NumFunctions,"Total number of functions")
InstrTy * getInstruction() const
unsigned getNumOperands() const
CallInst - This class represents a function call, abstracting a target machine's calling convention...
bool mayHaveSideEffects() const
mayHaveSideEffects - Return true if the instruction may have side effects.
const Function * getParent() const
Return the enclosing method, or null if none.
const Instruction & front() const
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
LoadInst - an instruction for reading from memory.
User::op_iterator arg_iterator
arg_iterator - The type of iterator to use when looping over actual arguments at this call site...
void emitOptimizationRemark(LLVMContext &Ctx, const char *PassName, const Function &Fn, const DebugLoc &DLoc, const Twine &Msg)
Emit an optimization-applied message.
iterator begin()
Instruction iterator methods.
Instruction * getFirstNonPHIOrDbg()
Returns a pointer to the first instruction in this block that is not a PHINode or a debug intrinsic...
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val()
A Use represents the edge between a Value definition and its users.
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
unsigned getNumArgOperands() const
getNumArgOperands - Return the number of call arguments.
bool hasAddressTaken() const
Returns true if there are any uses of this basic block other than direct branches, switches, etc.
void setName(const Twine &Name)
Change the name of the value.
Interval::succ_iterator succ_begin(Interval *I)
succ_begin/succ_end - define methods so that Intervals may be used just like BasicBlocks can with the...
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
bool isAssociative() const
isAssociative - Return true if the instruction is associative:
static bool CanTRE(Function &F)
Scan the specified function for alloca instructions.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
void takeName(Value *V)
Transfer the name from V to this value.
Interval::succ_iterator succ_end(Interval *I)
Subclasses of this class are all able to terminate a basic block.
void setDebugLoc(DebugLoc Loc)
setDebugLoc - Set the debug location information for this instruction.
LLVM Basic Block Representation.
BranchInst - Conditional or Unconditional Branch instruction.
FunctionPass * createTailCallEliminationPass()
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static bool isDynamicConstant(Value *V, CallInst *CI, ReturnInst *RI)
Return true if the specified value is the same when the return would exit as it was when the initial ...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Interval::pred_iterator pred_begin(Interval *I)
pred_begin/pred_end - define methods so that Intervals may be used just like BasicBlocks can with the...
const DebugLoc & getDebugLoc() const
getDebugLoc - Return the debug location for this node as a DebugLoc.
Represent the analysis usage information of a pass.
const InstListType & getInstList() const
Return the underlying instruction list container.
bool doesNotAccessMemory() const
Determine if the call does not access memory.
FunctionPass class - This class is used to implement most global optimizations.
Value * getOperand(unsigned i) const
Interval::pred_iterator pred_end(Interval *I)
bool isCommutative() const
isCommutative - Return true if the instruction is commutative:
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
void setTailCall(bool isTC=true)
iterator erase(iterator where)
static Value * getCommonReturnValue(ReturnInst *IgnoreRI, CallInst *CI)
Check to see if the function containing the specified tail call consistently returns the same runtime...
bool mayWriteToMemory() const
mayWriteToMemory - Return true if this instruction may modify memory.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
INITIALIZE_PASS_BEGIN(TailCallElim,"tailcallelim","Tail Call Elimination", false, false) INITIALIZE_PASS_END(TailCallElim
static Instruction * FirstNonDbg(BasicBlock::iterator I)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
Type * getType() const
All values are typed, get the type of this value.
Instruction * user_back()
user_back - Specialize the methods defined in Value, as we know that an instruction can only be used ...
Function * getCalledFunction() const
getCalledFunction - Return the function called, or null if this is an indirect function invocation...
static BranchInst * Create(BasicBlock *IfTrue, Instruction *InsertBefore=nullptr)
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
const BasicBlock & getEntryBlock() const
void setOperand(unsigned i, Value *Val)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Value * getArgOperand(unsigned i) const
getArgOperand/setArgOperand - Return/set the i-th call argument.
void initializeTailCallElimPass(PassRegistry &)
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
iplist< BasicBlock >::iterator eraseFromParent()
Unlink 'this' from the containing function and delete it.
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
FunctionType * getFunctionType() const
bool hasOneUse() const
Return true if there is exactly one user of this value.
bool callsFunctionThatReturnsTwice() const
callsFunctionThatReturnsTwice - Return true if the function has a call to setjmp or other function th...
ReturnInst * FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB, BasicBlock *Pred)
FoldReturnIntoUncondBranch - This method duplicates the specified return instruction into a predecess...
SwitchInst - Multiway switch.
iterator_range< op_iterator > arg_operands()
arg_operands - iteration adapter for range-for loops.
StringRef getValueAsString() const
Return the attribute's value as a string.
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
unsigned getOpcode() const
getOpcode() returns a member of one of the enums like Instruction::Add.
bool isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom, unsigned Align)
isSafeToLoadUnconditionally - Return true if we know that executing a load from this value cannot tra...
IterTy arg_begin() const
arg_begin/arg_end - Return iterators corresponding to the actual argument list for a call site...
Value * SimplifyInstruction(Instruction *I, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const DominatorTree *DT=nullptr, AssumptionCache *AC=nullptr)
SimplifyInstruction - See if we can compute a simplified version of this instruction.
const BasicBlock * getParent() const
bool onlyReadsMemory() const
Determine if the call does not access or only reads memory.
iterator_range< arg_iterator > args()
AllocaInst - an instruction to allocate memory on the stack.