Skip to content

Commit 48961ba

Browse files
laytonioefriedma-quic
authored andcommitted
[TRE][NFC] Refactor Basic Block Processing
Simplify and improve readability. Differential Revision: https://reviews.llvm.org/D82269
1 parent 4600e21 commit 48961ba

File tree

1 file changed

+56
-82
lines changed

1 file changed

+56
-82
lines changed

llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp

Lines changed: 56 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,10 @@ STATISTIC(NumAccumAdded, "Number of accumulators introduced");
9292
/// Scan the specified function for alloca instructions.
9393
/// If it contains any dynamic allocas, returns false.
9494
static bool canTRE(Function &F) {
95-
// Because of PR962, we don't TRE dynamic allocas.
95+
// FIXME: The code generator produces really bad code when an 'escaping
96+
// alloca' is changed from being a static alloca to being a dynamic alloca.
97+
// Until this is resolved, disable this transformation if that would ever
98+
// happen. This bug is PR962.
9699
return llvm::all_of(instructions(F), [](Instruction &I) {
97100
auto *AI = dyn_cast<AllocaInst>(&I);
98101
return !AI || AI->isStaticAlloca();
@@ -419,7 +422,7 @@ class TailRecursionEliminator {
419422
DomTreeUpdater &DTU)
420423
: F(F), TTI(TTI), AA(AA), ORE(ORE), DTU(DTU) {}
421424

422-
CallInst *findTRECandidate(Instruction *TI,
425+
CallInst *findTRECandidate(BasicBlock *BB,
423426
bool CannotTailCallElimCallsMarkedTail);
424427

425428
void createTailRecurseLoopHeader(CallInst *CI);
@@ -428,14 +431,10 @@ class TailRecursionEliminator {
428431

429432
bool eliminateCall(CallInst *CI);
430433

431-
bool foldReturnAndProcessPred(ReturnInst *Ret,
432-
bool CannotTailCallElimCallsMarkedTail);
433-
434-
bool processReturningBlock(ReturnInst *Ret,
435-
bool CannotTailCallElimCallsMarkedTail);
436-
437434
void cleanupAndFinalize();
438435

436+
bool processBlock(BasicBlock &BB, bool CannotTailCallElimCallsMarkedTail);
437+
439438
public:
440439
static bool eliminate(Function &F, const TargetTransformInfo *TTI,
441440
AliasAnalysis *AA, OptimizationRemarkEmitter *ORE,
@@ -444,8 +443,8 @@ class TailRecursionEliminator {
444443
} // namespace
445444

446445
CallInst *TailRecursionEliminator::findTRECandidate(
447-
Instruction *TI, bool CannotTailCallElimCallsMarkedTail) {
448-
BasicBlock *BB = TI->getParent();
446+
BasicBlock *BB, bool CannotTailCallElimCallsMarkedTail) {
447+
Instruction *TI = BB->getTerminator();
449448

450449
if (&BB->front() == TI) // Make sure there is something before the terminator.
451450
return nullptr;
@@ -672,63 +671,6 @@ bool TailRecursionEliminator::eliminateCall(CallInst *CI) {
672671
return true;
673672
}
674673

675-
bool TailRecursionEliminator::foldReturnAndProcessPred(
676-
ReturnInst *Ret, bool CannotTailCallElimCallsMarkedTail) {
677-
BasicBlock *BB = Ret->getParent();
678-
679-
bool Change = false;
680-
681-
// Make sure this block is a trivial return block.
682-
assert(BB->getFirstNonPHIOrDbg() == Ret &&
683-
"Trying to fold non-trivial return block");
684-
685-
// If the return block contains nothing but the return and PHI's,
686-
// there might be an opportunity to duplicate the return in its
687-
// predecessors and perform TRE there. Look for predecessors that end
688-
// in unconditional branch and recursive call(s).
689-
SmallVector<BranchInst*, 8> UncondBranchPreds;
690-
for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) {
691-
BasicBlock *Pred = *PI;
692-
Instruction *PTI = Pred->getTerminator();
693-
if (BranchInst *BI = dyn_cast<BranchInst>(PTI))
694-
if (BI->isUnconditional())
695-
UncondBranchPreds.push_back(BI);
696-
}
697-
698-
while (!UncondBranchPreds.empty()) {
699-
BranchInst *BI = UncondBranchPreds.pop_back_val();
700-
BasicBlock *Pred = BI->getParent();
701-
if (CallInst *CI =
702-
findTRECandidate(BI, CannotTailCallElimCallsMarkedTail)) {
703-
LLVM_DEBUG(dbgs() << "FOLDING: " << *BB
704-
<< "INTO UNCOND BRANCH PRED: " << *Pred);
705-
FoldReturnIntoUncondBranch(Ret, BB, Pred, &DTU);
706-
707-
// Cleanup: if all predecessors of BB have been eliminated by
708-
// FoldReturnIntoUncondBranch, delete it. It is important to empty it,
709-
// because the ret instruction in there is still using a value which
710-
// eliminateRecursiveTailCall will attempt to remove.
711-
if (!BB->hasAddressTaken() && pred_begin(BB) == pred_end(BB))
712-
DTU.deleteBB(BB);
713-
714-
eliminateCall(CI);
715-
++NumRetDuped;
716-
Change = true;
717-
}
718-
}
719-
720-
return Change;
721-
}
722-
723-
bool TailRecursionEliminator::processReturningBlock(
724-
ReturnInst *Ret, bool CannotTailCallElimCallsMarkedTail) {
725-
CallInst *CI = findTRECandidate(Ret, CannotTailCallElimCallsMarkedTail);
726-
if (!CI)
727-
return false;
728-
729-
return eliminateCall(CI);
730-
}
731-
732674
void TailRecursionEliminator::cleanupAndFinalize() {
733675
// If we eliminated any tail recursions, it's possible that we inserted some
734676
// silly PHI nodes which just merge an initial value (the incoming operand)
@@ -801,6 +743,50 @@ void TailRecursionEliminator::cleanupAndFinalize() {
801743
}
802744
}
803745

746+
bool TailRecursionEliminator::processBlock(
747+
BasicBlock &BB, bool CannotTailCallElimCallsMarkedTail) {
748+
Instruction *TI = BB.getTerminator();
749+
750+
if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
751+
if (BI->isConditional())
752+
return false;
753+
754+
BasicBlock *Succ = BI->getSuccessor(0);
755+
ReturnInst *Ret = dyn_cast<ReturnInst>(Succ->getFirstNonPHIOrDbg());
756+
757+
if (!Ret)
758+
return false;
759+
760+
CallInst *CI = findTRECandidate(&BB, CannotTailCallElimCallsMarkedTail);
761+
762+
if (!CI)
763+
return false;
764+
765+
LLVM_DEBUG(dbgs() << "FOLDING: " << *Succ
766+
<< "INTO UNCOND BRANCH PRED: " << BB);
767+
FoldReturnIntoUncondBranch(Ret, Succ, &BB, &DTU);
768+
++NumRetDuped;
769+
770+
// If all predecessors of Succ have been eliminated by
771+
// FoldReturnIntoUncondBranch, delete it. It is important to empty it,
772+
// because the ret instruction in there is still using a value which
773+
// eliminateCall will attempt to remove. This block can only contain
774+
// instructions that can't have uses, therefore it is safe to remove.
775+
if (pred_empty(Succ))
776+
DTU.deleteBB(Succ);
777+
778+
eliminateCall(CI);
779+
return true;
780+
} else if (isa<ReturnInst>(TI)) {
781+
CallInst *CI = findTRECandidate(&BB, CannotTailCallElimCallsMarkedTail);
782+
783+
if (CI)
784+
return eliminateCall(CI);
785+
}
786+
787+
return false;
788+
}
789+
804790
bool TailRecursionEliminator::eliminate(Function &F,
805791
const TargetTransformInfo *TTI,
806792
AliasAnalysis *AA,
@@ -825,23 +811,11 @@ bool TailRecursionEliminator::eliminate(Function &F,
825811
// TRE would deallocate variable sized allocas, TRE doesn't).
826812
bool CanTRETailMarkedCall = canTRE(F);
827813

814+
// Change any tail recursive calls to loops.
828815
TailRecursionEliminator TRE(F, TTI, AA, ORE, DTU);
829816

830-
// Change any tail recursive calls to loops.
831-
//
832-
// FIXME: The code generator produces really bad code when an 'escaping
833-
// alloca' is changed from being a static alloca to being a dynamic alloca.
834-
// Until this is resolved, disable this transformation if that would ever
835-
// happen. This bug is PR962.
836-
for (Function::iterator BBI = F.begin(), E = F.end(); BBI != E; /*in loop*/) {
837-
BasicBlock *BB = &*BBI++; // foldReturnAndProcessPred may delete BB.
838-
if (ReturnInst *Ret = dyn_cast<ReturnInst>(BB->getTerminator())) {
839-
bool Change = TRE.processReturningBlock(Ret, !CanTRETailMarkedCall);
840-
if (!Change && BB->getFirstNonPHIOrDbg() == Ret)
841-
Change = TRE.foldReturnAndProcessPred(Ret, !CanTRETailMarkedCall);
842-
MadeChange |= Change;
843-
}
844-
}
817+
for (BasicBlock &BB : F)
818+
MadeChange |= TRE.processBlock(BB, !CanTRETailMarkedCall);
845819

846820
TRE.cleanupAndFinalize();
847821

0 commit comments

Comments
 (0)