87 #define DEBUG_TYPE "tailcallelim" 89 STATISTIC(NumEliminated,
"Number of tail calls removed");
90 STATISTIC(NumRetDuped,
"Number of return duplicated");
91 STATISTIC(NumAccumAdded,
"Number of accumulators introduced");
104 struct AllocaDerivedValueTracker {
108 void walk(
Value *Root) {
112 auto AddUsesToWorklist = [&](
Value *V) {
113 for (
auto &U : V->uses()) {
114 if (!Visited.
insert(&U).second)
120 AddUsesToWorklist(Root);
122 while (!Worklist.
empty()) {
128 case Instruction::Invoke: {
138 callUsesLocalStack(CS, IsNocapture);
152 if (U->getOperandNo() == 0)
153 EscapePoints.insert(I);
156 case Instruction::BitCast:
157 case Instruction::GetElementPtr:
158 case Instruction::PHI:
160 case Instruction::AddrSpaceCast:
163 EscapePoints.insert(I);
167 AddUsesToWorklist(I);
171 void callUsesLocalStack(
CallSite CS,
bool IsNocapture) {
193 AllCallsAreTailCalls =
true;
196 AllocaDerivedValueTracker Tracker;
198 if (
Arg.hasByValAttr())
234 VisitType Escaped = UNESCAPED;
236 for (
auto &
I : *BB) {
237 if (Tracker.EscapePoints.count(&
I))
241 if (!CI || CI->
isTailCall() || isa<DbgInfoIntrinsic>(&
I))
254 bool SafeToTail =
true;
256 if (isa<Constant>(
Arg.getUser()))
258 if (
Argument *A = dyn_cast<Argument>(
Arg.getUser()))
259 if (!A->hasByValAttr())
268 <<
"marked as tail call candidate (readnone)";
276 if (!IsNoTail && Escaped == UNESCAPED && !Tracker.AllocaUsers.count(CI)) {
279 AllCallsAreTailCalls =
false;
284 auto &State = Visited[SuccBB];
285 if (State < Escaped) {
287 if (State == ESCAPED)
294 if (!WorklistEscaped.
empty()) {
299 while (!WorklistUnescaped.
empty()) {
301 if (Visited[NextBB] == UNESCAPED) {
310 for (
CallInst *CI : DeferredTails) {
311 if (Visited[CI->getParent()] != ESCAPED) {
314 LLVM_DEBUG(
dbgs() <<
"Marked as tail call candidate: " << *CI <<
"\n");
318 AllCallsAreTailCalls =
false;
335 if (
LoadInst *L = dyn_cast<LoadInst>(I)) {
342 const DataLayout &DL = L->getModule()->getDataLayout();
345 L->getAlignment(), DL, L))
364 if (isa<Constant>(V))
return true;
386 if (
SwitchInst *
SI = dyn_cast<SwitchInst>(UniquePred->getTerminator()))
387 if (
SI->getCondition() == V)
399 Value *ReturnedValue =
nullptr;
403 if (RI ==
nullptr || RI == IgnoreRI)
continue;
413 if (ReturnedValue && RetOp != ReturnedValue)
415 ReturnedValue = RetOp;
417 return ReturnedValue;
426 "Associative/commutative operations should have 2 args!");
444 while (isa<DbgInfoIntrinsic>(I))
450 bool CannotTailCallElimCallsMarkedTail,
455 if (&BB->
front() == TI)
467 if (BBI == BB->
begin())
474 if (CI->
isTailCall() && CannotTailCallElimCallsMarkedTail)
491 for (; I !=
E && FI != FE; ++
I, ++FI)
492 if (*I != &*FI)
break;
493 if (I ==
E && FI == FE)
514 Value *AccumulatorRecursionEliminationInitVal =
nullptr;
522 for (++BBI; &*BBI !=
Ret; ++BBI) {
530 if ((AccumulatorRecursionEliminationInitVal =
534 AccumulatorRecursionInstr = &*BBI;
546 AccumulatorRecursionEliminationInitVal ==
nullptr &&
556 if (!AccumulatorRecursionEliminationInitVal)
566 <<
"transforming tail recursion into loop";
575 OldEntry->
setName(
"tailrecurse");
582 if (TailCallsAreMarkedTail)
585 NEBI = NewEntry->
begin(); OEBI !=
E; )
586 if (
AllocaInst *AI = dyn_cast<AllocaInst>(OEBI++))
587 if (isa<ConstantInt>(AI->getArraySize()))
588 AI->moveBefore(&*NEBI);
598 I->getName() +
".tr", InsertPos);
599 I->replaceAllUsesWith(PN);
615 if (TailCallsAreMarkedTail && !CI->
isTailCall())
629 if (AccumulatorRecursionEliminationInitVal) {
630 Instruction *AccRecInstr = AccumulatorRecursionInstr;
634 AccumulatorRecursionEliminationInitVal->
getType(),
635 std::distance(PB, PE) + 1,
"accumulator.tr", &OldEntry->
front());
646 AccPN->
addIncoming(AccumulatorRecursionEliminationInitVal, P);
670 if (
ReturnInst *RI = dyn_cast<ReturnInst>(BBI.getTerminator()))
671 RI->setOperand(0, AccPN);
696 "Trying to fold non-trivial return block");
706 if (
BranchInst *BI = dyn_cast<BranchInst>(PTI))
707 if (BI->isUnconditional())
708 UncondBranchPreds.push_back(BI);
711 while (!UncondBranchPreds.empty()) {
712 BranchInst *BI = UncondBranchPreds.pop_back_val();
716 <<
"INTO UNCOND BRANCH PRED: " << *Pred);
727 ArgumentPHIs, AA, ORE, DTU);
746 ArgumentPHIs, AA, ORE, DTU);
756 bool MadeChange =
false;
757 bool AllCallsAreTailCalls =
false;
758 MadeChange |=
markTails(F, AllCallsAreTailCalls, ORE);
759 if (!AllCallsAreTailCalls)
768 bool TailCallsAreMarkedTail =
false;
774 bool CanTRETailMarkedCall =
canTRE(F);
786 ArgumentPHIs, !CanTRETailMarkedCall,
790 BB,
Ret, OldEntry, TailCallsAreMarkedTail, ArgumentPHIs,
791 !CanTRETailMarkedCall, TTI, AA, ORE, DTU);
792 MadeChange |= Change;
801 for (
PHINode *PN : ArgumentPHIs) {
804 PN->replaceAllUsesWith(PNV);
805 PN->eraseFromParent();
832 auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
833 auto *DT = DTWP ? &DTWP->getDomTree() :
nullptr;
834 auto *PDTWP = getAnalysisIfAvailable<PostDominatorTreeWrapperPass>();
835 auto *PDT = PDTWP ? &PDTWP->getPostDomTree() :
nullptr;
842 F, &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F),
843 &getAnalysis<AAResultsWrapperPass>().getAAResults(),
844 &getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE(), DTU);
859 return new TailCallElim();
Legacy wrapper pass to provide the GlobalsAAResult object.
bool hasOperandBundles() const
Return true if this User has any operand bundles.
Return a value (possibly void), from a function.
User::op_iterator arg_iterator
The type of iterator to use when looping over actual arguments at this call site. ...
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.
static bool processReturningBlock(ReturnInst *Ret, BasicBlock *&OldEntry, bool &TailCallsAreMarkedTail, SmallVectorImpl< PHINode *> &ArgumentPHIs, bool CannotTailCallElimCallsMarkedTail, const TargetTransformInfo *TTI, AliasAnalysis *AA, OptimizationRemarkEmitter *ORE, DomTreeUpdater &DTU)
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...
This class represents an incoming formal argument to a Function.
bool doesNotAccessMemory(unsigned OpNo) const
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
iterator erase(iterator where)
This class represents lattice values for constants.
This is the interface for a simple mod/ref and alias analysis over globals.
void push_back(const T &Elt)
This class represents a function call, abstracting a target machine's calling convention.
Analysis pass providing the TargetTransformInfo.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly...
STATISTIC(NumFunctions, "Total number of functions")
Analysis pass which computes a DominatorTree.
An instruction for reading from memory.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
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.
iterator begin()
Instruction iterator methods.
bool onlyReadsMemory() const
Determine if the call does not access or only reads memory.
Value * getArgOperand(unsigned i) const
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
A Use represents the edge between a Value definition and its users.
bool isArgOperand(Value::const_user_iterator UI) const
Determine whether the passed iterator points to an argument operand.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
InstrTy * getInstruction() const
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...
ReturnInst * FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB, BasicBlock *Pred, DomTreeUpdater *DTU=nullptr)
This method duplicates the specified return instruction into a predecessor which ends in an unconditi...
Type * getType() const
All values are typed, get the type of this value.
const BasicBlock * getUniquePredecessor() const
Return the predecessor of this block if it has a unique predecessor block.
unsigned getDataOperandNo(Value::const_user_iterator UI) const
Given a value use iterator, return the data operand corresponding to it.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
iterator_range< User::op_iterator > arg_operands()
void takeName(Value *V)
Transfer the name from V to this value.
Value * getOperand(unsigned i) const
Interval::succ_iterator succ_end(Interval *I)
static bool eliminateRecursiveTailCall(CallInst *CI, ReturnInst *Ret, BasicBlock *&OldEntry, bool &TailCallsAreMarkedTail, SmallVectorImpl< PHINode *> &ArgumentPHIs, AliasAnalysis *AA, OptimizationRemarkEmitter *ORE, DomTreeUpdater &DTU)
const BasicBlock & getEntryBlock() const
static bool runOnFunction(Function &F, bool PostInlining)
static MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
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.
LLVM Basic Block Representation.
void deleteBB(BasicBlock *DelBB)
Delete DelBB.
Conditional or Unconditional Branch instruction.
FunctionPass * createTailCallEliminationPass()
static bool foldReturnAndProcessPred(BasicBlock *BB, ReturnInst *Ret, BasicBlock *&OldEntry, bool &TailCallsAreMarkedTail, SmallVectorImpl< PHINode *> &ArgumentPHIs, bool CannotTailCallElimCallsMarkedTail, const TargetTransformInfo *TTI, AliasAnalysis *AA, OptimizationRemarkEmitter *ORE, DomTreeUpdater &DTU)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
const Instruction & front() const
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 ...
A manager for alias analyses.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool mayHaveSideEffects() const
Return true if the instruction may have side effects.
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...
bool isAssociative() const LLVM_READONLY
Return true if the instruction is associative:
Represent the analysis usage information of a pass.
Analysis pass providing a never-invalidated alias analysis result.
FunctionPass class - This class is used to implement most global optimizations.
Interval::pred_iterator pred_end(Interval *I)
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
self_iterator getIterator()
bool isDataOperand(Value::const_user_iterator UI) const
Determine whether the passed iterator points to a data operand.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
bool doesNotCapture(unsigned OpNo) const
Determine whether this data operand is not captured.
void setTailCall(bool isTC=true)
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
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)
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
bool hasAddressTaken() const
Returns true if there are any uses of this basic block other than direct branches, switches, etc.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
const InstListType & getInstList() const
Return the underlying instruction list container.
void insertEdge(BasicBlock *From, BasicBlock *To)
Notify all available trees on an edge insertion.
Iterator for intrusive lists based on ilist_node.
unsigned getNumOperands() const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Analysis pass which computes a PostDominatorTree.
Module.h This file contains the declarations for the Module class.
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()
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...
bool isCommutative() const
Return true if the instruction is commutative:
void setOperand(unsigned i, Value *Val)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionType * getFunctionType() const
Returns the FunctionType for me.
void initializeTailCallElimPass(PassRegistry &)
static bool canTRE(Function &F)
Scan the specified function for alloca instructions.
INITIALIZE_PASS_BEGIN(TailCallElim, "tailcallelim", "Tail Call Elimination", false, false) INITIALIZE_PASS_END(TailCallElim
amdgpu Simplify well known AMD library false Value Value * Arg
static bool canMoveAboveCall(Instruction *I, CallInst *CI, AliasAnalysis *AA)
Return true if it is safe to move the specified instruction from after the call to before the call...
LLVM_NODISCARD bool isModSet(const ModRefInfo MRI)
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
void recalculate(Function &F)
Recalculate all available trees and flush all BasicBlocks awaiting deletion immediately.
unsigned getNumArgOperands() const
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_NODISCARD bool empty() const
StringRef getValueAsString() const
Return the attribute's value as a string.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation.
const Function * getParent() const
Return the enclosing method, or null if none.
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
void preserve()
Mark an analysis as preserved.
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
bool isByValArgument(unsigned ArgNo) const
Determine whether this argument is passed by value.
bool callsFunctionThatReturnsTwice() const
callsFunctionThatReturnsTwice - Return true if the function has a call to setjmp or other function th...
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.
static bool eliminateTailRecursion(Function &F, const TargetTransformInfo *TTI, AliasAnalysis *AA, OptimizationRemarkEmitter *ORE, DomTreeUpdater &DTU)
unsigned getArgumentNo(Value::const_user_iterator I) const
Given a value use iterator, returns the argument that corresponds to it.
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
bool hasOneUse() const
Return true if there is exactly one user of this value.
bool isNoTailCall() const
inst_range instructions(Function *F)
A container for analyses that lazily runs them and caches their results.
const Instruction * getFirstNonPHIOrDbg() const
Returns a pointer to the first instruction in this block that is not a PHINode or a debug intrinsic...
Legacy analysis pass which computes a DominatorTree.
bool isStaticAlloca() const
Return true if this alloca is in the entry block of the function and is a constant size...
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object...
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc)
getModRefInfo (for call sites) - Return information about whether a particular call site modifies or ...
static bool markTails(Function &F, bool &AllCallsAreTailCalls, OptimizationRemarkEmitter *ORE)
Value * SimplifyInstruction(Instruction *I, const SimplifyQuery &Q, OptimizationRemarkEmitter *ORE=nullptr)
See if we can compute a simplified version of this instruction.
iterator_range< arg_iterator > args()
const BasicBlock * getParent() const
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.