53 #define DEBUG_TYPE "tailcallelim"
79 STATISTIC(NumEliminated,
"Number of tail calls removed");
80 STATISTIC(NumRetDuped,
"Number of return duplicated");
81 STATISTIC(NumAccumAdded,
"Number of accumulators introduced");
98 bool CannotTailCallElimCallsMarkedTail);
101 bool &TailCallsAreMarkedTail,
103 bool CannotTailCallElimCallsMarkedTail);
106 bool &TailCallsAreMarkedTail,
108 bool CannotTailCallElimCallsMarkedTail);
110 bool &TailCallsAreMarkedTail,
112 bool CannotTailCallElimCallsMarkedTail);
120 "Tail Call Elimination",
false,
false)
127 return new TailCallElim();
130 void TailCallElim::getAnalysisUsage(
AnalysisUsage &AU)
const {
150 AllocaCaptureTracker() : Captured(
false) {}
155 Value *V = U->getUser();
156 if (isa<CallInst>(V) || isa<InvokeInst>(V))
157 UsesAlloca.insert(V);
162 if (isa<ReturnInst>(U->getUser()))
173 bool TailCallElim::runOnFunction(
Function &
F) {
178 TTI = &getAnalysis<TargetTransformInfo>();
180 bool TailCallsAreMarkedTail =
false;
182 bool MadeChange =
false;
188 bool CanTRETailMarkedCall =
true;
191 AllocaCaptureTracker ACT;
195 CanTRETailMarkedCall &=
CanTRE(AI);
210 if (ACT.UsesAlloca.empty()) {
212 if (
ReturnInst *
Ret = dyn_cast<ReturnInst>(BB->getTerminator())) {
213 bool Change = ProcessReturningBlock(
Ret, OldEntry, TailCallsAreMarkedTail,
214 ArgumentPHIs, !CanTRETailMarkedCall);
215 if (!Change && BB->getFirstNonPHIOrDbg() ==
Ret)
216 Change = FoldReturnAndProcessPred(BB,
Ret, OldEntry,
217 TailCallsAreMarkedTail, ArgumentPHIs,
218 !CanTRETailMarkedCall);
219 MadeChange |= Change;
229 if (!ArgumentPHIs.
empty()) {
230 for (
unsigned i = 0, e = ArgumentPHIs.
size(); i != e; ++i) {
250 if (
CallInst *CI = dyn_cast<CallInst>(
I)) {
251 if (!ACT.UsesAlloca.count(CI)) {
274 if (
LoadInst *L = dyn_cast<LoadInst>(I)) {
307 if (isa<Constant>(V))
return true;
311 if (
Argument *Arg = dyn_cast<Argument>(V)) {
329 if (
SwitchInst *SI = dyn_cast<SwitchInst>(UniquePred->getTerminator()))
330 if (SI->getCondition() == V)
331 return SI->getDefaultDest() != RI->
getParent();
343 Value *ReturnedValue = 0;
347 if (RI == 0 || RI == IgnoreRI)
continue;
357 if (ReturnedValue && RetOp != ReturnedValue)
359 ReturnedValue = RetOp;
361 return ReturnedValue;
372 "Associative/commutative operations should have 2 args!");
390 while (isa<DbgInfoIntrinsic>(I))
397 bool CannotTailCallElimCallsMarkedTail) {
401 if (&BB->
front() == TI)
413 if (BBI == BB->
begin())
420 if (CI->
isTailCall() && CannotTailCallElimCallsMarkedTail)
438 for (; I != E && FI != FE; ++
I, ++FI)
439 if (*I != &*FI)
break;
440 if (I == E && FI == FE)
449 bool &TailCallsAreMarkedTail,
451 bool CannotTailCallElimCallsMarkedTail) {
462 Value *AccumulatorRecursionEliminationInitVal = 0;
470 for (++BBI; &*BBI !=
Ret; ++BBI) {
471 if (CanMoveAboveCall(BBI, CI))
continue;
477 if ((AccumulatorRecursionEliminationInitVal =
478 CanTransformAccumulatorRecursion(BBI, CI))) {
481 AccumulatorRecursionInstr = BBI;
493 AccumulatorRecursionEliminationInitVal == 0 &&
503 if (!AccumulatorRecursionEliminationInitVal)
516 OldEntry->
setName(
"tailrecurse");
522 if (TailCallsAreMarkedTail)
525 NEBI = NewEntry->
begin(); OEBI != E; )
526 if (
AllocaInst *AI = dyn_cast<AllocaInst>(OEBI++))
527 if (isa<ConstantInt>(AI->getArraySize()))
528 AI->moveBefore(NEBI);
538 I->getName() +
".tr", InsertPos);
551 if (TailCallsAreMarkedTail && !CI->
isTailCall())
565 if (AccumulatorRecursionEliminationInitVal) {
566 Instruction *AccRecInstr = AccumulatorRecursionInstr;
571 std::distance(PB, PE) + 1,
572 "accumulator.tr", OldEntry->
begin());
583 AccPN->
addIncoming(AccumulatorRecursionEliminationInitVal, P);
607 if (
ReturnInst *RI = dyn_cast<ReturnInst>(BBI->getTerminator()))
608 RI->setOperand(0, AccPN);
623 bool TailCallElim::FoldReturnAndProcessPred(
BasicBlock *BB,
625 bool &TailCallsAreMarkedTail,
627 bool CannotTailCallElimCallsMarkedTail) {
638 if (
BranchInst *BI = dyn_cast<BranchInst>(PTI))
639 if (BI->isUnconditional())
643 while (!UncondBranchPreds.
empty()) {
646 if (
CallInst *CI = FindTRECandidate(BI, CannotTailCallElimCallsMarkedTail)){
648 <<
"INTO UNCOND BRANCH PRED: " << *Pred);
650 OldEntry, TailCallsAreMarkedTail, ArgumentPHIs,
651 CannotTailCallElimCallsMarkedTail);
662 bool &TailCallsAreMarkedTail,
664 bool CannotTailCallElimCallsMarkedTail) {
665 CallInst *CI = FindTRECandidate(Ret, CannotTailCallElimCallsMarkedTail);
669 return EliminateRecursiveTailCall(CI, Ret, OldEntry, TailCallsAreMarkedTail,
671 CannotTailCallElimCallsMarkedTail);
void push_back(const T &Elt)
BasicBlock * getUniquePredecessor()
Return this block if it has a unique predecessor block. Otherwise return a null pointer.
void addIncoming(Value *V, BasicBlock *BB)
static PassRegistry * getPassRegistry()
LLVMContext & getContext() const
LLVM Argument representation.
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
unsigned getNumOperands() const
bool mayHaveSideEffects() const
const Function * getParent() const
Return the enclosing method, or null if none.
const Instruction & front() const
bool isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom, unsigned Align, const DataLayout *TD=0)
void setDebugLoc(const DebugLoc &Loc)
setDebugLoc - Set the debug location information for this instruction.
AnalysisUsage & addRequired()
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val()
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
unsigned getNumArgOperands() const
static BranchInst * Create(BasicBlock *IfTrue, Instruction *InsertBefore=0)
void setName(const Twine &Name)
ID
LLVM Calling Convention Representation.
STATISTIC(NumEliminated,"Number of tail calls removed")
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
bool isAssociative() const
void replaceAllUsesWith(Value *V)
User::op_iterator arg_iterator
LLVM Basic Block Representation.
FunctionPass * createTailCallEliminationPass()
static bool isDynamicConstant(Value *V, CallInst *CI, ReturnInst *RI)
Interval::pred_iterator pred_begin(Interval *I)
const DebugLoc & getDebugLoc() const
getDebugLoc - Return the debug location for this node as a DebugLoc.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", Instruction *InsertBefore=0)
ItTy next(ItTy it, Dist n)
const InstListType & getInstList() const
Return the underlying instruction list container.
Value * getOperand(unsigned i) const
Interval::pred_iterator pred_end(Interval *I)
bool isCommutative() const
#define INITIALIZE_AG_DEPENDENCY(depName)
Value * SimplifyInstruction(Instruction *I, const DataLayout *TD=0, const TargetLibraryInfo *TLI=0, const DominatorTree *DT=0)
bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures, bool StoreCaptures)
iterator erase(iterator where)
static Value * getCommonReturnValue(ReturnInst *IgnoreRI, CallInst *CI)
bool mayWriteToMemory() const
INITIALIZE_PASS_BEGIN(TailCallElim,"tailcallelim","Tail Call Elimination", false, false) INITIALIZE_PASS_END(TailCallElim
static Instruction * FirstNonDbg(BasicBlock::iterator I)
Function * getCalledFunction() const
const BasicBlock & getEntryBlock() const
static bool CanTRE(AllocaInst *AI)
void setOperand(unsigned i, Value *Val)
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
Value * getArgOperand(unsigned i) const
void initializeTailCallElimPass(PassRegistry &)
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 callsFunctionThatReturnsTwice() const
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=0, BasicBlock *InsertBefore=0)
Creates a new BasicBlock.
ReturnInst * FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB, BasicBlock *Pred)
LLVM Value Representation.
const Value * getArraySize() const
const BasicBlock * getParent() const