mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-17 21:29:20 +00:00
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:
parent
a6859b4715
commit
f5eaf16b94
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user