24 #define DEBUG_TYPE "branch-relaxation"
26 STATISTIC(NumSplit,
"Number of basic blocks split");
27 STATISTIC(NumConditionalRelaxed,
"Number of conditional branches relaxed");
28 STATISTIC(NumUnconditionalRelaxed,
"Number of unconditional branches relaxed");
30 #define BRANCH_RELAX_NAME "Branch relaxation pass"
55 unsigned PO =
Offset + Size;
60 unsigned AlignAmt = 1 << Align;
62 if (Align <= ParentAlign)
72 std::unique_ptr<RegScavenger> RS;
79 bool relaxBranchInstructions();
117 unsigned PrevNum = MF->begin()->getNumber();
122 assert(!Num || BlockInfo[PrevNum].postOffset(
MBB) <= BlockInfo[Num].
Offset);
130 void BranchRelaxation::dumpBBs() {
131 for (
auto &
MBB : *MF) {
140 void BranchRelaxation::scanFunction() {
142 BlockInfo.resize(MF->getNumBlockIDs());
152 adjustBlockOffsets(*MF->begin());
159 Size +=
TII->getInstSizeInBytes(
MI);
166 unsigned BranchRelaxation::getInstrOffset(
const MachineInstr &
MI)
const {
176 assert(
I != MBB->
end() &&
"Didn't find MI in its own basic block?");
177 Offset +=
TII->getInstSizeInBytes(*
I);
191 BlockInfo[Num].Offset = BlockInfo[PrevNum].postOffset(MBB);
229 TII->insertUnconditionalBranch(*OrigBB, NewBB,
DebugLoc());
256 adjustBlockOffsets(*OrigBB);
259 if (TRI->trackLivenessAfterRegAlloc(*MF))
269 bool BranchRelaxation::isBlockInRange(
271 int64_t BrOffset = getInstrOffset(MI);
272 int64_t DestOffset = BlockInfo[DestBB.
getNumber()].Offset;
274 if (
TII->isBranchOffsetInRange(MI.
getOpcode(), DestOffset - BrOffset))
278 dbgs() <<
"Out of range branch to destination BB#" << DestBB.
getNumber()
280 <<
" to " << DestOffset
281 <<
" offset " << DestOffset - BrOffset
291 bool BranchRelaxation::fixupConditionalBranch(
MachineInstr &MI) {
298 assert(!Fail &&
"branches to be relaxed must be analyzable");
309 if (FBB && isBlockInRange(MI, *FBB)) {
317 DEBUG(
dbgs() <<
" Invert condition and swap "
318 "its destination with " << MBB->
back());
321 int OldSize = 0, NewSize = 0;
325 BlockInfo[MBB->
getNumber()].Size += (NewSize - OldSize);
330 auto &NewBB = *MF->CreateMachineBasicBlock(MBB->
getBasicBlock());
337 unsigned &NewBBSize = BlockInfo[NewBB.
getNumber()].Size;
339 TII->insertUnconditionalBranch(NewBB, FBB, DL, &NewBrSize);
340 NewBBSize += NewBrSize;
353 <<
", invert condition and change dest. to BB#"
356 unsigned &MBBSize = BlockInfo[MBB->
getNumber()].Size;
362 MBBSize -= RemovedSize;
366 MBBSize += AddedSize;
369 adjustBlockOffsets(*MBB);
373 bool BranchRelaxation::fixupUnconditionalBranch(
MachineInstr &MI) {
376 unsigned OldBrSize =
TII->getInstSizeInBytes(MI);
379 int64_t DestOffset = BlockInfo[DestBB->
getNumber()].Offset;
380 int64_t SrcOffset = getInstrOffset(MI);
384 BlockInfo[MBB->
getNumber()].Size -= OldBrSize;
391 BranchBB = createNewBlockAfter(*MBB);
406 BlockInfo[BranchBB->
getNumber()].Size +=
TII->insertIndirectBranch(
407 *BranchBB, *DestBB, DL, DestOffset - SrcOffset, RS.
get());
409 adjustBlockOffsets(*MBB);
413 bool BranchRelaxation::relaxBranchInstructions() {
414 bool Changed =
false;
423 if (Last == MBB.
end())
431 if (Last->isUnconditionalBranch()) {
435 if (!isBlockInRange(*Last, *DestBB)) {
436 fixupUnconditionalBranch(*Last);
437 ++NumUnconditionalRelaxed;
446 J != MBB.
end(); J = Next) {
452 if (!isBlockInRange(MI, *DestBB)) {
453 if (Next != MBB.
end() && Next->isConditionalBranch()) {
458 splitBlockBeforeInstr(*Next, DestBB);
460 fixupConditionalBranch(MI);
461 ++NumConditionalRelaxed;
479 DEBUG(
dbgs() <<
"***** BranchRelaxation *****\n");
485 if (TRI->trackLivenessAfterRegAlloc(*MF))
490 MF->RenumberBlocks();
496 DEBUG(
dbgs() <<
" Basic blocks before relaxation\n"; dumpBBs(););
498 bool MadeChange =
false;
499 while (relaxBranchInstructions())
505 DEBUG(
dbgs() <<
" Basic blocks after relaxation\n\n"; dumpBBs());
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
unsigned getAlignment() const
getAlignment - Return the alignment (log2, not bytes) of the function.
STATISTIC(NumFunctions,"Total number of functions")
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
void transferSuccessors(MachineBasicBlock *FromMBB)
Transfers all the successors from MBB to this machine basic block (i.e., copies all the successors Fr...
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
Reverses the branch condition of the specified condition list, returning false on success and true if...
unsigned Offset
Offset - Distance from the beginning of the function to the beginning of this basic block...
void computeLiveIns(LivePhysRegs &LiveRegs, const TargetRegisterInfo &TRI, MachineBasicBlock &MBB)
Compute the live-in list for MBB assuming all of its successors live-in lists are up-to-date...
char & BranchRelaxationPassID
BranchRelaxation - This pass replaces branches that need to jump further than is supported by a branc...
bool isConditionalBranch(QueryType Type=AnyInBundle) const
Return true if this is a branch which may fall through to the next instruction or may transfer contro...
void computeBlockSize(MachineFunction *MF, MachineBasicBlock *MBB, BasicBlockInfo &BBI)
BasicBlockInfo - Information about the offset and size of a single basic block.
iterator_range< succ_iterator > successors()
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...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
DILocation * get() const
Get the underlying DILocation.
const HexagonInstrInfo * TII
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
iterator getLastNonDebugInstr()
Returns an iterator to the last non-debug instruction in the basic block, or end().
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
format_object< Ts...> format(const char *Fmt, const Ts &...Vals)
These are helper functions used to produce formatted output.
TargetInstrInfo - Interface to description of machine instruction set.
bool verify(const TargetRegisterInfo &TRI) const
Check that information hold by this instance make sense for the given TRI.
void addLiveIn(MCPhysReg PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
This file declares the machine register scavenger class.
self_iterator getIterator()
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Iterator for intrusive lists based on ilist_node.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
void updateTerminator()
Update the terminator instructions in block to account for changes to the layout. ...
unsigned Size
Size - Size of the basic block in bytes.
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.
void sortUniqueLiveIns()
Sorts and uniques the LiveIns vector.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void replaceSuccessor(MachineBasicBlock *Old, MachineBasicBlock *New)
Replace successor OLD with NEW and update probability info.
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
Remove the branching code at the end of the specific MBB.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
TargetSubtargetInfo - Generic base class for all target subtargets.
Representation of each machine instruction.
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 '...
A set of live physical registers with functions to track liveness when walking backward/forward throu...
Pair of physical register and lane mask.
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
virtual const TargetInstrInfo * getInstrInfo() const
#define BRANCH_RELAX_NAME
uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
StringRef - Represent a constant reference to a string, i.e.
static cl::opt< bool > BranchRelaxation("aarch64-enable-branch-relax", cl::Hidden, cl::init(true), cl::desc("Relax out of range conditional branches"))
unsigned getAlignment() const
Return alignment of the basic block.