Try to avoid scanning the fixed list. On architectures with a non-stupid

number of regs (e.g. most riscs), many functions won't need to use callee
clobbered registers.  Do a speculative check to see if we can get a free
register without processing the fixed list (which has all of these).  This
saves a lot of time on machines with lots of callee clobbered regs (e.g.
ppc and itanium, also x86).

This reduces ppc llc compile time from 184s -> 172s on kc++.  This is probably
worth FAR FAR more on itanium though.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22972 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2005-08-22 20:59:30 +00:00
parent a6c1750362
commit a411cbca5c

View File

@ -381,29 +381,64 @@ void RA::assignRegOrStackSlotAtInterval(LiveInterval* cur)
SpillWeightsToAdd.push_back(std::make_pair(reg, i->first->weight));
}
}
// For every interval in fixed we overlap with, mark the register as not free
// and update spill weights.
for (unsigned i = 0, e = fixed_.size(); i != e; ++i) {
IntervalPtr &IP = fixed_[i];
LiveInterval *I = IP.first;
if (I->endNumber() > StartPosition) {
LiveInterval::iterator II = I->advanceTo(IP.second, StartPosition);
IP.second = II;
if (II != I->begin() && II->start > StartPosition)
--II;
if (cur->overlapsFrom(*I, II)) {
unsigned reg = I->reg;
prt_->addRegUse(reg);
SpillWeightsToAdd.push_back(std::make_pair(reg, I->weight));
// Speculatively check to see if we can get a register right now. If not,
// we know we won't be able to by adding more constraints. If so, we can
// check to see if it is valid. Doing an exhaustive search of the fixed_ list
// is very bad (it contains all callee clobbered registers for any functions
// with a call), so we want to avoid doing that if possible.
unsigned physReg = getFreePhysReg(cur);
if (physReg) {
// We got a register. However, if it's in the fixed_ list, we might
// conflict with it. Check to see if we conflict with it.
bool ConflictsWithFixed = false;
for (unsigned i = 0, e = fixed_.size(); i != e; ++i) {
if (physReg == fixed_[i].first->reg) {
// Okay, this reg is on the fixed list. Check to see if we actually
// conflict.
IntervalPtr &IP = fixed_[i];
LiveInterval *I = IP.first;
if (I->endNumber() > StartPosition) {
LiveInterval::iterator II = I->advanceTo(IP.second, StartPosition);
IP.second = II;
if (II != I->begin() && II->start > StartPosition)
--II;
if (cur->overlapsFrom(*I, II))
ConflictsWithFixed = true;
}
break;
}
}
}
// Okay, the register picked by our speculative getFreePhysReg call turned
// out to be in use. Actually add all of the conflicting fixed registers to
// prt so we can do an accurate query.
if (ConflictsWithFixed) {
// For every interval in fixed we overlap with, mark the register as not free
// and update spill weights.
for (unsigned i = 0, e = fixed_.size(); i != e; ++i) {
IntervalPtr &IP = fixed_[i];
LiveInterval *I = IP.first;
if (I->endNumber() > StartPosition) {
LiveInterval::iterator II = I->advanceTo(IP.second, StartPosition);
IP.second = II;
if (II != I->begin() && II->start > StartPosition)
--II;
if (cur->overlapsFrom(*I, II)) {
unsigned reg = I->reg;
prt_->addRegUse(reg);
SpillWeightsToAdd.push_back(std::make_pair(reg, I->weight));
}
}
}
// Using the newly updated prt_ object, which includes conflicts in the
// future, see if there are any registers available.
unsigned physReg = getFreePhysReg(cur);
// Using the newly updated prt_ object, which includes conflicts in the
// future, see if there are any registers available.
physReg = getFreePhysReg(cur);
}
}
// Restore the physical register tracker, removing information about the
// future.
*prt_ = backupPrt;