83 #define DEBUG_TYPE "tailcallelim"
85 STATISTIC(NumEliminated,
"Number of tail calls removed");
86 STATISTIC(NumRetDuped,
"Number of return duplicated");
87 STATISTIC(NumAccumAdded,
"Number of accumulators introduced");
96 if (!AI->isStaticAlloca())
106 struct AllocaDerivedValueTracker {
110 void walk(
Value *Root) {
114 auto AddUsesToWorklist = [&](
Value *V) {
115 for (
auto &U : V->uses()) {
116 if (!Visited.
insert(&U).second)
122 AddUsesToWorklist(Root);
124 while (!Worklist.
empty()) {
130 case Instruction::Invoke: {
133 CS.isDataOperand(U) &&
CS.doesNotCapture(
CS.getDataOperandNo(U));
134 callUsesLocalStack(CS, IsNocapture);
148 if (U->getOperandNo() == 0)
149 EscapePoints.insert(I);
152 case Instruction::BitCast:
153 case Instruction::GetElementPtr:
154 case Instruction::PHI:
156 case Instruction::AddrSpaceCast:
159 EscapePoints.insert(I);
163 AddUsesToWorklist(I);
167 void callUsesLocalStack(
CallSite CS,
bool IsNocapture) {
188 AllCallsAreTailCalls =
true;
191 AllocaDerivedValueTracker Tracker;
193 if (Arg.hasByValAttr())
198 if (
AllocaInst *AI = dyn_cast<AllocaInst>(&I))
202 bool Modified =
false;
229 VisitType Escaped = UNESCAPED;
231 for (
auto &I : *BB) {
232 if (Tracker.EscapePoints.count(&I))
249 bool SafeToTail =
true;
251 if (isa<Constant>(Arg.getUser()))
253 if (
Argument *
A = dyn_cast<Argument>(Arg.getUser()))
254 if (!
A->hasByValAttr())
262 "marked this readnone call a tail call candidate");
269 if (!IsNoTail && Escaped == UNESCAPED && !Tracker.AllocaUsers.count(CI)) {
272 AllCallsAreTailCalls =
false;
277 auto &State = Visited[SuccBB];
278 if (State < Escaped) {
280 if (State == ESCAPED)
287 if (!WorklistEscaped.
empty()) {
292 while (!WorklistUnescaped.
empty()) {
294 if (Visited[NextBB] == UNESCAPED) {
303 for (
CallInst *CI : DeferredTails) {
304 if (Visited[CI->getParent()] != ESCAPED) {
309 "marked this call a tail call candidate");
313 AllCallsAreTailCalls =
false;
330 if (
LoadInst *
L = dyn_cast<LoadInst>(I)) {
337 const DataLayout &DL =
L->getModule()->getDataLayout();
340 L->getAlignment(), DL,
L))
359 if (isa<Constant>(V))
return true;
363 if (
Argument *Arg = dyn_cast<Argument>(V)) {
381 if (
SwitchInst *
SI = dyn_cast<SwitchInst>(UniquePred->getTerminator()))
382 if (
SI->getCondition() == V)
394 Value *ReturnedValue =
nullptr;
398 if (RI ==
nullptr || RI == IgnoreRI)
continue;
408 if (ReturnedValue && RetOp != ReturnedValue)
410 ReturnedValue = RetOp;
412 return ReturnedValue;
421 "Associative/commutative operations should have 2 args!");
439 while (isa<DbgInfoIntrinsic>(I))
445 bool CannotTailCallElimCallsMarkedTail,
450 if (&BB->
front() == TI)
462 if (BBI == BB->
begin())
469 if (CI->
isTailCall() && CannotTailCallElimCallsMarkedTail)
486 for (; I !=
E && FI != FE; ++
I, ++FI)
487 if (*I != &*FI)
break;
488 if (I ==
E && FI == FE)
497 bool &TailCallsAreMarkedTail,
499 bool CannotTailCallElimCallsMarkedTail) {
510 Value *AccumulatorRecursionEliminationInitVal =
nullptr;
518 for (++BBI; &*BBI !=
Ret; ++BBI) {
525 if ((AccumulatorRecursionEliminationInitVal =
529 AccumulatorRecursionInstr = &*BBI;
541 AccumulatorRecursionEliminationInitVal ==
nullptr &&
551 if (!AccumulatorRecursionEliminationInitVal)
559 "transforming tail recursion to loop");
567 OldEntry->
setName(
"tailrecurse");
573 if (TailCallsAreMarkedTail)
576 NEBI = NewEntry->
begin(); OEBI !=
E; )
577 if (
AllocaInst *AI = dyn_cast<AllocaInst>(OEBI++))
578 if (isa<ConstantInt>(AI->getArraySize()))
579 AI->moveBefore(&*NEBI);
589 I->
getName() +
".tr", InsertPos);
602 if (TailCallsAreMarkedTail && !CI->
isTailCall())
616 if (AccumulatorRecursionEliminationInitVal) {
617 Instruction *AccRecInstr = AccumulatorRecursionInstr;
621 AccumulatorRecursionEliminationInitVal->
getType(),
622 std::distance(PB, PE) + 1,
"accumulator.tr", &OldEntry->
front());
633 AccPN->
addIncoming(AccumulatorRecursionEliminationInitVal, P);
657 if (
ReturnInst *RI = dyn_cast<ReturnInst>(BBI.getTerminator()))
658 RI->setOperand(0, AccPN);
675 bool &TailCallsAreMarkedTail,
677 bool CannotTailCallElimCallsMarkedTail,
689 if (
BranchInst *BI = dyn_cast<BranchInst>(PTI))
690 if (BI->isUnconditional())
694 while (!UncondBranchPreds.
empty()) {
699 <<
"INTO UNCOND BRANCH PRED: " << *Pred);
711 CannotTailCallElimCallsMarkedTail);
721 bool &TailCallsAreMarkedTail,
723 bool CannotTailCallElimCallsMarkedTail,
731 CannotTailCallElimCallsMarkedTail);
738 bool MadeChange =
false;
739 bool AllCallsAreTailCalls =
false;
740 MadeChange |=
markTails(F, AllCallsAreTailCalls);
741 if (!AllCallsAreTailCalls)
750 bool TailCallsAreMarkedTail =
false;
756 bool CanTRETailMarkedCall =
canTRE(F);
769 ArgumentPHIs, !CanTRETailMarkedCall, TTI);
773 ArgumentPHIs, !CanTRETailMarkedCall, TTI);
774 MadeChange |= Change;
783 for (
PHINode *PN : ArgumentPHIs) {
786 PN->replaceAllUsesWith(PNV);
787 PN->eraseFromParent();
806 bool runOnFunction(
Function &
F)
override {
811 F, &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F));
825 return new TailCallElim();
Legacy wrapper pass to provide the GlobalsAAResult object.
Return a value (possibly void), from a function.
void push_back(const T &Elt)
A parsed version of the target data layout string in and methods for querying it. ...
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
BasicBlock * getUniquePredecessor()
Return the predecessor of this block if it has a unique predecessor block.
void addIncoming(Value *V, BasicBlock *BB)
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")
iterator erase(iterator where)
This is the interface for a simple mod/ref and alias analysis over globals.
static bool markTails(Function &F, bool &AllCallsAreTailCalls)
unsigned getNumOperands() const
This class represents a function call, abstracting a target machine's calling convention.
bool mayHaveSideEffects() const
Return true if the instruction may have side effects.
Analysis pass providing the TargetTransformInfo.
bool onlyReadsMemory() const
Determine if the call does not access or only reads memory.
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.
An instruction for reading from memory.
static bool canMoveAboveCall(Instruction *I, CallInst *CI)
Return true if it is safe to move the specified instruction from after the call to before the call...
bool isSafeToLoadUnconditionally(Value *V, unsigned Align, const DataLayout &DL, Instruction *ScanFrom=nullptr, const DominatorTree *DT=nullptr)
Return true if we know that executing a load from this value cannot trap.
void emitOptimizationRemark(LLVMContext &Ctx, const char *PassName, const Function &Fn, const DebugLoc &DLoc, const Twine &Msg)
Emit an optimization-applied message.
StringRef getName() const
Return a constant reference to the value's name.
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.
A Use represents the edge between a Value definition and its users.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
unsigned getNumArgOperands() const
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.
static bool eliminateRecursiveTailCall(CallInst *CI, ReturnInst *Ret, BasicBlock *&OldEntry, bool &TailCallsAreMarkedTail, SmallVectorImpl< PHINode * > &ArgumentPHIs, bool CannotTailCallElimCallsMarkedTail)
void setName(const Twine &Name)
Change the name of the value.
LLVM_NODISCARD bool empty() const
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 isAssociative() const
Return true if the instruction is associative:
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
static bool processReturningBlock(ReturnInst *Ret, BasicBlock *&OldEntry, bool &TailCallsAreMarkedTail, SmallVectorImpl< PHINode * > &ArgumentPHIs, bool CannotTailCallElimCallsMarkedTail, const TargetTransformInfo *TTI)
bool isNoTailCall() const
void takeName(Value *V)
Transfer the name from V to this value.
bool hasOperandBundles() const
Return true if this User has any operand bundles.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
Interval::succ_iterator succ_end(Interval *I)
Subclasses of this class are all able to terminate a basic block.
A set of analyses that are preserved following a run of a transformation pass.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs...ExtraArgs)
Get the result of an analysis pass for a given IR unit.
LLVM Basic Block Representation.
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
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.
Analysis pass providing a never-invalidated alias analysis result.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
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
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.
self_iterator getIterator()
void setTailCall(bool isTC=true)
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
User::op_iterator arg_iterator
arg_iterator - The type of iterator to use when looping over actual arguments at this call site...
static Instruction * firstNonDbg(BasicBlock::iterator I)
static Value * getCommonReturnValue(ReturnInst *IgnoreRI, CallInst *CI)
Check to see if the function containing the specified tail call consistently returns the same runtime...
static CallInst * findTRECandidate(Instruction *TI, bool CannotTailCallElimCallsMarkedTail, const TargetTransformInfo *TTI)
bool mayWriteToMemory() const
Return true if this instruction may modify memory.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Iterator for intrusive lists based on ilist_node.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
InstrTy * getInstruction() const
INITIALIZE_PASS_BEGIN(TailCallElim,"tailcallelim","Tail Call Elimination", false, false) INITIALIZE_PASS_END(TailCallElim
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()
Specialize the methods defined in Value, as we know that an instruction can only be used by other ins...
LLVM_NODISCARD T pop_back_val()
Function * getCalledFunction() const
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 &)
static bool eliminateTailRecursion(Function &F, const TargetTransformInfo *TTI)
static bool canTRE(Function &F)
Scan the specified function for alloca instructions.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
SymbolTableList< 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
Returns the FunctionType for me.
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...
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
ReturnInst * FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB, BasicBlock *Pred)
This method duplicates the specified return instruction into a predecessor which ends in an unconditi...
void preserve()
Mark an analysis as preserved.
iterator_range< op_iterator > arg_operands()
Iteration adapter for range-for loops.
StringRef getValueAsString() const
Return the attribute's value as a string.
static Value * canTransformAccumulatorRecursion(Instruction *I, CallInst *CI)
If the specified instruction can be transformed using accumulator recursion elimination, return the constant which is the start of the accumulator value.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
static bool foldReturnAndProcessPred(BasicBlock *BB, ReturnInst *Ret, BasicBlock *&OldEntry, bool &TailCallsAreMarkedTail, SmallVectorImpl< PHINode * > &ArgumentPHIs, bool CannotTailCallElimCallsMarkedTail, const TargetTransformInfo *TTI)
A container for analyses that lazily runs them and caches their results.
Value * SimplifyInstruction(Instruction *I, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const DominatorTree *DT=nullptr, AssumptionCache *AC=nullptr)
See if we can compute a simplified version of this instruction.
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
const BasicBlock * getParent() const
iterator_range< arg_iterator > args()
an instruction to allocate memory on the stack
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.