Skip to content

Commit 22c8b1d

Browse files
authored
[BranchRelaxation] Remove quadratic behavior in relaxation pass (#96250)
Currently, we recompute block offsets after each relaxation. This causes the complexity to be O(n^2) in the number of instructions, inflating compile time. If we instead recompute block offsets after each iteration of the outer loop, the complexity is O(n). Recomputing offsets in the outer loop will cause some out-of-range branches to be missed in the inner loop, but they will be relaxed in the next iteration of the outer loop. This change may introduce unnecessary relaxations for an architecture where the relaxed branch is smaller than the unrelaxed branch, but AFAIK there is no such architecture.
1 parent eb16ace commit 22c8b1d

File tree

1 file changed

+50
-27
lines changed

1 file changed

+50
-27
lines changed

llvm/lib/CodeGen/BranchRelaxation.cpp

Lines changed: 50 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ class BranchRelaxation : public MachineFunctionPass {
7272
if (Alignment <= ParentAlign)
7373
return alignTo(PO, Alignment);
7474

75-
// The alignment of this MBB is larger than the function's alignment, so we
76-
// can't tell whether or not it will insert nops. Assume that it will.
75+
// The alignment of this MBB is larger than the function's alignment, so
76+
// we can't tell whether or not it will insert nops. Assume that it will.
7777
return alignTo(PO, Alignment) + Alignment.value() - ParentAlign.value();
7878
}
7979
};
@@ -103,7 +103,10 @@ class BranchRelaxation : public MachineFunctionPass {
103103
MachineBasicBlock *splitBlockBeforeInstr(MachineInstr &MI,
104104
MachineBasicBlock *DestBB);
105105
void adjustBlockOffsets(MachineBasicBlock &Start);
106-
bool isBlockInRange(const MachineInstr &MI, const MachineBasicBlock &BB) const;
106+
void adjustBlockOffsets(MachineBasicBlock &Start,
107+
MachineFunction::iterator End);
108+
bool isBlockInRange(const MachineInstr &MI,
109+
const MachineBasicBlock &BB) const;
107110

108111
bool fixupConditionalBranch(MachineInstr &MI);
109112
bool fixupUnconditionalBranch(MachineInstr &MI);
@@ -199,7 +202,8 @@ void BranchRelaxation::scanFunction() {
199202
}
200203

201204
/// computeBlockSize - Compute the size for MBB.
202-
uint64_t BranchRelaxation::computeBlockSize(const MachineBasicBlock &MBB) const {
205+
uint64_t
206+
BranchRelaxation::computeBlockSize(const MachineBasicBlock &MBB) const {
203207
uint64_t Size = 0;
204208
for (const MachineInstr &MI : MBB)
205209
Size += TII->getInstSizeInBytes(MI);
@@ -227,9 +231,14 @@ unsigned BranchRelaxation::getInstrOffset(const MachineInstr &MI) const {
227231
}
228232

229233
void BranchRelaxation::adjustBlockOffsets(MachineBasicBlock &Start) {
234+
adjustBlockOffsets(Start, MF->end());
235+
}
236+
237+
void BranchRelaxation::adjustBlockOffsets(MachineBasicBlock &Start,
238+
MachineFunction::iterator End) {
230239
unsigned PrevNum = Start.getNumber();
231240
for (auto &MBB :
232-
make_range(std::next(MachineFunction::iterator(Start)), MF->end())) {
241+
make_range(std::next(MachineFunction::iterator(Start)), End)) {
233242
unsigned Num = MBB.getNumber();
234243
// Get the offset and known bits at the end of the layout predecessor.
235244
// Include the alignment of the current block.
@@ -314,8 +323,8 @@ BranchRelaxation::splitBlockBeforeInstr(MachineInstr &MI,
314323
// block, it may contain a tablejump.
315324
BlockInfo[NewBB->getNumber()].Size = computeBlockSize(*NewBB);
316325

317-
// All BBOffsets following these blocks must be modified.
318-
adjustBlockOffsets(*OrigBB);
326+
// Update the offset of the new block.
327+
adjustBlockOffsets(*OrigBB, std::next(NewBB->getIterator()));
319328

320329
// Need to fix live-in lists if we track liveness.
321330
if (TRI->trackLivenessAfterRegAlloc(*MF))
@@ -328,8 +337,8 @@ BranchRelaxation::splitBlockBeforeInstr(MachineInstr &MI,
328337

329338
/// isBlockInRange - Returns true if the distance between specific MI and
330339
/// specific BB can fit in MI's displacement field.
331-
bool BranchRelaxation::isBlockInRange(
332-
const MachineInstr &MI, const MachineBasicBlock &DestBB) const {
340+
bool BranchRelaxation::isBlockInRange(const MachineInstr &MI,
341+
const MachineBasicBlock &DestBB) const {
333342
int64_t BrOffset = getInstrOffset(MI);
334343
int64_t DestOffset = BlockInfo[DestBB.getNumber()].Offset;
335344

@@ -369,7 +378,7 @@ bool BranchRelaxation::fixupConditionalBranch(MachineInstr &MI) {
369378
};
370379
auto insertBranch = [&](MachineBasicBlock *MBB, MachineBasicBlock *TBB,
371380
MachineBasicBlock *FBB,
372-
SmallVectorImpl<MachineOperand>& Cond) {
381+
SmallVectorImpl<MachineOperand> &Cond) {
373382
unsigned &BBSize = BlockInfo[MBB->getNumber()].Size;
374383
int NewBrSize = 0;
375384
TII->insertBranch(*MBB, TBB, FBB, Cond, DL, &NewBrSize);
@@ -382,13 +391,18 @@ bool BranchRelaxation::fixupConditionalBranch(MachineInstr &MI) {
382391
BBSize -= RemovedSize;
383392
};
384393

385-
auto finalizeBlockChanges = [&](MachineBasicBlock *MBB,
386-
MachineBasicBlock *NewBB) {
387-
// Keep the block offsets up to date.
388-
adjustBlockOffsets(*MBB);
394+
// Populate the block offset and live-ins for a new basic block.
395+
auto updateOffsetAndLiveness = [&](MachineBasicBlock *NewBB) {
396+
assert(NewBB != nullptr && "can't populate offset for nullptr");
397+
398+
// Keep the block offsets approximately up to date. While they will be
399+
// slight underestimates, we will update them appropriately in the next
400+
// scan through the function.
401+
adjustBlockOffsets(*std::prev(NewBB->getIterator()),
402+
std::next(NewBB->getIterator()));
389403

390404
// Need to fix live-in lists if we track liveness.
391-
if (NewBB && TRI->trackLivenessAfterRegAlloc(*MF))
405+
if (TRI->trackLivenessAfterRegAlloc(*MF))
392406
computeAndAddLiveIns(LiveRegs, *NewBB);
393407
};
394408

@@ -428,7 +442,7 @@ bool BranchRelaxation::fixupConditionalBranch(MachineInstr &MI) {
428442
insertBranch(MBB, NewBB, FBB, Cond);
429443

430444
TrampolineInsertionPoint = NewBB;
431-
finalizeBlockChanges(MBB, NewBB);
445+
updateOffsetAndLiveness(NewBB);
432446
return true;
433447
}
434448

@@ -438,6 +452,7 @@ bool BranchRelaxation::fixupConditionalBranch(MachineInstr &MI) {
438452
<< ".\n");
439453
TrampolineInsertionPoint->setIsEndSection(NewBB->isEndSection());
440454
MF->erase(NewBB);
455+
NewBB = nullptr;
441456
}
442457

443458
// Add an unconditional branch to the destination and invert the branch
@@ -464,7 +479,6 @@ bool BranchRelaxation::fixupConditionalBranch(MachineInstr &MI) {
464479

465480
removeBranch(MBB);
466481
insertBranch(MBB, FBB, TBB, Cond);
467-
finalizeBlockChanges(MBB, nullptr);
468482
return true;
469483
}
470484
if (FBB) {
@@ -477,10 +491,11 @@ bool BranchRelaxation::fixupConditionalBranch(MachineInstr &MI) {
477491
// Do it here since if there's no split, no update is needed.
478492
MBB->replaceSuccessor(FBB, NewBB);
479493
NewBB->addSuccessor(FBB);
494+
updateOffsetAndLiveness(NewBB);
480495
}
481496

482-
// We now have an appropriate fall-through block in place (either naturally or
483-
// just created), so we can use the inverted the condition.
497+
// We now have an appropriate fall-through block in place (either naturally
498+
// or just created), so we can use the inverted the condition.
484499
MachineBasicBlock &NextBB = *std::next(MachineFunction::iterator(MBB));
485500

486501
LLVM_DEBUG(dbgs() << " Insert B to " << printMBBReference(*TBB)
@@ -490,8 +505,6 @@ bool BranchRelaxation::fixupConditionalBranch(MachineInstr &MI) {
490505
removeBranch(MBB);
491506
// Insert a new conditional branch and a new unconditional branch.
492507
insertBranch(MBB, &NextBB, TBB, Cond);
493-
494-
finalizeBlockChanges(MBB, NewBB);
495508
return true;
496509
}
497510
// Branch cond can't be inverted.
@@ -531,7 +544,7 @@ bool BranchRelaxation::fixupConditionalBranch(MachineInstr &MI) {
531544
removeBranch(MBB);
532545
insertBranch(MBB, NewBB, FBB, Cond);
533546

534-
finalizeBlockChanges(MBB, NewBB);
547+
updateOffsetAndLiveness(NewBB);
535548
return true;
536549
}
537550

@@ -577,8 +590,8 @@ bool BranchRelaxation::fixupUnconditionalBranch(MachineInstr &MI) {
577590
// Create the optional restore block and, initially, place it at the end of
578591
// function. That block will be placed later if it's used; otherwise, it will
579592
// be erased.
580-
MachineBasicBlock *RestoreBB = createNewBlockAfter(MF->back(),
581-
DestBB->getBasicBlock());
593+
MachineBasicBlock *RestoreBB =
594+
createNewBlockAfter(MF->back(), DestBB->getBasicBlock());
582595
std::prev(RestoreBB->getIterator())
583596
->setIsEndSection(RestoreBB->isEndSection());
584597
RestoreBB->setIsEndSection(false);
@@ -589,8 +602,10 @@ bool BranchRelaxation::fixupUnconditionalBranch(MachineInstr &MI) {
589602
: DestOffset - SrcOffset,
590603
RS.get());
591604

605+
// Update the block size and offset for the BranchBB (which may be newly
606+
// created).
592607
BlockInfo[BranchBB->getNumber()].Size = computeBlockSize(*BranchBB);
593-
adjustBlockOffsets(*MBB);
608+
adjustBlockOffsets(*MBB, std::next(BranchBB->getIterator()));
594609

595610
// If RestoreBB is required, place it appropriately.
596611
if (!RestoreBB->empty()) {
@@ -601,6 +616,8 @@ bool BranchRelaxation::fixupUnconditionalBranch(MachineInstr &MI) {
601616
MachineBasicBlock *NewBB = createNewBlockAfter(*TrampolineInsertionPoint);
602617
TII->insertUnconditionalBranch(*NewBB, DestBB, DebugLoc());
603618
BlockInfo[NewBB->getNumber()].Size = computeBlockSize(*NewBB);
619+
adjustBlockOffsets(*TrampolineInsertionPoint,
620+
std::next(NewBB->getIterator()));
604621

605622
// New trampolines should be inserted after NewBB.
606623
TrampolineInsertionPoint = NewBB;
@@ -636,8 +653,8 @@ bool BranchRelaxation::fixupUnconditionalBranch(MachineInstr &MI) {
636653
computeAndAddLiveIns(LiveRegs, *RestoreBB);
637654
// Compute the restore block size.
638655
BlockInfo[RestoreBB->getNumber()].Size = computeBlockSize(*RestoreBB);
639-
// Update the offset starting from the previous block.
640-
adjustBlockOffsets(*PrevBB);
656+
// Update the estimated offset for the restore block.
657+
adjustBlockOffsets(*PrevBB, DestBB->getIterator());
641658

642659
// Fix up section information for RestoreBB and DestBB
643660
RestoreBB->setSectionID(DestBB->getSectionID());
@@ -718,6 +735,12 @@ bool BranchRelaxation::relaxBranchInstructions() {
718735
}
719736
}
720737

738+
// If we relaxed a branch, we must recompute offsets for *all* basic blocks.
739+
// Otherwise, we may underestimate branch distances and fail to relax a branch
740+
// that has been pushed out of range.
741+
if (Changed)
742+
adjustBlockOffsets(MF->front());
743+
721744
return Changed;
722745
}
723746

0 commit comments

Comments
 (0)