@@ -3296,7 +3296,7 @@ void BinaryFunction::fixBranches() {
3296
3296
BB->eraseInstruction (BB->findInstruction (UncondBranch));
3297
3297
3298
3298
// Basic block that follows the current one in the final layout.
3299
- const BinaryBasicBlock *NextBB =
3299
+ const BinaryBasicBlock *const NextBB =
3300
3300
Layout.getBasicBlockAfter (BB, /* IgnoreSplits=*/ false );
3301
3301
3302
3302
if (BB->succ_size () == 1 ) {
@@ -3313,39 +3313,54 @@ void BinaryFunction::fixBranches() {
3313
3313
assert (CondBranch && " conditional branch expected" );
3314
3314
const BinaryBasicBlock *TSuccessor = BB->getConditionalSuccessor (true );
3315
3315
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 ;
3319
3329
std::swap (TSuccessor, FSuccessor);
3320
- {
3321
- auto L = BC.scopeLock ();
3322
- MIB->reverseBranchCondition (*CondBranch, TSuccessor->getLabel (), Ctx);
3323
- }
3324
3330
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 ()) {
3326
3343
auto L = BC.scopeLock ();
3327
3344
MIB->replaceBranchTarget (*CondBranch, TSuccessor->getLabel (), Ctx);
3328
3345
}
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 ();
3348
3361
}
3362
+
3363
+ BB->addBranchInstruction (FSuccessor);
3349
3364
}
3350
3365
// Cases where the number of successors is 0 (block ends with a
3351
3366
// terminator) or more than 2 (switch table) don't require branch
0 commit comments