Mercurial > hg > Members > tobaru > cbc > CbC_llvm
diff lib/Transforms/Scalar/TailRecursionElimination.cpp @ 85:5e5d649e25d2
Update LLVM 3.7
author | Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 19 Feb 2015 15:19:25 +0900 |
parents | e218c19a8176 60c9769439b8 |
children | b0dd3743370f |
line wrap: on
line diff
--- a/lib/Transforms/Scalar/TailRecursionElimination.cpp Mon Oct 27 20:20:15 2014 +0900 +++ b/lib/Transforms/Scalar/TailRecursionElimination.cpp Thu Feb 19 15:19:25 2015 +0900 @@ -63,6 +63,7 @@ #include "llvm/IR/CFG.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/Function.h" @@ -86,6 +87,7 @@ namespace { struct TailCallElim : public FunctionPass { const TargetTransformInfo *TTI; + const DataLayout *DL; static char ID; // Pass identification, replacement for typeid TailCallElim() : FunctionPass(ID) { @@ -136,7 +138,7 @@ char TailCallElim::ID = 0; INITIALIZE_PASS_BEGIN(TailCallElim, "tailcallelim", "Tail Call Elimination", false, false) -INITIALIZE_AG_DEPENDENCY(TargetTransformInfo) +INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) INITIALIZE_PASS_END(TailCallElim, "tailcallelim", "Tail Call Elimination", false, false) @@ -153,7 +155,7 @@ #endif void TailCallElim::getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired<TargetTransformInfo>(); + AU.addRequired<TargetTransformInfoWrapperPass>(); } /// \brief Scan the specified function for alloca instructions. @@ -176,6 +178,8 @@ if (skipOptnoneFunction(F)) return false; + DL = F.getParent()->getDataLayout(); + bool AllCallsAreTailCalls = false; bool Modified = markTails(F, AllCallsAreTailCalls); if (AllCallsAreTailCalls) @@ -194,7 +198,7 @@ auto AddUsesToWorklist = [&](Value *V) { for (auto &U : V->uses()) { - if (!Visited.insert(&U)) + if (!Visited.insert(&U).second) continue; Worklist.push_back(&U); } @@ -406,7 +410,7 @@ // right, so don't even try to convert it... if (F.getFunctionType()->isVarArg()) return false; - TTI = &getAnalysis<TargetTransformInfo>(); + TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F); BasicBlock *OldEntry = nullptr; bool TailCallsAreMarkedTail = false; SmallVector<PHINode*, 8> ArgumentPHIs; @@ -424,18 +428,28 @@ // alloca' is changed from being a static alloca to being a dynamic alloca. // Until this is resolved, disable this transformation if that would ever // happen. This bug is PR962. + SmallVector<BasicBlock*, 8> BBToErase; for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { if (ReturnInst *Ret = dyn_cast<ReturnInst>(BB->getTerminator())) { bool Change = ProcessReturningBlock(Ret, OldEntry, TailCallsAreMarkedTail, ArgumentPHIs, !CanTRETailMarkedCall); - if (!Change && BB->getFirstNonPHIOrDbg() == Ret) + if (!Change && BB->getFirstNonPHIOrDbg() == Ret) { Change = FoldReturnAndProcessPred(BB, Ret, OldEntry, TailCallsAreMarkedTail, ArgumentPHIs, !CanTRETailMarkedCall); + // FoldReturnAndProcessPred may have emptied some BB. Remember to + // erase them. + if (Change && BB->empty()) + BBToErase.push_back(BB); + + } MadeChange |= Change; } } + for (auto BB: BBToErase) + BB->eraseFromParent(); + // If we eliminated any tail recursions, it's possible that we inserted some // silly PHI nodes which just merge an initial value (the incoming operand) // with themselves. Check to see if we did and clean up our mess if so. This @@ -474,7 +488,7 @@ // being loaded from. if (CI->mayWriteToMemory() || !isSafeToLoadUnconditionally(L->getPointerOperand(), L, - L->getAlignment())) + L->getAlignment(), DL)) return false; } } @@ -843,8 +857,20 @@ if (CallInst *CI = FindTRECandidate(BI, CannotTailCallElimCallsMarkedTail)){ DEBUG(dbgs() << "FOLDING: " << *BB << "INTO UNCOND BRANCH PRED: " << *Pred); - EliminateRecursiveTailCall(CI, FoldReturnIntoUncondBranch(Ret, BB, Pred), - OldEntry, TailCallsAreMarkedTail, ArgumentPHIs, + ReturnInst *RI = FoldReturnIntoUncondBranch(Ret, BB, Pred); + + // Cleanup: if all predecessors of BB have been eliminated by + // FoldReturnIntoUncondBranch, we would like to delete it, but we + // can not just nuke it as it is being used as an iterator by our caller. + // Just empty it, and the caller will erase it when it is safe to do so. + // It is important to empty it, because the ret instruction in there is + // still using a value which EliminateRecursiveTailCall will attempt + // to remove. + if (!BB->hasAddressTaken() && pred_begin(BB) == pred_end(BB)) + BB->getInstList().clear(); + + EliminateRecursiveTailCall(CI, RI, OldEntry, TailCallsAreMarkedTail, + ArgumentPHIs, CannotTailCallElimCallsMarkedTail); ++NumRetDuped; Change = true;