[llvm-commits] CVS: llvm/lib/CodeGen/RegAllocLinearScan.cpp LiveIntervals.h LiveIntervals.cpp
Alkis Evlogimenos
alkis at cs.uiuc.edu
Sun May 30 02:28:02 PDT 2004
Changes in directory llvm/lib/CodeGen:
RegAllocLinearScan.cpp updated: 1.72 -> 1.73
LiveIntervals.h updated: 1.24 -> 1.25
LiveIntervals.cpp updated: 1.74 -> 1.75
---
Log message:
When spilling an register, introduce a new temporary for each of its
spills. This allows for more flexibility when allocating registers for
spill code.
---
Diffs of the changes: (+83 -56)
Index: llvm/lib/CodeGen/RegAllocLinearScan.cpp
diff -u llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.72 llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.73
--- llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.72 Fri May 7 22:50:03 2004
+++ llvm/lib/CodeGen/RegAllocLinearScan.cpp Sun May 30 02:24:39 2004
@@ -27,6 +27,7 @@
#include <algorithm>
#include <cmath>
#include <iostream>
+#include <set>
using namespace llvm;
@@ -366,24 +367,26 @@
DEBUG(std::cerr << "\t\tregister with min weight: "
<< mri_->getName(minReg) << " (" << minWeight << ")\n");
- // if the current has the minimum weight, we need to modify it,
- // push it back in unhandled and let the linear scan algorithm run
- // again
+ // if the current has the minimum weight, we need to spill it and
+ // add any added intervals back to unhandled, and restart
+ // linearscan.
if (cur->weight <= minWeight) {
DEBUG(std::cerr << "\t\t\tspilling(c): " << *cur << '\n';);
int slot = vrm_->assignVirt2StackSlot(cur->reg);
- li_->updateSpilledInterval(*cur, *vrm_, slot);
+ std::vector<LiveIntervals::Interval*> added =
+ li_->addIntervalsForSpills(*cur, *vrm_, slot);
- // if we didn't eliminate the interval find where to add it
- // back to unhandled. We need to scan since unhandled are
- // sorted on earliest start point and we may have changed our
- // start point.
- if (!cur->empty()) {
- IntervalPtrs::iterator it = unhandled_.begin();
- while (it != unhandled_.end() && (*it)->start() < cur->start())
- ++it;
- unhandled_.insert(it, cur);
+ // merge added with unhandled
+ std::vector<LiveIntervals::Interval*>::iterator addedIt = added.begin();
+ std::vector<LiveIntervals::Interval*>::iterator addedItEnd = added.end();
+ for (IntervalPtrs::iterator i = unhandled_.begin(), e = unhandled_.end();
+ i != e && addedIt != addedItEnd; ++i) {
+ if ((*i)->start() > (*addedIt)->start())
+ i = unhandled_.insert(i, *(addedIt++));
}
+ while (addedIt != addedItEnd)
+ unhandled_.push_back(*(addedIt++));
+
return;
}
@@ -395,6 +398,7 @@
// otherwise we spill all intervals aliasing the register with
// minimum weight, rollback to the interval with the earliest
// start point and let the linear scan algorithm run again
+ std::vector<LiveIntervals::Interval*> added;
assert(MRegisterInfo::isPhysicalRegister(minReg) &&
"did not choose a register to spill?");
std::vector<bool> toSpill(mri_->getNumRegs(), false);
@@ -403,6 +407,8 @@
toSpill[*as] = true;
unsigned earliestStart = cur->start();
+ std::set<unsigned> spilled;
+
for (IntervalPtrs::iterator i = active_.begin(); i != active_.end(); ++i) {
unsigned reg = (*i)->reg;
if (MRegisterInfo::isVirtualRegister(reg) &&
@@ -411,7 +417,10 @@
DEBUG(std::cerr << "\t\t\tspilling(a): " << **i << '\n');
earliestStart = std::min(earliestStart, (*i)->start());
int slot = vrm_->assignVirt2StackSlot((*i)->reg);
- li_->updateSpilledInterval(**i, *vrm_, slot);
+ std::vector<LiveIntervals::Interval*> newIs =
+ li_->addIntervalsForSpills(**i, *vrm_, slot);
+ std::copy(newIs.begin(), newIs.end(), std::back_inserter(added));
+ spilled.insert(reg);
}
}
for (IntervalPtrs::iterator i = inactive_.begin();
@@ -423,7 +432,10 @@
DEBUG(std::cerr << "\t\t\tspilling(i): " << **i << '\n');
earliestStart = std::min(earliestStart, (*i)->start());
int slot = vrm_->assignVirt2StackSlot((*i)->reg);
- li_->updateSpilledInterval(**i, *vrm_, slot);
+ std::vector<LiveIntervals::Interval*> newIs =
+ li_->addIntervalsForSpills(**i, *vrm_, slot);
+ std::copy(newIs.begin(), newIs.end(), std::back_inserter(added));
+ spilled.insert(reg);
}
}
@@ -433,7 +445,7 @@
while (!handled_.empty()) {
IntervalPtrs::value_type i = handled_.back();
// if this interval starts before t we are done
- if (!i->empty() && i->start() < earliestStart)
+ if (i->start() < earliestStart)
break;
DEBUG(std::cerr << "\t\t\tundo changes for: " << *i << '\n');
handled_.pop_back();
@@ -445,20 +457,10 @@
unhandled_.push_front(i);
}
else {
+ if (!spilled.count(i->reg))
+ unhandled_.push_front(i);
prt_->delRegUse(vrm_->getPhys(i->reg));
vrm_->clearVirt(i->reg);
- if (i->spilled()) {
- if (!i->empty()) {
- IntervalPtrs::iterator it = unhandled_.begin();
- while (it != unhandled_.end() &&
- (*it)->start() < i->start())
- ++it;
- unhandled_.insert(it, i);
- }
- }
- else
- unhandled_.push_front(i);
-
}
}
else if ((it = find(inactive_.begin(), inactive_.end(), i)) != inactive_.end()) {
@@ -466,18 +468,9 @@
if (MRegisterInfo::isPhysicalRegister(i->reg))
unhandled_.push_front(i);
else {
- vrm_->clearVirt(i->reg);
- if (i->spilled()) {
- if (!i->empty()) {
- IntervalPtrs::iterator it = unhandled_.begin();
- while (it != unhandled_.end() &&
- (*it)->start() < i->start())
- ++it;
- unhandled_.insert(it, i);
- }
- }
- else
+ if (!spilled.count(i->reg))
unhandled_.push_front(i);
+ vrm_->clearVirt(i->reg);
}
}
else {
@@ -501,6 +494,19 @@
prt_->addRegUse(vrm_->getPhys((*i)->reg));
}
}
+
+ std::sort(added.begin(), added.end(), LiveIntervals::StartPointPtrComp());
+ // merge added with unhandled
+ std::vector<LiveIntervals::Interval*>::iterator addedIt = added.begin();
+ std::vector<LiveIntervals::Interval*>::iterator addedItEnd = added.end();
+ for (IntervalPtrs::iterator i = unhandled_.begin(), e = unhandled_.end();
+ i != e && addedIt != addedItEnd; ++i) {
+ if ((*i)->start() > (*addedIt)->start())
+ i = unhandled_.insert(i, *(addedIt++));
+ }
+ while (addedIt != addedItEnd)
+ unhandled_.push_back(*(addedIt++));
+
}
unsigned RA::getFreePhysReg(IntervalPtrs::value_type cur)
Index: llvm/lib/CodeGen/LiveIntervals.h
diff -u llvm/lib/CodeGen/LiveIntervals.h:1.24 llvm/lib/CodeGen/LiveIntervals.h:1.25
--- llvm/lib/CodeGen/LiveIntervals.h:1.24 Sat May 29 11:18:57 2004
+++ llvm/lib/CodeGen/LiveIntervals.h Sun May 30 02:24:39 2004
@@ -80,9 +80,9 @@
}
};
- struct EndPointComp {
- bool operator()(const Interval& lhs, const Interval& rhs) {
- return lhs.ranges.back().second < rhs.ranges.back().second;
+ struct StartPointPtrComp {
+ bool operator()(const Interval* lhs, const Interval* rhs) {
+ return lhs->ranges.front().first < rhs->ranges.front().first;
}
};
@@ -164,7 +164,9 @@
Intervals& getIntervals() { return intervals_; }
- void updateSpilledInterval(Interval& i, VirtRegMap& vrm, int slot);
+ std::vector<Interval*> addIntervalsForSpills(const Interval& i,
+ VirtRegMap& vrm,
+ int slot);
private:
/// computeIntervals - compute live intervals
Index: llvm/lib/CodeGen/LiveIntervals.cpp
diff -u llvm/lib/CodeGen/LiveIntervals.cpp:1.74 llvm/lib/CodeGen/LiveIntervals.cpp:1.75
--- llvm/lib/CodeGen/LiveIntervals.cpp:1.74 Sat May 29 11:18:57 2004
+++ llvm/lib/CodeGen/LiveIntervals.cpp Sun May 30 02:24:39 2004
@@ -186,19 +186,23 @@
return true;
}
-void LiveIntervals::updateSpilledInterval(Interval& li,
- VirtRegMap& vrm,
- int slot)
+std::vector<LiveIntervals::Interval*>
+LiveIntervals::addIntervalsForSpills(const Interval& li,
+ VirtRegMap& vrm,
+ int slot)
{
+ std::vector<Interval*> added;
+
assert(li.weight != HUGE_VAL &&
"attempt to spill already spilled interval!");
- Interval::Ranges oldRanges;
- swap(oldRanges, li.ranges);
- DEBUG(std::cerr << "\t\t\t\tupdating interval: " << li);
+ DEBUG(std::cerr << "\t\t\t\tadding intervals for spills for interval: "
+ << li << '\n');
+
+ const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(li.reg);
- for (Interval::Ranges::iterator i = oldRanges.begin(), e = oldRanges.end();
- i != e; ++i) {
+ for (Interval::Ranges::const_iterator
+ i = li.ranges.begin(), e = li.ranges.end(); i != e; ++i) {
unsigned index = getBaseIndex(i->first);
unsigned end = getBaseIndex(i->second-1) + InstrSlots::NUM;
for (; index < end; index += InstrSlots::NUM) {
@@ -240,16 +244,31 @@
unsigned end = 1 + (mop.isDef() ?
getUseIndex(index+InstrSlots::NUM) :
getUseIndex(index));
- li.addRange(start, end);
+
+ // create a new register for this spill
+ unsigned nReg =
+ mf_->getSSARegMap()->createVirtualRegister(rc);
+ mi->SetMachineOperandReg(i, nReg);
+ vrm.grow();
+ vrm.assignVirt2StackSlot(nReg, slot);
+ Interval& nI = getOrCreateInterval(nReg);
+ assert(nI.empty());
+ // the spill weight is now infinity as it
+ // cannot be spilled again
+ nI.weight = HUGE_VAL;
+ nI.addRange(start, end);
+ added.push_back(&nI);
+ // update live variables
+ lv_->addVirtualRegisterKilled(nReg, mi->getParent(),mi);
+ DEBUG(std::cerr << "\t\t\t\tadded new interval: "
+ << nI << '\n');
}
}
}
}
}
- // the new spill weight is now infinity as it cannot be spilled again
- li.weight = HUGE_VAL;
- DEBUG(std::cerr << '\n');
- DEBUG(std::cerr << "\t\t\t\tupdated interval: " << li << '\n');
+
+ return added;
}
void LiveIntervals::printRegName(unsigned reg) const
More information about the llvm-commits
mailing list