Increase code clarity.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@11151 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Alkis Evlogimenos 2004-02-06 18:08:18 +00:00
parent a6859b4715
commit f5eaf16b94

View File

@ -119,6 +119,9 @@ namespace {
int instrAdded_; int instrAdded_;
typedef std::vector<float> SpillWeights;
SpillWeights spillWeights_;
public: public:
RA() RA()
: prt_(NULL) { : prt_(NULL) {
@ -153,12 +156,13 @@ namespace {
/// overlapping ones to the active list /// overlapping ones to the active list
void processInactiveIntervals(IntervalPtrs::value_type cur); void processInactiveIntervals(IntervalPtrs::value_type cur);
/// assignStackSlotAtInterval - choose and spill /// updateSpillWeights - updates the spill weights of the
/// interval. Currently we spill the interval with the last /// specifed physical register and its weight
/// end point in the active and inactive lists and the current void updateSpillWeights(unsigned reg, SpillWeights::value_type weight);
/// interval
void assignStackSlotAtInterval(IntervalPtrs::value_type cur, /// assignRegOrStackSlotAtInterval - assign a register if one
const PhysRegTracker& backupPtr); /// is available, or spill.
void assignRegOrStackSlotAtInterval(IntervalPtrs::value_type cur);
/// ///
/// register handling helpers /// register handling helpers
@ -329,42 +333,7 @@ bool RA::runOnMachineFunction(MachineFunction &fn) {
// a free physical register or spill an interval in order to // a free physical register or spill an interval in order to
// assign it one (we could spill the current though). // assign it one (we could spill the current though).
else { else {
PhysRegTracker backupPrt = prt_; assignRegOrStackSlotAtInterval(cur);
// for every interval in inactive we overlap with, mark the
// register as not free
for (IntervalPtrs::const_iterator i = inactive_.begin(),
e = inactive_.end(); i != e; ++i) {
unsigned reg = (*i)->reg;
if (MRegisterInfo::isVirtualRegister(reg))
reg = v2pMap_[reg];
if (cur->overlaps(**i)) {
prt_.addPhysRegUse(reg);
}
}
// for every interval in fixed we overlap with,
// mark the register as not free
for (IntervalPtrs::const_iterator i = fixed_.begin(),
e = fixed_.end(); i != e; ++i) {
assert(MRegisterInfo::isPhysicalRegister((*i)->reg) &&
"virtual register interval in fixed set?");
if (cur->overlaps(**i))
prt_.addPhysRegUse((*i)->reg);
}
DEBUG(std::cerr << "\tallocating current interval:\n");
unsigned physReg = getFreePhysReg(cur);
if (!physReg) {
assignStackSlotAtInterval(cur, backupPrt);
}
else {
prt_ = backupPrt;
assignVirt2PhysReg(cur->reg, physReg);
active_.push_back(cur);
}
} }
DEBUG(printIntervals("\tactive", active_.begin(), active_.end())); DEBUG(printIntervals("\tactive", active_.begin(), active_.end()));
@ -609,132 +578,136 @@ void RA::processInactiveIntervals(IntervalPtrs::value_type cur)
} }
} }
namespace { void RA::updateSpillWeights(unsigned reg, SpillWeights::value_type weight)
template <typename T> {
void updateWeight(std::vector<T>& rw, int reg, T w) spillWeights_[reg] += weight;
{ for (const unsigned* as = mri_->getAliasSet(reg); *as; ++as)
if (rw[reg] == std::numeric_limits<T>::max() || spillWeights_[*as] += weight;
w == std::numeric_limits<T>::max())
rw[reg] = std::numeric_limits<T>::max();
else
rw[reg] += w;
}
} }
void RA::assignStackSlotAtInterval(IntervalPtrs::value_type cur, void RA::assignRegOrStackSlotAtInterval(IntervalPtrs::value_type cur)
const PhysRegTracker& backupPrt)
{ {
DEBUG(std::cerr << "\t\tassigning stack slot at interval " DEBUG(std::cerr << "\tallocating current interval:\n");
<< *cur << ":\n");
std::vector<float> regWeight(mri_->getNumRegs(), 0.0); PhysRegTracker backupPrt = prt_;
// for each interval in active spillWeights_.assign(mri_->getNumRegs(), 0.0);
// for each interval in active update spill weights
for (IntervalPtrs::const_iterator i = active_.begin(), e = active_.end(); for (IntervalPtrs::const_iterator i = active_.begin(), e = active_.end();
i != e; ++i) { i != e; ++i) {
unsigned reg = (*i)->reg; unsigned reg = (*i)->reg;
if (MRegisterInfo::isVirtualRegister(reg)) { if (MRegisterInfo::isVirtualRegister(reg))
reg = v2pMap_[reg]; reg = v2pMap_[reg];
} updateSpillWeights(reg, (*i)->weight);
updateWeight(regWeight, reg, (*i)->weight);
for (const unsigned* as = mri_->getAliasSet(reg); *as; ++as)
updateWeight(regWeight, *as, (*i)->weight);
} }
// for each interval in inactive that overlaps // for every interval in inactive we overlap with, mark the
// register as not free and update spill weights
for (IntervalPtrs::const_iterator i = inactive_.begin(), for (IntervalPtrs::const_iterator i = inactive_.begin(),
e = inactive_.end(); i != e; ++i) { e = inactive_.end(); i != e; ++i) {
if (!cur->overlaps(**i)) if (cur->overlaps(**i)) {
continue; unsigned reg = (*i)->reg;
if (MRegisterInfo::isVirtualRegister(reg))
unsigned reg = (*i)->reg; reg = v2pMap_[reg];
if (MRegisterInfo::isVirtualRegister(reg)) { prt_.addPhysRegUse(reg);
reg = v2pMap_[reg]; updateSpillWeights(reg, (*i)->weight);
} }
updateWeight(regWeight, reg, (*i)->weight);
for (const unsigned* as = mri_->getAliasSet(reg); *as; ++as)
updateWeight(regWeight, *as, (*i)->weight);
} }
// for each fixed interval that overlaps // for every interval in fixed we overlap with,
for (IntervalPtrs::const_iterator i = fixed_.begin(), e = fixed_.end(); // mark the register as not free and update spill weights
i != e; ++i) { for (IntervalPtrs::const_iterator i = fixed_.begin(),
if (!cur->overlaps(**i)) e = fixed_.end(); i != e; ++i) {
continue; if (cur->overlaps(**i)) {
unsigned reg = (*i)->reg;
assert(MRegisterInfo::isPhysicalRegister((*i)->reg) && prt_.addPhysRegUse(reg);
"virtual register interval in fixed set?"); updateSpillWeights(reg, (*i)->weight);
updateWeight(regWeight, (*i)->reg, (*i)->weight); }
for (const unsigned* as = mri_->getAliasSet((*i)->reg); *as; ++as)
updateWeight(regWeight, *as, (*i)->weight);
} }
unsigned physReg = getFreePhysReg(cur);
// if we find a free register, we are done: restore original
// register tracker, assign this virtual to the free physical
// register and add this interval to the active list.
if (physReg) {
prt_ = backupPrt;
assignVirt2PhysReg(cur->reg, physReg);
active_.push_back(cur);
return;
}
DEBUG(std::cerr << "\t\tassigning stack slot at interval "<< *cur << ":\n");
float minWeight = std::numeric_limits<float>::max(); float minWeight = std::numeric_limits<float>::max();
unsigned minReg = 0; unsigned minReg = 0;
const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg); const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg);
for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_); for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_);
i != rc->allocation_order_end(*mf_); ++i) { i != rc->allocation_order_end(*mf_); ++i) {
unsigned reg = *i; unsigned reg = *i;
if (!prt_.isPhysRegReserved(reg) && minWeight > regWeight[reg]) { if (!prt_.isPhysRegReserved(reg) && minWeight > spillWeights_[reg]) {
minWeight = regWeight[reg]; minWeight = spillWeights_[reg];
minReg = reg; minReg = reg;
} }
} }
DEBUG(std::cerr << "\t\t\tregister with min weight: " DEBUG(std::cerr << "\t\t\tregister with min weight: "
<< mri_->getName(minReg) << " (" << minWeight << ")\n"); << mri_->getName(minReg) << " (" << minWeight << ")\n");
// if the current has the minimum weight, we are done: restore
// original register tracker and assign a stack slot to this
// virtual register
if (cur->weight < minWeight) { if (cur->weight < minWeight) {
prt_ = backupPrt; prt_ = backupPrt;
DEBUG(std::cerr << "\t\t\t\tspilling: " << *cur << '\n'); DEBUG(std::cerr << "\t\t\t\tspilling: " << *cur << '\n');
assignVirt2StackSlot(cur->reg); assignVirt2StackSlot(cur->reg);
return;
} }
else {
std::vector<bool> toSpill(mri_->getNumRegs(), false);
toSpill[minReg] = true;
for (const unsigned* as = mri_->getAliasSet(minReg); *as; ++as)
toSpill[*as] = true;
std::vector<unsigned> spilled; std::vector<bool> toSpill(mri_->getNumRegs(), false);
for (IntervalPtrs::iterator i = active_.begin(); toSpill[minReg] = true;
i != active_.end(); ) { for (const unsigned* as = mri_->getAliasSet(minReg); *as; ++as)
unsigned reg = (*i)->reg; toSpill[*as] = true;
if (MRegisterInfo::isVirtualRegister(reg) &&
toSpill[v2pMap_[reg]] && std::vector<unsigned> spilled;
cur->overlaps(**i)) { for (IntervalPtrs::iterator i = active_.begin();
spilled.push_back(v2pMap_[reg]); i != active_.end(); ) {
DEBUG(std::cerr << "\t\t\t\tspilling : " << **i << '\n'); unsigned reg = (*i)->reg;
assignVirt2StackSlot(reg); if (MRegisterInfo::isVirtualRegister(reg) &&
i = active_.erase(i); toSpill[v2pMap_[reg]] &&
} cur->overlaps(**i)) {
else { spilled.push_back(v2pMap_[reg]);
++i; DEBUG(std::cerr << "\t\t\t\tspilling : " << **i << '\n');
} assignVirt2StackSlot(reg);
i = active_.erase(i);
} }
for (IntervalPtrs::iterator i = inactive_.begin(); else {
i != inactive_.end(); ) { ++i;
unsigned reg = (*i)->reg;
if (MRegisterInfo::isVirtualRegister(reg) &&
toSpill[v2pMap_[reg]] &&
cur->overlaps(**i)) {
DEBUG(std::cerr << "\t\t\t\tspilling : " << **i << '\n');
assignVirt2StackSlot(reg);
i = inactive_.erase(i);
}
else {
++i;
}
} }
unsigned physReg = getFreePhysReg(cur);
assert(physReg && "no free physical register after spill?");
prt_ = backupPrt;
for (unsigned i = 0; i < spilled.size(); ++i)
prt_.delPhysRegUse(spilled[i]);
assignVirt2PhysReg(cur->reg, physReg);
active_.push_back(cur);
} }
for (IntervalPtrs::iterator i = inactive_.begin();
i != inactive_.end(); ) {
unsigned reg = (*i)->reg;
if (MRegisterInfo::isVirtualRegister(reg) &&
toSpill[v2pMap_[reg]] &&
cur->overlaps(**i)) {
DEBUG(std::cerr << "\t\t\t\tspilling : " << **i << '\n');
assignVirt2StackSlot(reg);
i = inactive_.erase(i);
}
else {
++i;
}
}
physReg = getFreePhysReg(cur);
assert(physReg && "no free physical register after spill?");
prt_ = backupPrt;
for (unsigned i = 0; i < spilled.size(); ++i)
prt_.delPhysRegUse(spilled[i]);
assignVirt2PhysReg(cur->reg, physReg);
active_.push_back(cur);
} }
unsigned RA::getFreePhysReg(IntervalPtrs::value_type cur) unsigned RA::getFreePhysReg(IntervalPtrs::value_type cur)