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 | 834a2316a30b299063151e666ca8ad61e5accc4f (patch) | |
tree | f5b7a193c6e322bb812d911574002b4b1b041b6f /llvm/lib/CodeGen/RegAllocLinearScan.cpp | |
parent | 95a157ae1a354df0a0dcbeedc3bdd3c7ee74bfc2 (diff) | |
download | bcm5719-llvm-834a2316a30b299063151e666ca8ad61e5accc4f.tar.gz bcm5719-llvm-834a2316a30b299063151e666ca8ad61e5accc4f.zip |
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.
llvm-svn: 22972
Diffstat (limited to 'llvm/lib/CodeGen/RegAllocLinearScan.cpp')
-rw-r--r-- | llvm/lib/CodeGen/RegAllocLinearScan.cpp | 75 |
1 files changed, 55 insertions, 20 deletions
diff --git a/llvm/lib/CodeGen/RegAllocLinearScan.cpp b/llvm/lib/CodeGen/RegAllocLinearScan.cpp index ce58e59cb55..6289754f9ff 100644 --- a/llvm/lib/CodeGen/RegAllocLinearScan.cpp +++ b/llvm/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; |