aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/BranchRelaxation.cpp
diff options
context:
space:
mode:
authorDaniel Hoekwater <hoekwater@google.com>2023-08-21 17:24:26 +0000
committerDaniel Hoekwater <hoekwater@google.com>2023-08-21 17:29:47 +0000
commite223e4567722661f1b32aa052cd13d9f47b896d9 (patch)
tree6a4a6e9c16c5070be74f8b7d894783f1865ada82 /llvm/lib/CodeGen/BranchRelaxation.cpp
parent5f771c9936b828d5fc017ad558e84702500df99c (diff)
downloadllvm-e223e4567722661f1b32aa052cd13d9f47b896d9.zip
llvm-e223e4567722661f1b32aa052cd13d9f47b896d9.tar.gz
llvm-e223e4567722661f1b32aa052cd13d9f47b896d9.tar.bz2
Reland "[AArch64][CodeGen] Avoid inverting hot branches during relaxation""
This is a reland of 46d2d7599d9ed5e68fb53e910feb10d47ee2667b, which was reverted because of breaking build https://lab.llvm.org/buildbot/#/builders/21/builds/78779. However, this buildbot is spuriously broken due to Flang::underscoring.f90 being nondeterministic.
Diffstat (limited to 'llvm/lib/CodeGen/BranchRelaxation.cpp')
-rw-r--r--llvm/lib/CodeGen/BranchRelaxation.cpp63
1 files changed, 61 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/BranchRelaxation.cpp b/llvm/lib/CodeGen/BranchRelaxation.cpp
index 378f8bf..2995732 100644
--- a/llvm/lib/CodeGen/BranchRelaxation.cpp
+++ b/llvm/lib/CodeGen/BranchRelaxation.cpp
@@ -79,6 +79,10 @@ class BranchRelaxation : public MachineFunctionPass {
};
SmallVector<BasicBlockInfo, 16> BlockInfo;
+
+ // The basic block after which trampolines are inserted. This is the last
+ // basic block that isn't in the cold section.
+ MachineBasicBlock *TrampolineInsertionPoint = nullptr;
std::unique_ptr<RegScavenger> RS;
LivePhysRegs LiveRegs;
@@ -166,16 +170,27 @@ LLVM_DUMP_METHOD void BranchRelaxation::dumpBBs() {
void BranchRelaxation::scanFunction() {
BlockInfo.clear();
BlockInfo.resize(MF->getNumBlockIDs());
+ TrampolineInsertionPoint = nullptr;
// First thing, compute the size of all basic blocks, and see if the function
// has any inline assembly in it. If so, we have to be conservative about
// alignment assumptions, as we don't know for sure the size of any
- // instructions in the inline assembly.
- for (MachineBasicBlock &MBB : *MF)
+ // instructions in the inline assembly. At the same time, place the
+ // trampoline insertion point at the end of the hot portion of the function.
+ for (MachineBasicBlock &MBB : *MF) {
BlockInfo[MBB.getNumber()].Size = computeBlockSize(MBB);
+ if (MBB.getSectionID() != MBBSectionID::ColdSectionID)
+ TrampolineInsertionPoint = &MBB;
+ }
+
// Compute block offsets and known bits.
adjustBlockOffsets(*MF->begin());
+
+ if (TrampolineInsertionPoint == nullptr) {
+ LLVM_DEBUG(dbgs() << " No suitable trampoline insertion point found in "
+ << MF->getName() << ".\n");
+ }
}
/// computeBlockSize - Compute the size for MBB.
@@ -376,6 +391,50 @@ bool BranchRelaxation::fixupConditionalBranch(MachineInstr &MI) {
assert(!Fail && "branches to be relaxed must be analyzable");
(void)Fail;
+ // Since cross-section conditional branches to the cold section are rarely
+ // taken, try to avoid inverting the condition. Instead, add a "trampoline
+ // branch", which unconditionally branches to the branch destination. Place
+ // the trampoline branch at the end of the function and retarget the
+ // conditional branch to the trampoline.
+ // tbz L1
+ // =>
+ // tbz L1Trampoline
+ // ...
+ // L1Trampoline: b L1
+ if (MBB->getSectionID() != TBB->getSectionID() &&
+ TBB->getSectionID() == MBBSectionID::ColdSectionID &&
+ TrampolineInsertionPoint != nullptr) {
+ // If the insertion point is out of range, we can't put a trampoline there.
+ NewBB =
+ createNewBlockAfter(*TrampolineInsertionPoint, MBB->getBasicBlock());
+
+ if (isBlockInRange(MI, *NewBB)) {
+ LLVM_DEBUG(dbgs() << " Retarget destination to trampoline at "
+ << NewBB->back());
+
+ insertUncondBranch(NewBB, TBB);
+
+ // Update the successor lists to include the trampoline.
+ MBB->replaceSuccessor(TBB, NewBB);
+ NewBB->addSuccessor(TBB);
+
+ // Replace branch in the current (MBB) block.
+ removeBranch(MBB);
+ insertBranch(MBB, NewBB, FBB, Cond);
+
+ TrampolineInsertionPoint = NewBB;
+ finalizeBlockChanges(MBB, NewBB);
+ return true;
+ }
+
+ LLVM_DEBUG(
+ dbgs() << " Trampoline insertion point out of range for Bcc from "
+ << printMBBReference(*MBB) << " to " << printMBBReference(*TBB)
+ << ".\n");
+ TrampolineInsertionPoint->setIsEndSection(NewBB->isEndSection());
+ MF->erase(NewBB);
+ }
+
// Add an unconditional branch to the destination and invert the branch
// condition to jump over it:
// tbz L1