LLVM: lib/CodeGen/BranchRelaxation.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
21#include "llvm/Config/llvm-config.h"
31#include
32#include
33#include
34#include
35
36using namespace llvm;
37
38#define DEBUG_TYPE "branch-relaxation"
39
40STATISTIC(NumSplit, "Number of basic blocks split");
41STATISTIC(NumConditionalRelaxed, "Number of conditional branches relaxed");
42STATISTIC(NumUnconditionalRelaxed, "Number of unconditional branches relaxed");
43
44#define BRANCH_RELAX_NAME "Branch relaxation pass"
45
46namespace {
47
48class BranchRelaxation {
49
50
52
53
54
55
57
58
59
60
61
62
63 unsigned Size = 0;
64
66
67
68
71 const Align Alignment = MBB.getAlignment();
72 const Align ParentAlign = MBB.getParent()->getAlignment();
73 if (Alignment <= ParentAlign)
74 return alignTo(PO, Alignment);
75
76
77
78 return alignTo(PO, Alignment) + Alignment.value() - ParentAlign.value();
79 }
80 };
81
83
84
85
88 RelaxedUnconditionals;
89 std::unique_ptr RS;
91
96
97 bool relaxBranchInstructions();
98 void scanFunction();
99
103
111
115 unsigned getInstrOffset(const MachineInstr &MI) const;
116 void dumpBBs();
118
119public:
121};
122
124public:
125 static char ID;
126
128
129 bool runOnMachineFunction(MachineFunction &MF) override {
131 }
132
134};
135
136}
137
138char BranchRelaxationLegacy::ID = 0;
139
141
143 false)
144
145
146void BranchRelaxation::verify() {
147#ifndef NDEBUG
148 unsigned PrevNum = MF->begin()->getNumber();
150 const unsigned Num = MBB.getNumber();
151 assert(!Num || BlockInfo[PrevNum].postOffset(MBB) <= BlockInfo[Num].Offset);
152 assert(BlockInfo[Num].Size == computeBlockSize(MBB));
153 PrevNum = Num;
154 }
155
158 J != MBB.end(); J = std::next(J)) {
160 if (.isConditionalBranch() &&
.isUnconditionalBranch())
161 continue;
162 if (MI.getOpcode() == TargetOpcode::FAULTING_OP)
163 continue;
165 assert(isBlockInRange(MI, *DestBB) ||
166 RelaxedUnconditionals.contains({&MBB, DestBB}));
167 }
168 }
169#endif
170}
171
172#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
173
175 for (auto &MBB : *MF) {
176 const BasicBlockInfo &BBI = BlockInfo[MBB.getNumber()];
179 }
180}
181#endif
182
183
184
185void BranchRelaxation::scanFunction() {
186 BlockInfo.clear();
187 BlockInfo.resize(MF->getNumBlockIDs());
188
189 TrampolineInsertionPoint = nullptr;
190 RelaxedUnconditionals.clear();
191
192
193
194
195
196
197 for (MachineBasicBlock &MBB : *MF) {
199
201 TrampolineInsertionPoint = &MBB;
202 }
203
204
205 adjustBlockOffsets(*MF->begin());
206
207 if (TrampolineInsertionPoint == nullptr) {
208 LLVM_DEBUG(dbgs() << " No suitable trampoline insertion point found in "
209 << MF->getName() << ".\n");
210 }
211}
212
213
214uint64_t
215BranchRelaxation::computeBlockSize(const MachineBasicBlock &MBB) const {
216 uint64_t Size = 0;
217 for (const MachineInstr &MI : MBB)
220}
221
222
223
224
225unsigned BranchRelaxation::getInstrOffset(const MachineInstr &MI) const {
226 const MachineBasicBlock *MBB = MI.getParent();
227
228
229
230
232
233
235 assert(I != MBB->end() && "Didn't find MI in its own basic block?");
237 }
238
240}
241
242void BranchRelaxation::adjustBlockOffsets(MachineBasicBlock &Start) {
243 adjustBlockOffsets(Start, MF->end());
244}
245
246void BranchRelaxation::adjustBlockOffsets(MachineBasicBlock &Start,
248 unsigned PrevNum = Start.getNumber();
249 for (auto &MBB :
252
253
254 BlockInfo[Num].Offset = BlockInfo[PrevNum].postOffset(MBB);
255
256 PrevNum = Num;
257 }
258}
259
260
261MachineBasicBlock *
262BranchRelaxation::createNewBlockAfter(MachineBasicBlock &OrigBB) {
263 return createNewBlockAfter(OrigBB, OrigBB.getBasicBlock());
264}
265
266
267
268MachineBasicBlock *
269BranchRelaxation::createNewBlockAfter(MachineBasicBlock &OrigMBB,
270 const BasicBlock *BB) {
271
272 MachineBasicBlock *NewBB = MF->CreateMachineBasicBlock(BB);
273 MF->insert(++OrigMBB.getIterator(), NewBB);
274
275
279
280
281 BlockInfo.insert(BlockInfo.begin() + NewBB->getNumber(), BasicBlockInfo());
282
283 return NewBB;
284}
285
286
287
288
289MachineBasicBlock *
290BranchRelaxation::splitBlockBeforeInstr(MachineInstr &MI,
291 MachineBasicBlock *DestBB) {
292 MachineBasicBlock *OrigBB = MI.getParent();
293
294
295 MachineBasicBlock *NewBB =
296 MF->CreateMachineBasicBlock(OrigBB->getBasicBlock());
298
299
303
304
305 NewBB->splice(NewBB->end(), OrigBB, MI.getIterator(), OrigBB->end());
306
307
308
309
310
312
313
314 BlockInfo.insert(BlockInfo.begin() + NewBB->getNumber(), BasicBlockInfo());
315
319
320
321
323
324
325
326
327
328
329 BlockInfo[OrigBB->getNumber()].Size = computeBlockSize(*OrigBB);
330
331
332
333 BlockInfo[NewBB->getNumber()].Size = computeBlockSize(*NewBB);
334
335
336 adjustBlockOffsets(*OrigBB, std::next(NewBB->getIterator()));
337
338
339 if (TRI->trackLivenessAfterRegAlloc(*MF))
341
342 ++NumSplit;
343
344 return NewBB;
345}
346
347
348
349bool BranchRelaxation::isBlockInRange(const MachineInstr &MI,
350 const MachineBasicBlock &DestBB) const {
351 int64_t BrOffset = getInstrOffset(MI);
352 int64_t DestOffset = BlockInfo[DestBB.getNumber()].Offset;
353
354 const MachineBasicBlock *SrcBB = MI.getParent();
355
359 : DestOffset - BrOffset))
360 return true;
361
362 LLVM_DEBUG(dbgs() << "Out of range branch to destination "
365 << DestOffset << " offset " << DestOffset - BrOffset << '\t'
366 << MI);
367
368 return false;
369}
370
371
372
373
374bool BranchRelaxation::fixupConditionalBranch(MachineInstr &MI) {
376 MachineBasicBlock *MBB = MI.getParent();
377 MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
378 MachineBasicBlock *NewBB = nullptr;
380
381 auto insertUncondBranch = [&](MachineBasicBlock *MBB,
382 MachineBasicBlock *DestBB) {
383 unsigned &BBSize = BlockInfo[MBB->getNumber()].Size;
384 int NewBrSize = 0;
386 BBSize += NewBrSize;
387 };
388 auto insertBranch = [&](MachineBasicBlock *MBB, MachineBasicBlock *TBB,
389 MachineBasicBlock *FBB,
390 SmallVectorImpl &Cond) {
391 unsigned &BBSize = BlockInfo[MBB->getNumber()].Size;
392 int NewBrSize = 0;
394 BBSize += NewBrSize;
395 };
396 auto removeBranch = [&](MachineBasicBlock *MBB) {
397 unsigned &BBSize = BlockInfo[MBB->getNumber()].Size;
398 int RemovedSize = 0;
400 BBSize -= RemovedSize;
401 };
402
403
404 auto updateOffsetAndLiveness = [&](MachineBasicBlock *NewBB) {
405 assert(NewBB != nullptr && "can't populate offset for nullptr");
406
407
408
409
410 adjustBlockOffsets(*std::prev(NewBB->getIterator()),
412
413
414 if (TRI->trackLivenessAfterRegAlloc(*MF))
416 };
417
419 assert( && "branches to be relaxed must be analyzable");
421
422
423
424
425
426
427
428
429
430
431
434 TrampolineInsertionPoint != nullptr) {
435
436 NewBB =
437 createNewBlockAfter(*TrampolineInsertionPoint, MBB->getBasicBlock());
438
439 if (isBlockInRange(MI, *NewBB)) {
440 LLVM_DEBUG(dbgs() << " Retarget destination to trampoline at "
441 << NewBB->back());
442
443 insertUncondBranch(NewBB, TBB);
444
445
448
449
450 removeBranch(MBB);
451 insertBranch(MBB, NewBB, FBB, Cond);
452
453 TrampolineInsertionPoint = NewBB;
454 updateOffsetAndLiveness(NewBB);
455 return true;
456 }
457
459 dbgs() << " Trampoline insertion point out of range for Bcc from "
461 << ".\n");
463 MF->erase(NewBB);
464 NewBB = nullptr;
465 }
466
467
468
469
470
471
472
473
474
476 if (ReversedCond) {
477 if (FBB && isBlockInRange(MI, *FBB)) {
478
479
480
481
482
483
484
486 "its destination with "
488
489 removeBranch(MBB);
491 return true;
492 }
493 if (FBB) {
494
495
496
497
498
499
500
501
502
503 if (TBB == FBB) {
504 removeBranch(MBB);
505 insertUncondBranch(MBB, TBB);
506 return true;
507 }
508
509
510 NewBB = createNewBlockAfter(*MBB);
511
512 insertUncondBranch(NewBB, FBB);
513
514
517 updateOffsetAndLiveness(NewBB);
518 }
519
520
521
523
525 << ", invert condition and change dest. to "
527
528 removeBranch(MBB);
529
530 insertBranch(MBB, &NextBB, TBB, Cond);
531 return true;
532 }
533
534
535 LLVM_DEBUG(dbgs() << " The branch condition can't be inverted. "
536 << " Insert a new BB after " << MBB->back());
537
538 if (!FBB)
540
541
542
543
544
545
546
547
548
549
550
551
552 NewBB = createNewBlockAfter(*MBB);
553 insertUncondBranch(NewBB, TBB);
554
557 << " Keep the exiting condition.\n"
559 << " In the new BB: Insert B to "
561
562
565
566
567 removeBranch(MBB);
568 insertBranch(MBB, NewBB, FBB, Cond);
569
570 updateOffsetAndLiveness(NewBB);
571 return true;
572}
573
574bool BranchRelaxation::fixupUnconditionalBranch(MachineInstr &MI) {
575 MachineBasicBlock *MBB = MI.getParent();
578
579 int64_t DestOffset = BlockInfo[DestBB->getNumber()].Offset;
580 int64_t SrcOffset = getInstrOffset(MI);
581
585 : DestOffset - SrcOffset));
586
587 BlockInfo[MBB->getNumber()].Size -= OldBrSize;
588
589 MachineBasicBlock *BranchBB = MBB;
590
591
592
594 BranchBB = createNewBlockAfter(*MBB);
595
596
597 for (const MachineBasicBlock *Succ : MBB->successors()) {
598 for (const MachineBasicBlock::RegisterMaskPair &LiveIn : Succ->liveins())
600 }
601
605 if (TrampolineInsertionPoint == MBB)
606 TrampolineInsertionPoint = BranchBB;
607 }
608
610 MI.eraseFromParent();
611
612
613
614
615 MachineBasicBlock *RestoreBB =
616 createNewBlockAfter(MF->back(), DestBB->getBasicBlock());
618 ->setIsEndSection(RestoreBB->isEndSection());
620
624 : DestOffset - SrcOffset,
625 RS.get());
626
627
628
629 BlockInfo[BranchBB->getNumber()].Size = computeBlockSize(*BranchBB);
630 adjustBlockOffsets(*MBB, std::next(BranchBB->getIterator()));
631
632
633 if (!RestoreBB->empty()) {
634
635
638 MachineBasicBlock *NewBB = createNewBlockAfter(*TrampolineInsertionPoint);
640 BlockInfo[NewBB->getNumber()].Size = computeBlockSize(*NewBB);
641 adjustBlockOffsets(*TrampolineInsertionPoint,
643
644
645 TrampolineInsertionPoint = NewBB;
646
647
650
651 DestBB = NewBB;
652 }
653
654
655
656
657
658
659
661 MachineBasicBlock *PrevBB = &*std::prev(DestBB->getIterator());
662
663
665 assert(FT == DestBB);
667 BlockInfo[PrevBB->getNumber()].Size = computeBlockSize(*PrevBB);
668 }
669
671
674 if (TRI->trackLivenessAfterRegAlloc(*MF))
676
677 BlockInfo[RestoreBB->getNumber()].Size = computeBlockSize(*RestoreBB);
678
679 adjustBlockOffsets(*PrevBB, DestBB->getIterator());
680
681
685 RelaxedUnconditionals.insert({BranchBB, RestoreBB});
686 } else {
687
688 MF->erase(RestoreBB);
689 RelaxedUnconditionals.insert({BranchBB, DestBB});
690 }
691
692 return true;
693}
694
695bool BranchRelaxation::relaxBranchInstructions() {
697
698
699
700 for (MachineBasicBlock &MBB : *MF) {
701
704 continue;
705
706
707
708
709
710
711 if (Last->isUnconditionalBranch()) {
712
713
716 !RelaxedUnconditionals.contains({&MBB, DestBB})) {
717 fixupUnconditionalBranch(*Last);
718 ++NumUnconditionalRelaxed;
720 }
721 }
722 }
723
724
728 Next = std::next(J);
729 MachineInstr &MI = *J;
730
731 if (.isConditionalBranch())
732 continue;
733
734 if (MI.getOpcode() == TargetOpcode::FAULTING_OP)
735
736
737 continue;
738
740 if (!isBlockInRange(MI, *DestBB)) {
741 if (Next != MBB.end() && Next->isConditionalBranch()) {
742
743
744
745
746 splitBlockBeforeInstr(*Next, DestBB);
747 } else {
748 fixupConditionalBranch(MI);
749 ++NumConditionalRelaxed;
750 }
751
753
754
756 }
757 }
758 }
759
760
761
762
764 adjustBlockOffsets(MF->front());
765
767}
768
769PreservedAnalyses
777
779 MF = &mf;
780
781 LLVM_DEBUG(dbgs() << "***** BranchRelaxation *****\n");
782
784 TII = ST.getInstrInfo();
786
787 TRI = ST.getRegisterInfo();
788 if (TRI->trackLivenessAfterRegAlloc(*MF))
790
791
792
793 MF->RenumberBlocks();
794
795
796
797 scanFunction();
798
799 LLVM_DEBUG(dbgs() << " Basic blocks before relaxation\n"; dumpBBs(););
800
801 bool MadeChange = false;
802 while (relaxBranchInstructions())
803 MadeChange = true;
804
805
807
808 LLVM_DEBUG(dbgs() << " Basic blocks after relaxation\n\n"; dumpBBs());
809
810 BlockInfo.clear();
811 RelaxedUnconditionals.clear();
812
813 return MadeChange;
814}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const TargetInstrInfo & TII
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
Definition BranchRelaxation.cpp:44
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
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)
LLVM Basic Block Representation.
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
Definition BranchRelaxation.cpp:770
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)
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.
virtual bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const
Reverses the branch condition of the specified condition list, returning false on success and true if...
virtual unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const
Remove the branching code at the end of the specific MBB.
virtual bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify=false) const
Analyze the branching code at the end of MBB, returning true if it cannot be understood (e....
virtual void insertIndirectBranch(MachineBasicBlock &MBB, MachineBasicBlock &NewDestBB, MachineBasicBlock &RestoreBB, const DebugLoc &DL, int64_t BrOffset=0, RegScavenger *RS=nullptr) const
Insert an unconditional indirect branch at the end of MBB to NewDestBB.
virtual bool isBranchOffsetInRange(unsigned BranchOpc, int64_t BrOffset) const
virtual unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const
Insert branch code into the end of the specified MachineBasicBlock.
virtual bool isTailCall(const MachineInstr &Inst) const
Determines whether Inst is a tail call instruction.
virtual MachineBasicBlock * getBranchDestBlock(const MachineInstr &MI) const
virtual unsigned getInstSizeInBytes(const MachineInstr &MI) const
Returns the size in bytes of the specified MachineInstr, or ~0U when this function is not implemented...
unsigned insertUnconditionalBranch(MachineBasicBlock &MBB, MachineBasicBlock *DestBB, const DebugLoc &DL, int *BytesAdded=nullptr) const
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...
Definition BranchRelaxation.cpp:140
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