aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/RegAllocLinearScan.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-08-22 20:59:30 +0000
committerChris Lattner <sabre@nondot.org>2005-08-22 20:59:30 +0000
commita411cbca5c081f0813ff507901be412903894423 (patch)
tree4ef3701b8322dd1bec842e0d2103cb897f57a3b5 /lib/CodeGen/RegAllocLinearScan.cpp
parenta6c1750362ffb5e8c5b5b5232442cd4c49eafdc8 (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.cpp75
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;