diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2022-03-20 11:40:34 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2022-05-14 11:43:05 +0000 |
commit | 349cc55c9796c4596a5b9904cd3281af295f878f (patch) | |
tree | 410c5a785075730a35f1272ca6a7adf72222ad03 /contrib/llvm-project/llvm/lib/CodeGen/BranchRelaxation.cpp | |
parent | cb2ae6163174b90e999326ecec3699ee093a5d43 (diff) | |
parent | c0981da47d5696fe36474fcf86b4ce03ae3ff818 (diff) |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/BranchRelaxation.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/CodeGen/BranchRelaxation.cpp | 42 |
1 files changed, 40 insertions, 2 deletions
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/BranchRelaxation.cpp b/contrib/llvm-project/llvm/lib/CodeGen/BranchRelaxation.cpp index 366c303614d6..50825ccf9bac 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/BranchRelaxation.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/BranchRelaxation.cpp @@ -463,10 +463,48 @@ bool BranchRelaxation::fixupUnconditionalBranch(MachineInstr &MI) { DebugLoc DL = MI.getDebugLoc(); MI.eraseFromParent(); - BlockInfo[BranchBB->getNumber()].Size += TII->insertIndirectBranch( - *BranchBB, *DestBB, DL, DestOffset - SrcOffset, RS.get()); + // Create the optional restore block and, initially, place it at the end of + // function. That block will be placed later if it's used; otherwise, it will + // be erased. + MachineBasicBlock *RestoreBB = createNewBlockAfter(MF->back()); + + TII->insertIndirectBranch(*BranchBB, *DestBB, *RestoreBB, DL, + DestOffset - SrcOffset, RS.get()); + + BlockInfo[BranchBB->getNumber()].Size = computeBlockSize(*BranchBB); adjustBlockOffsets(*MBB); + + // If RestoreBB is required, try to place just before DestBB. + if (!RestoreBB->empty()) { + // TODO: For multiple far branches to the same destination, there are + // chances that some restore blocks could be shared if they clobber the + // same registers and share the same restore sequence. So far, those + // restore blocks are just duplicated for each far branch. + assert(!DestBB->isEntryBlock()); + MachineBasicBlock *PrevBB = &*std::prev(DestBB->getIterator()); + if (auto *FT = PrevBB->getFallThrough()) { + assert(FT == DestBB); + TII->insertUnconditionalBranch(*PrevBB, FT, DebugLoc()); + // Recalculate the block size. + BlockInfo[PrevBB->getNumber()].Size = computeBlockSize(*PrevBB); + } + // Now, RestoreBB could be placed directly before DestBB. + MF->splice(DestBB->getIterator(), RestoreBB->getIterator()); + // Update successors and predecessors. + RestoreBB->addSuccessor(DestBB); + BranchBB->replaceSuccessor(DestBB, RestoreBB); + if (TRI->trackLivenessAfterRegAlloc(*MF)) + computeAndAddLiveIns(LiveRegs, *RestoreBB); + // Compute the restore block size. + BlockInfo[RestoreBB->getNumber()].Size = computeBlockSize(*RestoreBB); + // Update the offset starting from the previous block. + adjustBlockOffsets(*PrevBB); + } else { + // Remove restore block if it's not required. + MF->erase(RestoreBB); + } + return true; } |