@@ -682,7 +682,11 @@ bool SimplifyConditionalTailCalls::shouldRewriteBranch(
682682 const BinaryBasicBlock *PredBB,
683683 const MCInst &CondBranch,
684684 const BinaryBasicBlock *BB,
685- const bool DirectionFlag) {
685+ const bool DirectionFlag
686+ ) {
687+ if (BeenOptimized.count (PredBB))
688+ return false ;
689+
686690 const bool IsForward = BinaryFunction::isForwardBranch (PredBB, BB);
687691
688692 if (IsForward)
@@ -725,9 +729,8 @@ uint64_t SimplifyConditionalTailCalls::fixTailCalls(BinaryContext &BC,
725729 uint64_t NumLocalCTCs = 0 ;
726730 uint64_t LocalCTCTakenCount = 0 ;
727731 uint64_t LocalCTCExecCount = 0 ;
728- std::vector<std::tuple<BinaryBasicBlock *,
729- BinaryBasicBlock *,
730- const BinaryBasicBlock *>> NeedsUncondBranch;
732+ std::vector<std::pair<BinaryBasicBlock *,
733+ const BinaryBasicBlock *>> NeedsUncondBranch;
731734
732735 // Will block be deleted by UCE?
733736 auto isValid = [](const BinaryBasicBlock *BB) {
@@ -792,14 +795,17 @@ uint64_t SimplifyConditionalTailCalls::fixTailCalls(BinaryContext &BC,
792795 if (!shouldRewriteBranch (PredBB, *CondBranch, BB, DirectionFlag))
793796 continue ;
794797
798+ // Record this block so that we don't try to optimize it twice.
799+ BeenOptimized.insert (PredBB);
800+
795801 if (CondSucc != BB) {
796802 // Patch the new target address into the conditional branch.
797803 MIA->reverseBranchCondition (*CondBranch, CalleeSymbol, BC.Ctx .get ());
798804 // Since we reversed the condition on the branch we need to change
799805 // the target for the unconditional branch or add a unconditional
800806 // branch to the old target. This has to be done manually since
801807 // fixupBranches is not called after SCTC.
802- NeedsUncondBranch.emplace_back (std::make_tuple (BB, PredBB, CondSucc));
808+ NeedsUncondBranch.emplace_back (std::make_pair ( PredBB, CondSucc));
803809 // Swap branch statistics after swapping the branch targets.
804810 auto BI = PredBB->branch_info_begin ();
805811 std::swap (*BI, *(BI + 1 ));
@@ -840,34 +846,39 @@ uint64_t SimplifyConditionalTailCalls::fixTailCalls(BinaryContext &BC,
840846 // Add unconditional branches at the end of BBs to new successors
841847 // as long as the successor is not a fallthrough.
842848 for (auto &Entry : NeedsUncondBranch) {
843- auto *BB = std::get<0 >(Entry);
844- auto *PredBB = std::get<1 >(Entry);
845- auto *CondSucc = std::get<2 >(Entry);
849+ auto *PredBB = Entry.first ;
850+ auto *CondSucc = Entry.second ;
846851
847852 const MCSymbol *TBB = nullptr ;
848853 const MCSymbol *FBB = nullptr ;
849854 MCInst *CondBranch = nullptr ;
850855 MCInst *UncondBranch = nullptr ;
851856 PredBB->analyzeBranch (TBB, FBB, CondBranch, UncondBranch);
852857
853- // Only add a new branch if the target is not the fall-through.
854- if (BF.getBasicBlockAfter (BB) != CondSucc || isValid (BB) ||
855- PredBB->isCold () != CondSucc->isCold ()) {
856- if (UncondBranch) {
858+ // Find the next valid block. Invalid blocks will be deleted
859+ // so they shouldn't be considered fallthrough targets.
860+ const auto *NextBlock = BF.getBasicBlockAfter (PredBB, false );
861+ while (NextBlock && !isValid (NextBlock)) {
862+ NextBlock = BF.getBasicBlockAfter (NextBlock, false );
863+ }
864+
865+ // Get the unconditional successor to this block.
866+ const auto *PredSucc = PredBB->getSuccessor ();
867+ assert (PredSucc && " The other branch should be a tail call" );
868+
869+ const bool HasFallthrough = (NextBlock && PredSucc == NextBlock);
870+
871+ if (UncondBranch) {
872+ if (HasFallthrough)
873+ PredBB->eraseInstruction (UncondBranch);
874+ else
857875 MIA->replaceBranchTarget (*UncondBranch,
858876 CondSucc->getLabel (),
859877 BC.Ctx .get ());
860- } else {
861- MCInst Branch;
862- auto Result = MIA->createUncondBranch (Branch,
863- CondSucc->getLabel (),
864- BC.Ctx .get ());
865- (void )Result;
866- assert (Result);
867- PredBB->addInstruction (Branch);
868- }
869- } else if (UncondBranch) {
870- PredBB->eraseInstruction (UncondBranch);
878+ } else if (!HasFallthrough) {
879+ MCInst Branch;
880+ MIA->createUncondBranch (Branch, CondSucc->getLabel (), BC.Ctx .get ());
881+ PredBB->addInstruction (Branch);
871882 }
872883 }
873884
0 commit comments