mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 04:40:38 +00:00
Changes in the branch relaxation algorithm.
The existing version worked incorrectly when inversion of a branch condintion is impossible. Changed the "fixupConditionalBranch()" function - a new BB (a trampoline) is created to keep the original branch condition. Differential Revision: https://reviews.llvm.org/D41634 llvm-svn: 321785
This commit is contained in:
parent
347c5f1847
commit
df75127937
@ -302,8 +302,41 @@ bool BranchRelaxation::fixupConditionalBranch(MachineInstr &MI) {
|
||||
DebugLoc DL = MI.getDebugLoc();
|
||||
MachineBasicBlock *MBB = MI.getParent();
|
||||
MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
|
||||
MachineBasicBlock *NewBB = nullptr;
|
||||
SmallVector<MachineOperand, 4> Cond;
|
||||
|
||||
auto insertUncondBranch = [&](MachineBasicBlock *MBB,
|
||||
MachineBasicBlock *DestBB) {
|
||||
unsigned &BBSize = BlockInfo[MBB->getNumber()].Size;
|
||||
int NewBrSize = 0;
|
||||
TII->insertUnconditionalBranch(*MBB, DestBB, DL, &NewBrSize);
|
||||
BBSize += NewBrSize;
|
||||
};
|
||||
auto insertBranch = [&](MachineBasicBlock *MBB, MachineBasicBlock *TBB,
|
||||
MachineBasicBlock *FBB,
|
||||
SmallVectorImpl<MachineOperand>& Cond) {
|
||||
unsigned &BBSize = BlockInfo[MBB->getNumber()].Size;
|
||||
int NewBrSize = 0;
|
||||
TII->insertBranch(*MBB, TBB, FBB, Cond, DL, &NewBrSize);
|
||||
BBSize += NewBrSize;
|
||||
};
|
||||
auto removeBranch = [&](MachineBasicBlock *MBB) {
|
||||
unsigned &BBSize = BlockInfo[MBB->getNumber()].Size;
|
||||
int RemovedSize = 0;
|
||||
TII->removeBranch(*MBB, &RemovedSize);
|
||||
BBSize -= RemovedSize;
|
||||
};
|
||||
|
||||
auto finalizeBlockChanges = [&](MachineBasicBlock *MBB,
|
||||
MachineBasicBlock *NewBB) {
|
||||
// Keep the block offsets up to date.
|
||||
adjustBlockOffsets(*MBB);
|
||||
|
||||
// Need to fix live-in lists if we track liveness.
|
||||
if (NewBB && TRI->trackLivenessAfterRegAlloc(*MF))
|
||||
computeAndAddLiveIns(LiveRegs, *NewBB);
|
||||
};
|
||||
|
||||
bool Fail = TII->analyzeBranch(*MBB, TBB, FBB, Cond);
|
||||
assert(!Fail && "branches to be relaxed must be analyzable");
|
||||
(void)Fail;
|
||||
@ -316,71 +349,88 @@ bool BranchRelaxation::fixupConditionalBranch(MachineInstr &MI) {
|
||||
// b L1
|
||||
// L2:
|
||||
|
||||
if (FBB && isBlockInRange(MI, *FBB)) {
|
||||
// Last MI in the BB is an unconditional branch. We can simply invert the
|
||||
// condition and swap destinations:
|
||||
// beq L1
|
||||
// b L2
|
||||
// =>
|
||||
// bne L2
|
||||
// b L1
|
||||
DEBUG(dbgs() << " Invert condition and swap "
|
||||
"its destination with " << MBB->back());
|
||||
bool ReversedCond = !TII->reverseBranchCondition(Cond);
|
||||
if (ReversedCond) {
|
||||
if (FBB && isBlockInRange(MI, *FBB)) {
|
||||
// Last MI in the BB is an unconditional branch. We can simply invert the
|
||||
// condition and swap destinations:
|
||||
// beq L1
|
||||
// b L2
|
||||
// =>
|
||||
// bne L2
|
||||
// b L1
|
||||
DEBUG(dbgs() << " Invert condition and swap "
|
||||
"its destination with " << MBB->back());
|
||||
|
||||
TII->reverseBranchCondition(Cond);
|
||||
int OldSize = 0, NewSize = 0;
|
||||
TII->removeBranch(*MBB, &OldSize);
|
||||
TII->insertBranch(*MBB, FBB, TBB, Cond, DL, &NewSize);
|
||||
removeBranch(MBB);
|
||||
insertBranch(MBB, FBB, TBB, Cond);
|
||||
finalizeBlockChanges(MBB, nullptr);
|
||||
return true;
|
||||
}
|
||||
if (FBB) {
|
||||
// We need to split the basic block here to obtain two long-range
|
||||
// unconditional branches.
|
||||
NewBB = createNewBlockAfter(*MBB);
|
||||
|
||||
BlockInfo[MBB->getNumber()].Size += (NewSize - OldSize);
|
||||
insertUncondBranch(NewBB, FBB);
|
||||
// Update the succesor lists according to the transformation to follow.
|
||||
// Do it here since if there's no split, no update is needed.
|
||||
MBB->replaceSuccessor(FBB, NewBB);
|
||||
NewBB->addSuccessor(FBB);
|
||||
}
|
||||
|
||||
// We now have an appropriate fall-through block in place (either naturally or
|
||||
// just created), so we can use the inverted the condition.
|
||||
MachineBasicBlock &NextBB = *std::next(MachineFunction::iterator(MBB));
|
||||
|
||||
DEBUG(dbgs() << " Insert B to " << printMBBReference(*TBB)
|
||||
<< ", invert condition and change dest. to "
|
||||
<< printMBBReference(NextBB) << '\n');
|
||||
|
||||
removeBranch(MBB);
|
||||
// Insert a new conditional branch and a new unconditional branch.
|
||||
insertBranch(MBB, &NextBB, TBB, Cond);
|
||||
|
||||
finalizeBlockChanges(MBB, NewBB);
|
||||
return true;
|
||||
} else if (FBB) {
|
||||
// We need to split the basic block here to obtain two long-range
|
||||
// unconditional branches.
|
||||
auto &NewBB = *MF->CreateMachineBasicBlock(MBB->getBasicBlock());
|
||||
MF->insert(++MBB->getIterator(), &NewBB);
|
||||
|
||||
// Insert an entry into BlockInfo to align it properly with the block
|
||||
// numbers.
|
||||
BlockInfo.insert(BlockInfo.begin() + NewBB.getNumber(), BasicBlockInfo());
|
||||
|
||||
unsigned &NewBBSize = BlockInfo[NewBB.getNumber()].Size;
|
||||
int NewBrSize;
|
||||
TII->insertUnconditionalBranch(NewBB, FBB, DL, &NewBrSize);
|
||||
NewBBSize += NewBrSize;
|
||||
|
||||
// Update the successor lists according to the transformation to follow.
|
||||
// Do it here since if there's no split, no update is needed.
|
||||
MBB->replaceSuccessor(FBB, &NewBB);
|
||||
NewBB.addSuccessor(FBB);
|
||||
|
||||
// Need to fix live-in lists if we track liveness.
|
||||
if (TRI->trackLivenessAfterRegAlloc(*MF))
|
||||
computeAndAddLiveIns(LiveRegs, NewBB);
|
||||
}
|
||||
// Branch cond can't be inverted.
|
||||
// In this case we always add a block after the MBB.
|
||||
DEBUG(dbgs() << " The branch condition can't be inverted. "
|
||||
<< " Insert a new BB after " << MBB->back());
|
||||
|
||||
// We now have an appropriate fall-through block in place (either naturally or
|
||||
// just created), so we can invert the condition.
|
||||
MachineBasicBlock &NextBB = *std::next(MachineFunction::iterator(MBB));
|
||||
if (!FBB)
|
||||
FBB = &(*std::next(MachineFunction::iterator(MBB)));
|
||||
|
||||
DEBUG(dbgs() << " Insert B to " << printMBBReference(*TBB)
|
||||
<< ", invert condition and change dest. to "
|
||||
<< printMBBReference(NextBB) << '\n');
|
||||
// This is the block with cond. branch and the distance to TBB is too long.
|
||||
// beq L1
|
||||
// L2:
|
||||
|
||||
unsigned &MBBSize = BlockInfo[MBB->getNumber()].Size;
|
||||
// We do the following transformation:
|
||||
// beq NewBB
|
||||
// b L2
|
||||
// NewBB:
|
||||
// b L1
|
||||
// L2:
|
||||
|
||||
// Insert a new conditional branch and a new unconditional branch.
|
||||
int RemovedSize = 0;
|
||||
TII->reverseBranchCondition(Cond);
|
||||
TII->removeBranch(*MBB, &RemovedSize);
|
||||
MBBSize -= RemovedSize;
|
||||
NewBB = createNewBlockAfter(*MBB);
|
||||
insertUncondBranch(NewBB, TBB);
|
||||
|
||||
int AddedSize = 0;
|
||||
TII->insertBranch(*MBB, &NextBB, TBB, Cond, DL, &AddedSize);
|
||||
MBBSize += AddedSize;
|
||||
DEBUG(dbgs() << " Insert cond B to the new BB " << printMBBReference(*NewBB)
|
||||
<< " Keep the exiting condition.\n"
|
||||
<< " Insert B to " << printMBBReference(*FBB) << ".\n"
|
||||
<< " In the new BB: Insert B to "
|
||||
<< printMBBReference(*TBB) << ".\n");
|
||||
|
||||
// Finally, keep the block offsets up to date.
|
||||
adjustBlockOffsets(*MBB);
|
||||
// Update the successor lists according to the transformation to follow.
|
||||
MBB->replaceSuccessor(TBB, NewBB);
|
||||
NewBB->addSuccessor(TBB);
|
||||
|
||||
// Replace branch in the current (MBB) block.
|
||||
removeBranch(MBB);
|
||||
insertBranch(MBB, NewBB, FBB, Cond);
|
||||
|
||||
finalizeBlockChanges(MBB, NewBB);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user