From 834a2316a30b299063151e666ca8ad61e5accc4f Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 22 Aug 2005 20:59:30 +0000 Subject: 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 --- llvm/lib/CodeGen/RegAllocLinearScan.cpp | 75 ++++++++++++++++++++++++--------- 1 file changed, 55 insertions(+), 20 deletions(-) (limited to 'llvm/lib/CodeGen/RegAllocLinearScan.cpp') 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; -- cgit v1.2.3