Skip to content

Commit 4bcbbe1

Browse files
authored
[BOLT] Refactor fixBranches() (llvm#73752)
Simplify code in fixBranches(). Mostly NFC, accept the x86-specific check for code fragments now takes into account presence of more than two fragments. Should only matter when we split code into multiple fragments and can run fixBranches() more than once. Also, don't replace a branch target with the same one, as such operation may allocate memory for extra MCSymbolRefExpr.
1 parent e3021bd commit 4bcbbe1

File tree

1 file changed

+43
-28
lines changed

1 file changed

+43
-28
lines changed

bolt/lib/Core/BinaryFunction.cpp

Lines changed: 43 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)