diff options
author | Chris Lattner <sabre@nondot.org> | 2005-08-22 20:59:30 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2005-08-22 20:59:30 +0000 |
commit | a411cbca5c081f0813ff507901be412903894423 (patch) | |
tree | 4ef3701b8322dd1bec842e0d2103cb897f57a3b5 /lib/CodeGen/RegAllocLinearScan.cpp | |
parent | a6c1750362ffb5e8c5b5b5232442cd4c49eafdc8 (diff) |
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
Diffstat (limited to 'lib/CodeGen/RegAllocLinearScan.cpp')
-rw-r--r-- | lib/CodeGen/RegAllocLinearScan.cpp | 75 |
1 files changed, 55 insertions, 20 deletions
diff --git a/lib/CodeGen/RegAllocLinearScan.cpp b/lib/CodeGen/RegAllocLinearScan.cpp index ce58e59cb5..6289754f9f 100644 --- a/lib/CodeGen/RegAllocLinearScan.cpp +++ b/lib/CodeGen/RegAllocLinearScan.cpp @@ -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; |