23#include "llvm/Config/llvm-config.h"
40#define DEBUG_TYPE "branch-relaxation"
43STATISTIC(NumConditionalRelaxed,
"Number of conditional branches relaxed");
44STATISTIC(NumUnconditionalRelaxed,
"Number of unconditional branches relaxed");
46#define BRANCH_RELAX_NAME "Branch relaxation pass"
50class BranchRelaxation {
73 const Align Alignment =
MBB.getAlignment();
74 const Align ParentAlign =
MBB.getParent()->getAlignment();
75 if (Alignment <= ParentAlign)
90 RelaxedUnconditionals;
91 std::unique_ptr<RegScavenger> RS;
99 bool relaxBranchInstructions();
140char BranchRelaxationLegacy::ID = 0;
148void BranchRelaxation::
verify() {
150 unsigned PrevNum = MF->begin()->getNumber();
152 const unsigned Num =
MBB.getNumber();
153 assert(!Num || BlockInfo[PrevNum].postOffset(
MBB) <= BlockInfo[Num].
Offset);
160 J !=
MBB.end(); J = std::next(J)) {
162 if (!
MI.isConditionalBranch() && !
MI.isUnconditionalBranch())
164 if (
MI.getOpcode() == TargetOpcode::FAULTING_OP)
167 assert(isBlockInRange(
MI, *DestBB) ||
168 RelaxedUnconditionals.contains({&MBB, DestBB}));
174#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
177 for (
auto &
MBB : *MF) {
187void BranchRelaxation::scanFunction() {
189 BlockInfo.resize(MF->getNumBlockIDs());
191 TrampolineInsertionPoint =
nullptr;
192 RelaxedUnconditionals.clear();
199 for (MachineBasicBlock &
MBB : *MF) {
203 TrampolineInsertionPoint = &
MBB;
207 adjustBlockOffsets(*MF->begin());
209 if (TrampolineInsertionPoint ==
nullptr) {
210 LLVM_DEBUG(
dbgs() <<
" No suitable trampoline insertion point found in "
211 << MF->getName() <<
".\n");
217BranchRelaxation::computeBlockSize(
const MachineBasicBlock &
MBB)
const {
219 for (
const MachineInstr &
MI :
MBB)
227unsigned BranchRelaxation::getInstrOffset(
const MachineInstr &
MI)
const {
228 const MachineBasicBlock *
MBB =
MI.getParent();
237 assert(
I !=
MBB->
end() &&
"Didn't find MI in its own basic block?");
244void BranchRelaxation::adjustBlockOffsets(MachineBasicBlock &Start) {
245 adjustBlockOffsets(Start, MF->end());
248void BranchRelaxation::adjustBlockOffsets(MachineBasicBlock &Start,
250 unsigned PrevNum =
Start.getNumber();
256 BlockInfo[Num].Offset = BlockInfo[PrevNum].postOffset(
MBB);
264BranchRelaxation::createNewBlockAfter(MachineBasicBlock &OrigBB) {
271BranchRelaxation::createNewBlockAfter(MachineBasicBlock &OrigMBB,
272 const BasicBlock *BB) {
274 MachineBasicBlock *NewBB = MF->CreateMachineBasicBlock(BB);
283 BlockInfo.insert(BlockInfo.begin() + NewBB->
getNumber(), BasicBlockInfo());
292BranchRelaxation::splitBlockBeforeInstr(MachineInstr &
MI,
293 MachineBasicBlock *DestBB) {
294 MachineBasicBlock *OrigBB =
MI.getParent();
297 MachineBasicBlock *NewBB =
307 NewBB->
splice(NewBB->
end(), OrigBB,
MI.getIterator(), OrigBB->
end());
313 TII->insertUnconditionalBranch(*OrigBB, NewBB,
DebugLoc());
316 BlockInfo.insert(BlockInfo.begin() + NewBB->
getNumber(), BasicBlockInfo());
331 BlockInfo[OrigBB->
getNumber()].Size = computeBlockSize(*OrigBB);
335 BlockInfo[NewBB->
getNumber()].Size = computeBlockSize(*NewBB);
338 adjustBlockOffsets(*OrigBB, std::next(NewBB->
getIterator()));
341 if (
TRI->trackLivenessAfterRegAlloc(*MF))
351bool BranchRelaxation::isBlockInRange(
const MachineInstr &
MI,
352 const MachineBasicBlock &DestBB)
const {
353 int64_t BrOffset = getInstrOffset(
MI);
354 int64_t DestOffset = BlockInfo[DestBB.
getNumber()].Offset;
356 const MachineBasicBlock *SrcBB =
MI.getParent();
358 if (
TII->isBranchOffsetInRange(
MI.getOpcode(),
361 : DestOffset - BrOffset))
367 << DestOffset <<
" offset " << DestOffset - BrOffset <<
'\t'
376bool BranchRelaxation::fixupConditionalBranch(MachineInstr &
MI) {
378 MachineBasicBlock *
MBB =
MI.getParent();
379 MachineBasicBlock *
TBB =
nullptr, *FBB =
nullptr;
380 MachineBasicBlock *NewBB =
nullptr;
383 auto insertUncondBranch = [&](MachineBasicBlock *
MBB,
384 MachineBasicBlock *DestBB) {
387 TII->insertUnconditionalBranch(*
MBB, DestBB,
DL, &NewBrSize);
390 auto insertBranch = [&](MachineBasicBlock *
MBB, MachineBasicBlock *
TBB,
391 MachineBasicBlock *FBB,
392 SmallVectorImpl<MachineOperand> &
Cond) {
398 auto removeBranch = [&](MachineBasicBlock *
MBB) {
402 BBSize -= RemovedSize;
406 auto updateOffsetAndLiveness = [&](MachineBasicBlock *NewBB) {
407 assert(NewBB !=
nullptr &&
"can't populate offset for nullptr");
412 adjustBlockOffsets(*std::prev(NewBB->
getIterator()),
416 if (
TRI->trackLivenessAfterRegAlloc(*MF))
421 assert(!
Fail &&
"branches to be relaxed must be analyzable");
436 TrampolineInsertionPoint !=
nullptr) {
441 if (isBlockInRange(
MI, *NewBB)) {
445 insertUncondBranch(NewBB,
TBB);
453 insertBranch(
MBB, NewBB, FBB,
Cond);
455 TrampolineInsertionPoint = NewBB;
456 updateOffsetAndLiveness(NewBB);
461 dbgs() <<
" Trampoline insertion point out of range for Bcc from "
479 if (FBB && isBlockInRange(
MI, *FBB)) {
488 "its destination with "
507 insertUncondBranch(
MBB,
TBB);
512 NewBB = createNewBlockAfter(*
MBB);
514 insertUncondBranch(NewBB, FBB);
519 updateOffsetAndLiveness(NewBB);
527 <<
", invert condition and change dest. to "
538 <<
" Insert a new BB after " <<
MBB->
back());
554 NewBB = createNewBlockAfter(*
MBB);
555 insertUncondBranch(NewBB,
TBB);
559 <<
" Keep the exiting condition.\n"
561 <<
" In the new BB: Insert B to "
570 insertBranch(
MBB, NewBB, FBB,
Cond);
572 updateOffsetAndLiveness(NewBB);
576bool BranchRelaxation::fixupUnconditionalBranch(MachineInstr &
MI) {
577 MachineBasicBlock *
MBB =
MI.getParent();
578 unsigned OldBrSize =
TII->getInstSizeInBytes(
MI);
579 MachineBasicBlock *DestBB =
TII->getBranchDestBlock(
MI);
581 int64_t DestOffset = BlockInfo[DestBB->
getNumber()].Offset;
582 int64_t SrcOffset = getInstrOffset(
MI);
587 : DestOffset - SrcOffset));
591 MachineBasicBlock *BranchBB =
MBB;
596 BranchBB = createNewBlockAfter(*
MBB);
600 for (
const MachineBasicBlock::RegisterMaskPair &LiveIn : Succ->liveins())
607 if (TrampolineInsertionPoint ==
MBB)
608 TrampolineInsertionPoint = BranchBB;
612 MI.eraseFromParent();
617 MachineBasicBlock *RestoreBB =
623 TII->insertIndirectBranch(*BranchBB, *DestBB, *RestoreBB,
DL,
626 : DestOffset - SrcOffset,
631 BlockInfo[BranchBB->
getNumber()].Size = computeBlockSize(*BranchBB);
635 if (!RestoreBB->
empty()) {
640 MachineBasicBlock *NewBB = createNewBlockAfter(*TrampolineInsertionPoint);
641 TII->insertUnconditionalBranch(*NewBB, DestBB,
DebugLoc());
642 BlockInfo[NewBB->
getNumber()].Size = computeBlockSize(*NewBB);
643 adjustBlockOffsets(*TrampolineInsertionPoint,
647 TrampolineInsertionPoint = NewBB;
663 MachineBasicBlock *PrevBB = &*std::prev(DestBB->
getIterator());
668 TII->insertUnconditionalBranch(*PrevBB, FT,
DebugLoc());
669 BlockInfo[PrevBB->
getNumber()].Size = computeBlockSize(*PrevBB);
676 if (
TRI->trackLivenessAfterRegAlloc(*MF))
679 BlockInfo[RestoreBB->
getNumber()].Size = computeBlockSize(*RestoreBB);
681 adjustBlockOffsets(*PrevBB, DestBB->
getIterator());
687 RelaxedUnconditionals.insert({BranchBB, RestoreBB});
690 MF->erase(RestoreBB);
691 RelaxedUnconditionals.insert({BranchBB, DestBB});
697bool BranchRelaxation::relaxBranchInstructions() {
702 for (MachineBasicBlock &
MBB : *MF) {
713 if (
Last->isUnconditionalBranch()) {
716 if (MachineBasicBlock *DestBB =
TII->getBranchDestBlock(*
Last)) {
718 !RelaxedUnconditionals.contains({&MBB, DestBB})) {
719 fixupUnconditionalBranch(*
Last);
720 ++NumUnconditionalRelaxed;
731 MachineInstr &
MI = *J;
733 if (!
MI.isConditionalBranch())
736 if (
MI.getOpcode() == TargetOpcode::FAULTING_OP)
741 MachineBasicBlock *DestBB =
TII->getBranchDestBlock(
MI);
742 if (!isBlockInRange(
MI, *DestBB)) {
748 splitBlockBeforeInstr(*
Next, DestBB);
750 fixupConditionalBranch(
MI);
751 ++NumConditionalRelaxed;
766 adjustBlockOffsets(MF->front());
781 MDT->updateBlockNumbers();
783 MPDT->updateBlockNumbers();
793 TII = ST.getInstrInfo();
796 TRI = ST.getRegisterInfo();
797 if (
TRI->trackLivenessAfterRegAlloc(*MF))
802 MF->RenumberBlocks();
808 LLVM_DEBUG(
dbgs() <<
" Basic blocks before relaxation\n"; dumpBBs(););
810 bool MadeChange =
false;
811 while (relaxBranchInstructions())
817 LLVM_DEBUG(
dbgs() <<
" Basic blocks after relaxation\n\n"; dumpBBs());
820 RelaxedUnconditionals.clear();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static cl::opt< bool > BranchRelaxation("aarch64-enable-branch-relax", cl::Hidden, cl::init(true), cl::desc("Relax out of range conditional branches"))
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define BRANCH_RELAX_NAME
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
const HexagonInstrInfo * TII
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
Register const TargetRegisterInfo * TRI
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
This file declares the machine register scavenger class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
LLVM Basic Block Representation.
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
Remove the branching code at the end of the specific MBB.
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
Analyze the branching code at the end of MBB, returning true if it cannot be understood (e....
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
Reverses the branch condition of the specified condition list, returning false on success and true if...
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
Insert branch code into the end of the specified MachineBasicBlock.
bool isTailCall(const MachineInstr &MI) const override
A set of physical registers with utility functions to track liveness when walking backward/forward th...
void setIsEndSection(bool V=true)
MachineInstrBundleIterator< const MachineInstr > const_iterator
MachineBasicBlock * getLogicalFallThrough()
Return the fallthrough block if the block can implicitly transfer control to it's successor,...
LLVM_ABI void replaceSuccessor(MachineBasicBlock *Old, MachineBasicBlock *New)
Replace successor OLD with NEW and update probability info.
LLVM_ABI void transferSuccessors(MachineBasicBlock *FromMBB)
Transfers all the successors from MBB to this machine basic block (i.e., copies all the successors Fr...
LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI void updateTerminator(MachineBasicBlock *PreviousLayoutSuccessor)
Update the terminator instructions in block to account for changes to block layout which may have bee...
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
MBBSectionID getSectionID() const
Returns the section ID of this basic block.
LLVM_ABI bool isEntryBlock() const
Returns true if this is the entry block of the function.
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
LLVM_ABI void sortUniqueLiveIns()
Sorts and uniques the LiveIns vector.
void setSectionID(MBBSectionID V)
Sets the section ID for this basic block.
LLVM_ABI iterator getLastNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the last non-debug instruction in the basic block, or end().
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
bool isBeginSection() const
Returns true if this block begins any section.
iterator_range< succ_iterator > successors()
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
bool isEndSection() const
Returns true if this block ends any section.
MachineInstrBundleIterator< MachineInstr > iterator
void setIsBeginSection(bool V=true)
Analysis pass which computes a MachineDominatorTree.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
BasicBlockListType::iterator iterator
Representation of each machine instruction.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Implements a dense probed hash-table based set with some number of buckets stored inline.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
TargetInstrInfo - Interface to description of machine instruction set.
Primary interface to the complete machine description for the target machine.
uint64_t getMaxCodeSize() const
Returns the maximum code size possible under the code model.
const Target & getTarget() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
TargetSubtargetInfo - Generic base class for all target subtargets.
self_iterator getIterator()
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
LLVM_ABI char & BranchRelaxationPassID
BranchRelaxation - This pass replaces branches that need to jump further than is supported by a branc...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
FunctionAddr VTableAddr Next
void computeAndAddLiveIns(LivePhysRegs &LiveRegs, MachineBasicBlock &MBB)
Convenience function combining computeLiveIns() and addLiveIns().
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
BasicBlockInfo - Information about the offset and size of a single basic block.
unsigned Size
Size - Size of the basic block in bytes.
unsigned Offset
Offset - Distance from the beginning of the function to the beginning of this basic block.
LLVM_ABI static const MBBSectionID ColdSectionID