@@ -3296,7 +3296,7 @@ void BinaryFunction::fixBranches() {
32963296 BB->eraseInstruction (BB->findInstruction (UncondBranch));
32973297
32983298 // Basic block that follows the current one in the final layout.
3299- const BinaryBasicBlock *NextBB =
3299+ const BinaryBasicBlock *const NextBB =
33003300 Layout.getBasicBlockAfter (BB, /* IgnoreSplits=*/ false );
33013301
33023302 if (BB->succ_size () == 1 ) {
@@ -3313,39 +3313,54 @@ void BinaryFunction::fixBranches() {
33133313 assert (CondBranch && " conditional branch expected" );
33143314 const BinaryBasicBlock *TSuccessor = BB->getConditionalSuccessor (true );
33153315 const BinaryBasicBlock *FSuccessor = BB->getConditionalSuccessor (false );
3316- // Check whether we support reversing this branch direction
3317- const bool IsSupported = !MIB->isUnsupportedBranch (*CondBranch);
3318- if (NextBB && NextBB == TSuccessor && IsSupported) {
3316+
3317+ // Eliminate unnecessary conditional branch.
3318+ if (TSuccessor == FSuccessor) {
3319+ BB->removeDuplicateConditionalSuccessor (CondBranch);
3320+ if (TSuccessor != NextBB)
3321+ BB->addBranchInstruction (TSuccessor);
3322+ continue ;
3323+ }
3324+
3325+ // Reverse branch condition and swap successors.
3326+ auto swapSuccessors = [&]() {
3327+ if (MIB->isUnsupportedBranch (*CondBranch))
3328+ return false ;
33193329 std::swap (TSuccessor, FSuccessor);
3320- {
3321- auto L = BC.scopeLock ();
3322- MIB->reverseBranchCondition (*CondBranch, TSuccessor->getLabel (), Ctx);
3323- }
33243330 BB->swapConditionalSuccessors ();
3325- } else {
3331+ auto L = BC.scopeLock ();
3332+ MIB->reverseBranchCondition (*CondBranch, TSuccessor->getLabel (), Ctx);
3333+ return true ;
3334+ };
3335+
3336+ // Check whether the next block is a "taken" target and try to swap it
3337+ // with a "fall-through" target.
3338+ if (TSuccessor == NextBB && swapSuccessors ())
3339+ continue ;
3340+
3341+ // Update conditional branch destination if needed.
3342+ if (MIB->getTargetSymbol (*CondBranch) != TSuccessor->getLabel ()) {
33263343 auto L = BC.scopeLock ();
33273344 MIB->replaceBranchTarget (*CondBranch, TSuccessor->getLabel (), Ctx);
33283345 }
3329- if (TSuccessor == FSuccessor)
3330- BB->removeDuplicateConditionalSuccessor (CondBranch);
3331- if (!NextBB ||
3332- ((NextBB != TSuccessor || !IsSupported) && NextBB != FSuccessor)) {
3333- // If one of the branches is guaranteed to be "long" while the other
3334- // could be "short", then prioritize short for "taken". This will
3335- // generate a sequence 1 byte shorter on x86.
3336- if (IsSupported && BC.isX86 () &&
3337- TSuccessor->getFragmentNum () != FSuccessor->getFragmentNum () &&
3338- BB->getFragmentNum () != TSuccessor->getFragmentNum ()) {
3339- std::swap (TSuccessor, FSuccessor);
3340- {
3341- auto L = BC.scopeLock ();
3342- MIB->reverseBranchCondition (*CondBranch, TSuccessor->getLabel (),
3343- Ctx);
3344- }
3345- BB->swapConditionalSuccessors ();
3346- }
3347- BB->addBranchInstruction (FSuccessor);
3346+
3347+ // No need for the unconditional branch.
3348+ if (FSuccessor == NextBB)
3349+ continue ;
3350+
3351+ if (BC.isX86 ()) {
3352+ // We are going to generate two branches. Check if their targets are in
3353+ // the same fragment as this block. If only one target is in the same
3354+ // fragment, make it the destination of the conditional branch. There
3355+ // is a chance it will be a short branch which takes 5 bytes fewer than
3356+ // a long conditional branch. For unconditional branch, the difference
3357+ // is 4 bytes.
3358+ if (BB->getFragmentNum () != TSuccessor->getFragmentNum () &&
3359+ BB->getFragmentNum () == FSuccessor->getFragmentNum ())
3360+ swapSuccessors ();
33483361 }
3362+
3363+ BB->addBranchInstruction (FSuccessor);
33493364 }
33503365 // Cases where the number of successors is 0 (block ends with a
33513366 // terminator) or more than 2 (switch table) don't require branch
0 commit comments