@@ -682,7 +682,11 @@ bool SimplifyConditionalTailCalls::shouldRewriteBranch(
682
682
const BinaryBasicBlock *PredBB,
683
683
const MCInst &CondBranch,
684
684
const BinaryBasicBlock *BB,
685
- const bool DirectionFlag) {
685
+ const bool DirectionFlag
686
+ ) {
687
+ if (BeenOptimized.count (PredBB))
688
+ return false ;
689
+
686
690
const bool IsForward = BinaryFunction::isForwardBranch (PredBB, BB);
687
691
688
692
if (IsForward)
@@ -725,9 +729,8 @@ uint64_t SimplifyConditionalTailCalls::fixTailCalls(BinaryContext &BC,
725
729
uint64_t NumLocalCTCs = 0 ;
726
730
uint64_t LocalCTCTakenCount = 0 ;
727
731
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;
731
734
732
735
// Will block be deleted by UCE?
733
736
auto isValid = [](const BinaryBasicBlock *BB) {
@@ -792,14 +795,17 @@ uint64_t SimplifyConditionalTailCalls::fixTailCalls(BinaryContext &BC,
792
795
if (!shouldRewriteBranch (PredBB, *CondBranch, BB, DirectionFlag))
793
796
continue ;
794
797
798
+ // Record this block so that we don't try to optimize it twice.
799
+ BeenOptimized.insert (PredBB);
800
+
795
801
if (CondSucc != BB) {
796
802
// Patch the new target address into the conditional branch.
797
803
MIA->reverseBranchCondition (*CondBranch, CalleeSymbol, BC.Ctx .get ());
798
804
// Since we reversed the condition on the branch we need to change
799
805
// the target for the unconditional branch or add a unconditional
800
806
// branch to the old target. This has to be done manually since
801
807
// 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));
803
809
// Swap branch statistics after swapping the branch targets.
804
810
auto BI = PredBB->branch_info_begin ();
805
811
std::swap (*BI, *(BI + 1 ));
@@ -840,34 +846,39 @@ uint64_t SimplifyConditionalTailCalls::fixTailCalls(BinaryContext &BC,
840
846
// Add unconditional branches at the end of BBs to new successors
841
847
// as long as the successor is not a fallthrough.
842
848
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 ;
846
851
847
852
const MCSymbol *TBB = nullptr ;
848
853
const MCSymbol *FBB = nullptr ;
849
854
MCInst *CondBranch = nullptr ;
850
855
MCInst *UncondBranch = nullptr ;
851
856
PredBB->analyzeBranch (TBB, FBB, CondBranch, UncondBranch);
852
857
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
857
875
MIA->replaceBranchTarget (*UncondBranch,
858
876
CondSucc->getLabel (),
859
877
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);
871
882
}
872
883
}
873
884
0 commit comments