Move all work list processing to copyCoalesceWorkList().

This will make it possible to filter out erased instructions later.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157073 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jakob Stoklund Olesen 2012-05-18 21:09:40 +00:00
parent 90255a8517
commit b3776d33cf

View File

@ -91,13 +91,19 @@ namespace {
/// been remat'ed. /// been remat'ed.
SmallPtrSet<MachineInstr*, 8> ReMatDefs; SmallPtrSet<MachineInstr*, 8> ReMatDefs;
/// WorkList - Copy instructions yet to be coalesced.
SmallVector<MachineInstr*, 8> WorkList;
/// joinAllIntervals - join compatible live intervals /// joinAllIntervals - join compatible live intervals
void joinAllIntervals(); void joinAllIntervals();
/// copyCoalesceInMBB - Coalesce copies in the specified MBB, putting /// copyCoalesceInMBB - Coalesce copies in the specified MBB, putting
/// copies that cannot yet be coalesced into the "TryAgain" list. /// copies that cannot yet be coalesced into WorkList.
void copyCoalesceInMBB(MachineBasicBlock *MBB, void copyCoalesceInMBB(MachineBasicBlock *MBB);
std::vector<MachineInstr*> &TryAgain);
/// copyCoalesceWorkList - Try to coalesce all copies in WorkList after
/// position From. Return true if any progress was made.
bool copyCoalesceWorkList(unsigned From = 0);
/// joinCopy - Attempt to join intervals corresponding to SrcReg/DstReg, /// joinCopy - Attempt to join intervals corresponding to SrcReg/DstReg,
/// which are the src/dst of the copy instruction CopyMI. This returns /// which are the src/dst of the copy instruction CopyMI. This returns
@ -1528,41 +1534,52 @@ namespace {
}; };
} }
// Try joining WorkList copies starting from index From.
// Null out any successful joins.
bool RegisterCoalescer::copyCoalesceWorkList(unsigned From) {
assert(From <= WorkList.size() && "Out of range");
bool Progress = false;
for (unsigned i = From, e = WorkList.size(); i != e; ++i) {
if (!WorkList[i])
continue;
bool Again = false;
bool Success = joinCopy(WorkList[i], Again);
Progress |= Success;
if (Success || !Again)
WorkList[i] = 0;
}
return Progress;
}
void void
RegisterCoalescer::copyCoalesceInMBB(MachineBasicBlock *MBB, RegisterCoalescer::copyCoalesceInMBB(MachineBasicBlock *MBB) {
std::vector<MachineInstr*> &TryAgain) {
DEBUG(dbgs() << MBB->getName() << ":\n"); DEBUG(dbgs() << MBB->getName() << ":\n");
// Collect all copy-like instructions in MBB. Don't start coalescing anything // Collect all copy-like instructions in MBB. Don't start coalescing anything
// yet, it might invalidate the iterator. // yet, it might invalidate the iterator.
const unsigned PrevSize = TryAgain.size(); const unsigned PrevSize = WorkList.size();
for (MachineBasicBlock::iterator MII = MBB->begin(), E = MBB->end(); for (MachineBasicBlock::iterator MII = MBB->begin(), E = MBB->end();
MII != E; ++MII) MII != E; ++MII)
if (MII->isCopyLike()) if (MII->isCopyLike())
TryAgain.push_back(MII); WorkList.push_back(MII);
// Try coalescing the collected copies immediately. // Try coalescing the collected copies immediately, and remove the nulls.
// Null out the successful joins. // This prevents the WorkList from getting too large since most copies are
for (unsigned i = PrevSize, e = TryAgain.size(); i != e; ++i) { // joinable on the first attempt.
bool Again = false; if (copyCoalesceWorkList(PrevSize))
if (joinCopy(TryAgain[i], Again) || !Again) WorkList.erase(std::remove(WorkList.begin() + PrevSize, WorkList.end(),
TryAgain[i] = 0; (MachineInstr*)0), WorkList.end());
}
// Remove the nulls from TryAgain.
TryAgain.erase(std::remove(TryAgain.begin() + PrevSize, TryAgain.end(),
(MachineInstr*)0), TryAgain.end());
} }
void RegisterCoalescer::joinAllIntervals() { void RegisterCoalescer::joinAllIntervals() {
DEBUG(dbgs() << "********** JOINING INTERVALS ***********\n"); DEBUG(dbgs() << "********** JOINING INTERVALS ***********\n");
assert(WorkList.empty() && "Old data still around.");
std::vector<MachineInstr*> TryAgainList;
if (Loops->empty()) { if (Loops->empty()) {
// If there are no loops in the function, join intervals in function order. // If there are no loops in the function, join intervals in function order.
for (MachineFunction::iterator I = MF->begin(), E = MF->end(); for (MachineFunction::iterator I = MF->begin(), E = MF->end();
I != E; ++I) I != E; ++I)
copyCoalesceInMBB(I, TryAgainList); copyCoalesceInMBB(I);
} else { } else {
// Otherwise, join intervals in inner loops before other intervals. // Otherwise, join intervals in inner loops before other intervals.
// Unfortunately we can't just iterate over loop hierarchy here because // Unfortunately we can't just iterate over loop hierarchy here because
@ -1581,34 +1598,20 @@ void RegisterCoalescer::joinAllIntervals() {
// Finally, join intervals in loop nest order. // Finally, join intervals in loop nest order.
for (unsigned i = 0, e = MBBs.size(); i != e; ++i) for (unsigned i = 0, e = MBBs.size(); i != e; ++i)
copyCoalesceInMBB(MBBs[i].second, TryAgainList); copyCoalesceInMBB(MBBs[i].second);
} }
// Joining intervals can allow other intervals to be joined. Iteratively join // Joining intervals can allow other intervals to be joined. Iteratively join
// until we make no progress. // until we make no progress.
bool ProgressMade = true; while (copyCoalesceWorkList())
while (ProgressMade) { /* empty */ ;
ProgressMade = false;
for (unsigned i = 0, e = TryAgainList.size(); i != e; ++i) {
MachineInstr *&TheCopy = TryAgainList[i];
if (!TheCopy)
continue;
bool Again = false;
bool Success = joinCopy(TheCopy, Again);
if (Success || !Again) {
TheCopy= 0; // Mark this one as done.
ProgressMade = true;
}
}
}
} }
void RegisterCoalescer::releaseMemory() { void RegisterCoalescer::releaseMemory() {
JoinedCopies.clear(); JoinedCopies.clear();
ReMatCopies.clear(); ReMatCopies.clear();
ReMatDefs.clear(); ReMatDefs.clear();
WorkList.clear();
} }
bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) { bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) {