mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
When spilling an register, introduce a new temporary for each of its
spills. This allows for more flexibility when allocating registers for spill code. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@13907 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
25d4b54f93
commit
26f5a69e52
@ -80,9 +80,9 @@ namespace llvm {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EndPointComp {
|
struct StartPointPtrComp {
|
||||||
bool operator()(const Interval& lhs, const Interval& rhs) {
|
bool operator()(const Interval* lhs, const Interval* rhs) {
|
||||||
return lhs.ranges.back().second < rhs.ranges.back().second;
|
return lhs->ranges.front().first < rhs->ranges.front().first;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -164,7 +164,9 @@ namespace llvm {
|
|||||||
|
|
||||||
Intervals& getIntervals() { return intervals_; }
|
Intervals& getIntervals() { return intervals_; }
|
||||||
|
|
||||||
void updateSpilledInterval(Interval& i, VirtRegMap& vrm, int slot);
|
std::vector<Interval*> addIntervalsForSpills(const Interval& i,
|
||||||
|
VirtRegMap& vrm,
|
||||||
|
int slot);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// computeIntervals - compute live intervals
|
/// computeIntervals - compute live intervals
|
||||||
|
@ -186,19 +186,23 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LiveIntervals::updateSpilledInterval(Interval& li,
|
std::vector<LiveIntervals::Interval*>
|
||||||
VirtRegMap& vrm,
|
LiveIntervals::addIntervalsForSpills(const Interval& li,
|
||||||
int slot)
|
VirtRegMap& vrm,
|
||||||
|
int slot)
|
||||||
{
|
{
|
||||||
|
std::vector<Interval*> added;
|
||||||
|
|
||||||
assert(li.weight != HUGE_VAL &&
|
assert(li.weight != HUGE_VAL &&
|
||||||
"attempt to spill already spilled interval!");
|
"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');
|
||||||
|
|
||||||
for (Interval::Ranges::iterator i = oldRanges.begin(), e = oldRanges.end();
|
const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(li.reg);
|
||||||
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 index = getBaseIndex(i->first);
|
||||||
unsigned end = getBaseIndex(i->second-1) + InstrSlots::NUM;
|
unsigned end = getBaseIndex(i->second-1) + InstrSlots::NUM;
|
||||||
for (; index < end; index += InstrSlots::NUM) {
|
for (; index < end; index += InstrSlots::NUM) {
|
||||||
@ -240,16 +244,31 @@ void LiveIntervals::updateSpilledInterval(Interval& li,
|
|||||||
unsigned end = 1 + (mop.isDef() ?
|
unsigned end = 1 + (mop.isDef() ?
|
||||||
getUseIndex(index+InstrSlots::NUM) :
|
getUseIndex(index+InstrSlots::NUM) :
|
||||||
getUseIndex(index));
|
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;
|
return added;
|
||||||
DEBUG(std::cerr << '\n');
|
|
||||||
DEBUG(std::cerr << "\t\t\t\tupdated interval: " << li << '\n');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LiveIntervals::printRegName(unsigned reg) const
|
void LiveIntervals::printRegName(unsigned reg) const
|
||||||
|
@ -80,9 +80,9 @@ namespace llvm {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EndPointComp {
|
struct StartPointPtrComp {
|
||||||
bool operator()(const Interval& lhs, const Interval& rhs) {
|
bool operator()(const Interval* lhs, const Interval* rhs) {
|
||||||
return lhs.ranges.back().second < rhs.ranges.back().second;
|
return lhs->ranges.front().first < rhs->ranges.front().first;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -164,7 +164,9 @@ namespace llvm {
|
|||||||
|
|
||||||
Intervals& getIntervals() { return intervals_; }
|
Intervals& getIntervals() { return intervals_; }
|
||||||
|
|
||||||
void updateSpilledInterval(Interval& i, VirtRegMap& vrm, int slot);
|
std::vector<Interval*> addIntervalsForSpills(const Interval& i,
|
||||||
|
VirtRegMap& vrm,
|
||||||
|
int slot);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// computeIntervals - compute live intervals
|
/// computeIntervals - compute live intervals
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
@ -366,24 +367,26 @@ void RA::assignRegOrStackSlotAtInterval(IntervalPtrs::value_type cur)
|
|||||||
DEBUG(std::cerr << "\t\tregister with min weight: "
|
DEBUG(std::cerr << "\t\tregister with min weight: "
|
||||||
<< mri_->getName(minReg) << " (" << minWeight << ")\n");
|
<< mri_->getName(minReg) << " (" << minWeight << ")\n");
|
||||||
|
|
||||||
// if the current has the minimum weight, we need to modify it,
|
// if the current has the minimum weight, we need to spill it and
|
||||||
// push it back in unhandled and let the linear scan algorithm run
|
// add any added intervals back to unhandled, and restart
|
||||||
// again
|
// linearscan.
|
||||||
if (cur->weight <= minWeight) {
|
if (cur->weight <= minWeight) {
|
||||||
DEBUG(std::cerr << "\t\t\tspilling(c): " << *cur << '\n';);
|
DEBUG(std::cerr << "\t\t\tspilling(c): " << *cur << '\n';);
|
||||||
int slot = vrm_->assignVirt2StackSlot(cur->reg);
|
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
|
// merge added with unhandled
|
||||||
// back to unhandled. We need to scan since unhandled are
|
std::vector<LiveIntervals::Interval*>::iterator addedIt = added.begin();
|
||||||
// sorted on earliest start point and we may have changed our
|
std::vector<LiveIntervals::Interval*>::iterator addedItEnd = added.end();
|
||||||
// start point.
|
for (IntervalPtrs::iterator i = unhandled_.begin(), e = unhandled_.end();
|
||||||
if (!cur->empty()) {
|
i != e && addedIt != addedItEnd; ++i) {
|
||||||
IntervalPtrs::iterator it = unhandled_.begin();
|
if ((*i)->start() > (*addedIt)->start())
|
||||||
while (it != unhandled_.end() && (*it)->start() < cur->start())
|
i = unhandled_.insert(i, *(addedIt++));
|
||||||
++it;
|
|
||||||
unhandled_.insert(it, cur);
|
|
||||||
}
|
}
|
||||||
|
while (addedIt != addedItEnd)
|
||||||
|
unhandled_.push_back(*(addedIt++));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -395,6 +398,7 @@ void RA::assignRegOrStackSlotAtInterval(IntervalPtrs::value_type cur)
|
|||||||
// otherwise we spill all intervals aliasing the register with
|
// otherwise we spill all intervals aliasing the register with
|
||||||
// minimum weight, rollback to the interval with the earliest
|
// minimum weight, rollback to the interval with the earliest
|
||||||
// start point and let the linear scan algorithm run again
|
// start point and let the linear scan algorithm run again
|
||||||
|
std::vector<LiveIntervals::Interval*> added;
|
||||||
assert(MRegisterInfo::isPhysicalRegister(minReg) &&
|
assert(MRegisterInfo::isPhysicalRegister(minReg) &&
|
||||||
"did not choose a register to spill?");
|
"did not choose a register to spill?");
|
||||||
std::vector<bool> toSpill(mri_->getNumRegs(), false);
|
std::vector<bool> toSpill(mri_->getNumRegs(), false);
|
||||||
@ -403,6 +407,8 @@ void RA::assignRegOrStackSlotAtInterval(IntervalPtrs::value_type cur)
|
|||||||
toSpill[*as] = true;
|
toSpill[*as] = true;
|
||||||
unsigned earliestStart = cur->start();
|
unsigned earliestStart = cur->start();
|
||||||
|
|
||||||
|
std::set<unsigned> spilled;
|
||||||
|
|
||||||
for (IntervalPtrs::iterator i = active_.begin(); i != active_.end(); ++i) {
|
for (IntervalPtrs::iterator i = active_.begin(); i != active_.end(); ++i) {
|
||||||
unsigned reg = (*i)->reg;
|
unsigned reg = (*i)->reg;
|
||||||
if (MRegisterInfo::isVirtualRegister(reg) &&
|
if (MRegisterInfo::isVirtualRegister(reg) &&
|
||||||
@ -411,7 +417,10 @@ void RA::assignRegOrStackSlotAtInterval(IntervalPtrs::value_type cur)
|
|||||||
DEBUG(std::cerr << "\t\t\tspilling(a): " << **i << '\n');
|
DEBUG(std::cerr << "\t\t\tspilling(a): " << **i << '\n');
|
||||||
earliestStart = std::min(earliestStart, (*i)->start());
|
earliestStart = std::min(earliestStart, (*i)->start());
|
||||||
int slot = vrm_->assignVirt2StackSlot((*i)->reg);
|
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();
|
for (IntervalPtrs::iterator i = inactive_.begin();
|
||||||
@ -423,7 +432,10 @@ void RA::assignRegOrStackSlotAtInterval(IntervalPtrs::value_type cur)
|
|||||||
DEBUG(std::cerr << "\t\t\tspilling(i): " << **i << '\n');
|
DEBUG(std::cerr << "\t\t\tspilling(i): " << **i << '\n');
|
||||||
earliestStart = std::min(earliestStart, (*i)->start());
|
earliestStart = std::min(earliestStart, (*i)->start());
|
||||||
int slot = vrm_->assignVirt2StackSlot((*i)->reg);
|
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 @@ void RA::assignRegOrStackSlotAtInterval(IntervalPtrs::value_type cur)
|
|||||||
while (!handled_.empty()) {
|
while (!handled_.empty()) {
|
||||||
IntervalPtrs::value_type i = handled_.back();
|
IntervalPtrs::value_type i = handled_.back();
|
||||||
// if this interval starts before t we are done
|
// if this interval starts before t we are done
|
||||||
if (!i->empty() && i->start() < earliestStart)
|
if (i->start() < earliestStart)
|
||||||
break;
|
break;
|
||||||
DEBUG(std::cerr << "\t\t\tundo changes for: " << *i << '\n');
|
DEBUG(std::cerr << "\t\t\tundo changes for: " << *i << '\n');
|
||||||
handled_.pop_back();
|
handled_.pop_back();
|
||||||
@ -445,20 +457,10 @@ void RA::assignRegOrStackSlotAtInterval(IntervalPtrs::value_type cur)
|
|||||||
unhandled_.push_front(i);
|
unhandled_.push_front(i);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if (!spilled.count(i->reg))
|
||||||
|
unhandled_.push_front(i);
|
||||||
prt_->delRegUse(vrm_->getPhys(i->reg));
|
prt_->delRegUse(vrm_->getPhys(i->reg));
|
||||||
vrm_->clearVirt(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()) {
|
else if ((it = find(inactive_.begin(), inactive_.end(), i)) != inactive_.end()) {
|
||||||
@ -466,18 +468,9 @@ void RA::assignRegOrStackSlotAtInterval(IntervalPtrs::value_type cur)
|
|||||||
if (MRegisterInfo::isPhysicalRegister(i->reg))
|
if (MRegisterInfo::isPhysicalRegister(i->reg))
|
||||||
unhandled_.push_front(i);
|
unhandled_.push_front(i);
|
||||||
else {
|
else {
|
||||||
vrm_->clearVirt(i->reg);
|
if (!spilled.count(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);
|
unhandled_.push_front(i);
|
||||||
|
vrm_->clearVirt(i->reg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -501,6 +494,19 @@ void RA::assignRegOrStackSlotAtInterval(IntervalPtrs::value_type cur)
|
|||||||
prt_->addRegUse(vrm_->getPhys((*i)->reg));
|
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)
|
unsigned RA::getFreePhysReg(IntervalPtrs::value_type cur)
|
||||||
|
Loading…
Reference in New Issue
Block a user