Two tail merging improvements:

When considering blocks with more than 2 predecessors, merge the block with
the largest number of matching insns, rather than the first block found.
Considering that 1 matching insn is enough to show a win for candidates that
already end with a branch.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37315 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Dale Johannesen 2007-05-23 21:07:20 +00:00
parent 79b48b8bc0
commit 7aea832034

View File

@ -234,10 +234,15 @@ static unsigned HashMachineInstr(const MachineInstr *MI) {
return Hash; return Hash;
} }
/// HashEndOfMBB - Hash the last two instructions in the MBB. We hash two /// HashEndOfMBB - Hash the last few instructions in the MBB. For blocks
/// instructions, because cross-jumping only saves code when at least two /// with no successors, we hash two instructions, because cross-jumping
/// instructions are removed (since a branch must be inserted). /// only saves code when at least two instructions are removed (since a
static unsigned HashEndOfMBB(const MachineBasicBlock *MBB) { /// branch must be inserted). For blocks with a successor, one of the
/// two blocks to be tail-merged will end with a branch already, so
/// it gains to cross-jump even for one instruction.
static unsigned HashEndOfMBB(const MachineBasicBlock *MBB,
unsigned minCommonTailLength) {
MachineBasicBlock::const_iterator I = MBB->end(); MachineBasicBlock::const_iterator I = MBB->end();
if (I == MBB->begin()) if (I == MBB->begin())
return 0; // Empty MBB. return 0; // Empty MBB.
@ -245,7 +250,7 @@ static unsigned HashEndOfMBB(const MachineBasicBlock *MBB) {
--I; --I;
unsigned Hash = HashMachineInstr(I); unsigned Hash = HashMachineInstr(I);
if (I == MBB->begin()) if (I == MBB->begin() || minCommonTailLength == 1)
return Hash; // Single instr MBB. return Hash; // Single instr MBB.
--I; --I;
@ -425,6 +430,7 @@ static void FixTail(MachineBasicBlock* CurMBB, MachineBasicBlock *SuccBB,
bool BranchFolder::TryMergeBlocks(MachineBasicBlock *SuccBB, bool BranchFolder::TryMergeBlocks(MachineBasicBlock *SuccBB,
MachineBasicBlock* PredBB) { MachineBasicBlock* PredBB) {
unsigned minCommonTailLength = (SuccBB ? 1 : 2);
MadeChange = false; MadeChange = false;
// Sort by hash value so that blocks with identical end sequences sort // Sort by hash value so that blocks with identical end sequences sort
@ -446,44 +452,42 @@ bool BranchFolder::TryMergeBlocks(MachineBasicBlock *SuccBB,
continue; continue;
} }
// Determine the actual length of the shared tail between these two basic // Look through all the blocks that have the same hash as this one, and
// blocks. Because the hash can have collisions, it's possible that this is // find the one that has the largest number of instructions in common.
// less than 2.
MachineBasicBlock::iterator BBI1, BBI2;
unsigned CommonTailLen =
ComputeCommonTailLength(CurMBB, (MergePotentials.end()-2)->second,
BBI1, BBI2);
// If the tails don't have at least two instructions in common, see if there
// is anything else in the equivalence class that does match.
// Since instructions may get combined later (e.g. single stores into // Since instructions may get combined later (e.g. single stores into
// store multiple) this measure is not particularly accurate. // store multiple) this measure is not particularly accurate.
if (CommonTailLen < 2) { MachineBasicBlock::iterator BBI1, BBI2;
unsigned FoundMatch = ~0U;
for (int i = MergePotentials.size()-2; unsigned FoundMatch = ~0U;
i != -1 && MergePotentials[i].first == CurHash; --i) { unsigned maxCommonTailLength = 0U;
CommonTailLen = ComputeCommonTailLength(CurMBB, for (int i = MergePotentials.size()-2;
MergePotentials[i].second, i != -1 && MergePotentials[i].first == CurHash; --i) {
BBI1, BBI2); MachineBasicBlock::iterator TrialBBI1, TrialBBI2;
if (CommonTailLen >= 2) { unsigned CommonTailLen = ComputeCommonTailLength(CurMBB,
FoundMatch = i; MergePotentials[i].second,
break; TrialBBI1, TrialBBI2);
} if (CommonTailLen >= minCommonTailLength &&
CommonTailLen >= maxCommonTailLength) {
FoundMatch = i;
maxCommonTailLength = CommonTailLen;
BBI1 = TrialBBI1;
BBI2 = TrialBBI2;
} }
}
// If we didn't find anything that has at least two instructions matching
// this one, bail out. // If we didn't find anything that has at least minCommonTailLength
if (FoundMatch == ~0U) { // instructions matching this one, bail out.
// Put the unconditional branch back, if we need one. if (FoundMatch == ~0U) {
if (SuccBB && CurMBB != PredBB) // Put the unconditional branch back, if we need one.
FixTail(CurMBB, SuccBB, TII); if (SuccBB && CurMBB != PredBB)
MergePotentials.pop_back(); FixTail(CurMBB, SuccBB, TII);
continue; MergePotentials.pop_back();
} continue;
// Otherwise, move the matching block to the right position.
std::swap(MergePotentials[FoundMatch], *(MergePotentials.end()-2));
} }
// Otherwise, move the matching block to the right position.
if (FoundMatch != MergePotentials.size()-2)
std::swap(MergePotentials[FoundMatch], *(MergePotentials.end()-2));
MachineBasicBlock *MBB2 = (MergePotentials.end()-2)->second; MachineBasicBlock *MBB2 = (MergePotentials.end()-2)->second;
@ -541,7 +545,7 @@ bool BranchFolder::TailMergeBlocks(MachineFunction &MF) {
MergePotentials.clear(); MergePotentials.clear();
for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) { for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
if (I->succ_empty()) if (I->succ_empty())
MergePotentials.push_back(std::make_pair(HashEndOfMBB(I), I)); MergePotentials.push_back(std::make_pair(HashEndOfMBB(I, 2U), I));
} }
// See if we can do any tail merging on those. // See if we can do any tail merging on those.
MadeChange |= TryMergeBlocks(NULL, NULL); MadeChange |= TryMergeBlocks(NULL, NULL);
@ -596,7 +600,7 @@ bool BranchFolder::TailMergeBlocks(MachineFunction &MF) {
// reinsert conditional branch only, for now // reinsert conditional branch only, for now
TII->InsertBranch(*PBB, (TBB==IBB) ? FBB : TBB, 0, NewCond); TII->InsertBranch(*PBB, (TBB==IBB) ? FBB : TBB, 0, NewCond);
} }
MergePotentials.push_back(std::make_pair(HashEndOfMBB(PBB), *P)); MergePotentials.push_back(std::make_pair(HashEndOfMBB(PBB, 1U), *P));
} }
} }
if (MergePotentials.size() >= 2) if (MergePotentials.size() >= 2)