mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-17 05:29:24 +00:00
* Improve comments/documentation substantially
* Eliminate the releaseMemory method, this is not an analysis * Change the fixed, active, and inactive lists of intervals to maintain an iterator for the current position in the interval. This allows us to do constant time increments of the iterator instead of having to do a binary search to find our liverange in our liveinterval all of the time, which substantially speeds up cases where LiveIntervals have many LiveRanges - which is very common for physical registers. On targets with many physregs, this can make a noticable difference. With a release build of LLC for PPC, this halves the time in processInactiveIntervals and processActiveIntervals, from 1.5s to .75s. This also lays the ground for more to come. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@17933 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
743ef6d70e
commit
cbb5625cec
@ -29,6 +29,7 @@
|
||||
#include <cmath>
|
||||
#include <set>
|
||||
#include <queue>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
@ -39,16 +40,33 @@ namespace {
|
||||
static unsigned numIterations = 0;
|
||||
static unsigned numIntervals = 0;
|
||||
|
||||
class RA : public MachineFunctionPass {
|
||||
struct RA : public MachineFunctionPass {
|
||||
typedef std::pair<LiveInterval*, LiveInterval::iterator> IntervalPtr;
|
||||
typedef std::vector<IntervalPtr> IntervalPtrs;
|
||||
private:
|
||||
MachineFunction* mf_;
|
||||
const TargetMachine* tm_;
|
||||
const MRegisterInfo* mri_;
|
||||
LiveIntervals* li_;
|
||||
typedef LiveInterval* IntervalPtr;
|
||||
typedef std::vector<IntervalPtr> IntervalPtrs;
|
||||
IntervalPtrs handled_, fixed_, active_, inactive_;
|
||||
|
||||
/// handled_ - Intervals are added to the handled_ set in the order of their
|
||||
/// start value. This is uses for backtracking.
|
||||
std::vector<LiveInterval*> handled_;
|
||||
|
||||
/// fixed_ - Intervals that correspond to machine registers.
|
||||
///
|
||||
IntervalPtrs fixed_;
|
||||
|
||||
/// active_ - Intervals that are currently being processed, and which have a
|
||||
/// live range active for the current point.
|
||||
IntervalPtrs active_;
|
||||
|
||||
/// inactive_ - Intervals that are currently being processed, but which have
|
||||
/// a hold at the current point.
|
||||
IntervalPtrs inactive_;
|
||||
|
||||
typedef std::priority_queue<LiveInterval*,
|
||||
IntervalPtrs,
|
||||
std::vector<LiveInterval*>,
|
||||
greater_ptr<LiveInterval> > IntervalHeap;
|
||||
IntervalHeap unhandled_;
|
||||
std::auto_ptr<PhysRegTracker> prt_;
|
||||
@ -71,26 +89,24 @@ namespace {
|
||||
/// runOnMachineFunction - register allocate the whole function
|
||||
bool runOnMachineFunction(MachineFunction&);
|
||||
|
||||
void releaseMemory();
|
||||
|
||||
private:
|
||||
/// linearScan - the linear scan algorithm
|
||||
void linearScan();
|
||||
|
||||
/// initIntervalSets - initializa the four interval sets:
|
||||
/// unhandled, fixed, active and inactive
|
||||
/// initIntervalSets - initialize the interval sets.
|
||||
///
|
||||
void initIntervalSets();
|
||||
|
||||
/// processActiveIntervals - expire old intervals and move
|
||||
/// non-overlapping ones to the incative list
|
||||
void processActiveIntervals(LiveInterval* cur);
|
||||
/// processActiveIntervals - expire old intervals and move non-overlapping
|
||||
/// ones to the inactive list.
|
||||
void processActiveIntervals(unsigned CurPoint);
|
||||
|
||||
/// processInactiveIntervals - expire old intervals and move
|
||||
/// overlapping ones to the active list
|
||||
void processInactiveIntervals(LiveInterval* cur);
|
||||
/// processInactiveIntervals - expire old intervals and move overlapping
|
||||
/// ones to the active list.
|
||||
void processInactiveIntervals(unsigned CurPoint);
|
||||
|
||||
/// updateSpillWeights - updates the spill weights of the
|
||||
/// specifed physical register and its weight
|
||||
/// specifed physical register and its weight.
|
||||
void updateSpillWeights(unsigned reg, SpillWeights::value_type weight);
|
||||
|
||||
/// assignRegOrStackSlotAtInterval - assign a register if one
|
||||
@ -101,9 +117,8 @@ namespace {
|
||||
/// register handling helpers
|
||||
///
|
||||
|
||||
/// getFreePhysReg - return a free physical register for this
|
||||
/// virtual register interval if we have one, otherwise return
|
||||
/// 0
|
||||
/// getFreePhysReg - return a free physical register for this virtual
|
||||
/// register interval if we have one, otherwise return 0.
|
||||
unsigned getFreePhysReg(LiveInterval* cur);
|
||||
|
||||
/// assignVirt2StackSlot - assigns this virtual register to a
|
||||
@ -114,8 +129,8 @@ namespace {
|
||||
void printIntervals(const char* const str, ItTy i, ItTy e) const {
|
||||
if (str) std::cerr << str << " intervals:\n";
|
||||
for (; i != e; ++i) {
|
||||
std::cerr << "\t" << **i << " -> ";
|
||||
unsigned reg = (*i)->reg;
|
||||
std::cerr << "\t" << *i->first << " -> ";
|
||||
unsigned reg = i->first->reg;
|
||||
if (MRegisterInfo::isVirtualRegister(reg)) {
|
||||
reg = vrm_->getPhys(reg);
|
||||
}
|
||||
@ -125,15 +140,6 @@ namespace {
|
||||
};
|
||||
}
|
||||
|
||||
void RA::releaseMemory()
|
||||
{
|
||||
while (!unhandled_.empty()) unhandled_.pop();
|
||||
fixed_.clear();
|
||||
active_.clear();
|
||||
inactive_.clear();
|
||||
handled_.clear();
|
||||
}
|
||||
|
||||
bool RA::runOnMachineFunction(MachineFunction &fn) {
|
||||
mf_ = &fn;
|
||||
tm_ = &fn.getTarget();
|
||||
@ -150,6 +156,14 @@ bool RA::runOnMachineFunction(MachineFunction &fn) {
|
||||
spiller_->runOnMachineFunction(*mf_, *vrm_);
|
||||
|
||||
vrm_.reset(); // Free the VirtRegMap
|
||||
|
||||
|
||||
while (!unhandled_.empty()) unhandled_.pop();
|
||||
fixed_.clear();
|
||||
active_.clear();
|
||||
inactive_.clear();
|
||||
handled_.clear();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -172,19 +186,18 @@ void RA::linearScan()
|
||||
++numIterations;
|
||||
DEBUG(std::cerr << "\n*** CURRENT ***: " << *cur << '\n');
|
||||
|
||||
processActiveIntervals(cur);
|
||||
processInactiveIntervals(cur);
|
||||
processActiveIntervals(cur->beginNumber());
|
||||
processInactiveIntervals(cur->beginNumber());
|
||||
|
||||
// if this register is fixed we are done
|
||||
if (MRegisterInfo::isPhysicalRegister(cur->reg)) {
|
||||
prt_->addRegUse(cur->reg);
|
||||
active_.push_back(cur);
|
||||
active_.push_back(std::make_pair(cur, cur->begin()));
|
||||
handled_.push_back(cur);
|
||||
}
|
||||
// otherwise we are allocating a virtual register. try to find
|
||||
// a free physical register or spill an interval in order to
|
||||
// assign it one (we could spill the current though).
|
||||
else {
|
||||
} else {
|
||||
// otherwise we are allocating a virtual register. try to find a free
|
||||
// physical register or spill an interval in order to assign it one (we
|
||||
// could spill the current though).
|
||||
assignRegOrStackSlotAtInterval(cur);
|
||||
}
|
||||
|
||||
@ -197,8 +210,8 @@ void RA::linearScan()
|
||||
// expire any remaining active intervals
|
||||
for (IntervalPtrs::reverse_iterator
|
||||
i = active_.rbegin(); i != active_.rend(); ) {
|
||||
unsigned reg = (*i)->reg;
|
||||
DEBUG(std::cerr << "\tinterval " << **i << " expired\n");
|
||||
unsigned reg = i->first->reg;
|
||||
DEBUG(std::cerr << "\tinterval " << *i->first << " expired\n");
|
||||
if (MRegisterInfo::isVirtualRegister(reg))
|
||||
reg = vrm_->getPhys(reg);
|
||||
prt_->delRegUse(reg);
|
||||
@ -208,13 +221,15 @@ void RA::linearScan()
|
||||
// expire any remaining inactive intervals
|
||||
for (IntervalPtrs::reverse_iterator
|
||||
i = inactive_.rbegin(); i != inactive_.rend(); ) {
|
||||
DEBUG(std::cerr << "\tinterval " << **i << " expired\n");
|
||||
DEBUG(std::cerr << "\tinterval " << *i->first << " expired\n");
|
||||
i = IntervalPtrs::reverse_iterator(inactive_.erase(i.base()-1));
|
||||
}
|
||||
|
||||
DEBUG(std::cerr << *vrm_);
|
||||
}
|
||||
|
||||
/// initIntervalSets - initialize the interval sets.
|
||||
///
|
||||
void RA::initIntervalSets()
|
||||
{
|
||||
assert(unhandled_.empty() && fixed_.empty() &&
|
||||
@ -224,79 +239,95 @@ void RA::initIntervalSets()
|
||||
for (LiveIntervals::iterator i = li_->begin(), e = li_->end(); i != e; ++i){
|
||||
unhandled_.push(&i->second);
|
||||
if (MRegisterInfo::isPhysicalRegister(i->second.reg))
|
||||
fixed_.push_back(&i->second);
|
||||
fixed_.push_back(std::make_pair(&i->second, i->second.begin()));
|
||||
}
|
||||
}
|
||||
|
||||
void RA::processActiveIntervals(IntervalPtrs::value_type cur)
|
||||
/// processActiveIntervals - expire old intervals and move non-overlapping ones
|
||||
/// to the inactive list.
|
||||
void RA::processActiveIntervals(unsigned CurPoint)
|
||||
{
|
||||
DEBUG(std::cerr << "\tprocessing active intervals:\n");
|
||||
|
||||
IntervalPtrs::iterator ii = active_.begin(), ie = active_.end();
|
||||
while (ii != ie) {
|
||||
LiveInterval* i = *ii;
|
||||
unsigned reg = i->reg;
|
||||
for (unsigned i = 0, e = active_.size(); i != e; ++i) {
|
||||
LiveInterval *Interval = active_[i].first;
|
||||
LiveInterval::iterator IntervalPos = active_[i].second;
|
||||
unsigned reg = Interval->reg;
|
||||
|
||||
// remove expired intervals
|
||||
if (i->expiredAt(cur->beginNumber())) {
|
||||
DEBUG(std::cerr << "\t\tinterval " << *i << " expired\n");
|
||||
IntervalPos = Interval->advanceTo(IntervalPos, CurPoint);
|
||||
|
||||
if (IntervalPos == Interval->end()) { // Remove expired intervals.
|
||||
DEBUG(std::cerr << "\t\tinterval " << *Interval << " expired\n");
|
||||
if (MRegisterInfo::isVirtualRegister(reg))
|
||||
reg = vrm_->getPhys(reg);
|
||||
prt_->delRegUse(reg);
|
||||
// swap with last element and move end iterator back one position
|
||||
std::iter_swap(ii, --ie);
|
||||
}
|
||||
// move inactive intervals to inactive list
|
||||
else if (!i->liveAt(cur->beginNumber())) {
|
||||
DEBUG(std::cerr << "\t\tinterval " << *i << " inactive\n");
|
||||
|
||||
// Pop off the end of the list.
|
||||
active_[i] = active_.back();
|
||||
active_.pop_back();
|
||||
--i; --e;
|
||||
|
||||
} else if (IntervalPos->start > CurPoint) {
|
||||
// Move inactive intervals to inactive list.
|
||||
DEBUG(std::cerr << "\t\tinterval " << *Interval << " inactive\n");
|
||||
if (MRegisterInfo::isVirtualRegister(reg))
|
||||
reg = vrm_->getPhys(reg);
|
||||
prt_->delRegUse(reg);
|
||||
// add to inactive
|
||||
inactive_.push_back(i);
|
||||
// swap with last element and move end iterator back one postion
|
||||
std::iter_swap(ii, --ie);
|
||||
}
|
||||
else {
|
||||
++ii;
|
||||
// add to inactive.
|
||||
inactive_.push_back(std::make_pair(Interval, IntervalPos));
|
||||
|
||||
// Pop off the end of the list.
|
||||
active_[i] = active_.back();
|
||||
active_.pop_back();
|
||||
--i; --e;
|
||||
} else {
|
||||
// Otherwise, just update the iterator position.
|
||||
active_[i].second = IntervalPos;
|
||||
}
|
||||
}
|
||||
active_.erase(ie, active_.end());
|
||||
}
|
||||
|
||||
void RA::processInactiveIntervals(IntervalPtrs::value_type cur)
|
||||
/// processInactiveIntervals - expire old intervals and move overlapping
|
||||
/// ones to the active list.
|
||||
void RA::processInactiveIntervals(unsigned CurPoint)
|
||||
{
|
||||
DEBUG(std::cerr << "\tprocessing inactive intervals:\n");
|
||||
IntervalPtrs::iterator ii = inactive_.begin(), ie = inactive_.end();
|
||||
for (unsigned i = 0, e = inactive_.size(); i != e; ++i) {
|
||||
LiveInterval *Interval = inactive_[i].first;
|
||||
LiveInterval::iterator IntervalPos = inactive_[i].second;
|
||||
unsigned reg = Interval->reg;
|
||||
|
||||
while (ii != ie) {
|
||||
LiveInterval* i = *ii;
|
||||
unsigned reg = i->reg;
|
||||
IntervalPos = Interval->advanceTo(IntervalPos, CurPoint);
|
||||
|
||||
if (IntervalPos == Interval->end()) { // remove expired intervals.
|
||||
DEBUG(std::cerr << "\t\tinterval " << *Interval << " expired\n");
|
||||
|
||||
// remove expired intervals
|
||||
if (i->expiredAt(cur->beginNumber())) {
|
||||
DEBUG(std::cerr << "\t\tinterval " << *i << " expired\n");
|
||||
// swap with last element and move end iterator back one position
|
||||
std::iter_swap(ii, --ie);
|
||||
}
|
||||
// move re-activated intervals in active list
|
||||
else if (i->liveAt(cur->beginNumber())) {
|
||||
DEBUG(std::cerr << "\t\tinterval " << *i << " active\n");
|
||||
// Pop off the end of the list.
|
||||
inactive_[i] = inactive_.back();
|
||||
inactive_.pop_back();
|
||||
--i; --e;
|
||||
} else if (IntervalPos->start <= CurPoint) {
|
||||
// move re-activated intervals in active list
|
||||
DEBUG(std::cerr << "\t\tinterval " << *Interval << " active\n");
|
||||
if (MRegisterInfo::isVirtualRegister(reg))
|
||||
reg = vrm_->getPhys(reg);
|
||||
prt_->addRegUse(reg);
|
||||
// add to active
|
||||
active_.push_back(i);
|
||||
// swap with last element and move end iterator back one position
|
||||
std::iter_swap(ii, --ie);
|
||||
}
|
||||
else {
|
||||
++ii;
|
||||
active_.push_back(std::make_pair(Interval, IntervalPos));
|
||||
|
||||
// Pop off the end of the list.
|
||||
inactive_[i] = inactive_.back();
|
||||
inactive_.pop_back();
|
||||
--i; --e;
|
||||
} else {
|
||||
// Otherwise, just update the iterator position.
|
||||
inactive_[i].second = IntervalPos;
|
||||
}
|
||||
}
|
||||
inactive_.erase(ie, inactive_.end());
|
||||
}
|
||||
|
||||
/// updateSpillWeights - updates the spill weights of the specifed physical
|
||||
/// register and its weight.
|
||||
void RA::updateSpillWeights(unsigned reg, SpillWeights::value_type weight)
|
||||
{
|
||||
spillWeights_[reg] += weight;
|
||||
@ -304,6 +335,17 @@ void RA::updateSpillWeights(unsigned reg, SpillWeights::value_type weight)
|
||||
spillWeights_[*as] += weight;
|
||||
}
|
||||
|
||||
static RA::IntervalPtrs::iterator FindIntervalInVector(RA::IntervalPtrs &IP,
|
||||
LiveInterval *LI) {
|
||||
for (RA::IntervalPtrs::iterator I = IP.begin(), E = IP.end(); I != E; ++I)
|
||||
if (I->first == LI) return I;
|
||||
return IP.end();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// assignRegOrStackSlotAtInterval - assign a register if one is available, or
|
||||
/// spill.
|
||||
void RA::assignRegOrStackSlotAtInterval(LiveInterval* cur)
|
||||
{
|
||||
DEBUG(std::cerr << "\tallocating current interval: ");
|
||||
@ -315,22 +357,22 @@ void RA::assignRegOrStackSlotAtInterval(LiveInterval* cur)
|
||||
// for each interval in active update spill weights
|
||||
for (IntervalPtrs::const_iterator i = active_.begin(), e = active_.end();
|
||||
i != e; ++i) {
|
||||
unsigned reg = (*i)->reg;
|
||||
unsigned reg = i->first->reg;
|
||||
if (MRegisterInfo::isVirtualRegister(reg))
|
||||
reg = vrm_->getPhys(reg);
|
||||
updateSpillWeights(reg, (*i)->weight);
|
||||
updateSpillWeights(reg, i->first->weight);
|
||||
}
|
||||
|
||||
// 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(),
|
||||
e = inactive_.end(); i != e; ++i) {
|
||||
if (cur->overlaps(**i)) {
|
||||
unsigned reg = (*i)->reg;
|
||||
if (cur->overlaps(*i->first)) {
|
||||
unsigned reg = i->first->reg;
|
||||
if (MRegisterInfo::isVirtualRegister(reg))
|
||||
reg = vrm_->getPhys(reg);
|
||||
prt_->addRegUse(reg);
|
||||
updateSpillWeights(reg, (*i)->weight);
|
||||
updateSpillWeights(reg, i->first->weight);
|
||||
}
|
||||
}
|
||||
|
||||
@ -338,10 +380,10 @@ void RA::assignRegOrStackSlotAtInterval(LiveInterval* cur)
|
||||
// mark the register as not free and update spill weights
|
||||
for (IntervalPtrs::const_iterator i = fixed_.begin(),
|
||||
e = fixed_.end(); i != e; ++i) {
|
||||
if (cur->overlaps(**i)) {
|
||||
unsigned reg = (*i)->reg;
|
||||
if (cur->overlaps(*i->first)) {
|
||||
unsigned reg = i->first->reg;
|
||||
prt_->addRegUse(reg);
|
||||
updateSpillWeights(reg, (*i)->weight);
|
||||
updateSpillWeights(reg, i->first->weight);
|
||||
}
|
||||
}
|
||||
|
||||
@ -355,7 +397,7 @@ void RA::assignRegOrStackSlotAtInterval(LiveInterval* cur)
|
||||
DEBUG(std::cerr << mri_->getName(physReg) << '\n');
|
||||
vrm_->assignVirt2Phys(cur->reg, physReg);
|
||||
prt_->addRegUse(physReg);
|
||||
active_.push_back(cur);
|
||||
active_.push_back(std::make_pair(cur, cur->begin()));
|
||||
handled_.push_back(cur);
|
||||
return;
|
||||
}
|
||||
@ -428,64 +470,63 @@ void RA::assignRegOrStackSlotAtInterval(LiveInterval* cur)
|
||||
// point
|
||||
for (IntervalPtrs::iterator
|
||||
i = active_.begin(); i != active_.end(); ++i) {
|
||||
unsigned reg = (*i)->reg;
|
||||
unsigned reg = i->first->reg;
|
||||
if (MRegisterInfo::isVirtualRegister(reg) &&
|
||||
toSpill[vrm_->getPhys(reg)] &&
|
||||
cur->overlaps(**i)) {
|
||||
DEBUG(std::cerr << "\t\t\tspilling(a): " << **i << '\n');
|
||||
earliestStart = std::min(earliestStart, (*i)->beginNumber());
|
||||
int slot = vrm_->assignVirt2StackSlot((*i)->reg);
|
||||
cur->overlaps(*i->first)) {
|
||||
DEBUG(std::cerr << "\t\t\tspilling(a): " << *i->first << '\n');
|
||||
earliestStart = std::min(earliestStart, i->first->beginNumber());
|
||||
int slot = vrm_->assignVirt2StackSlot(i->first->reg);
|
||||
std::vector<LiveInterval*> newIs =
|
||||
li_->addIntervalsForSpills(**i, *vrm_, slot);
|
||||
li_->addIntervalsForSpills(*i->first, *vrm_, slot);
|
||||
std::copy(newIs.begin(), newIs.end(), std::back_inserter(added));
|
||||
spilled.insert(reg);
|
||||
}
|
||||
}
|
||||
for (IntervalPtrs::iterator
|
||||
i = inactive_.begin(); i != inactive_.end(); ++i) {
|
||||
unsigned reg = (*i)->reg;
|
||||
unsigned reg = i->first->reg;
|
||||
if (MRegisterInfo::isVirtualRegister(reg) &&
|
||||
toSpill[vrm_->getPhys(reg)] &&
|
||||
cur->overlaps(**i)) {
|
||||
DEBUG(std::cerr << "\t\t\tspilling(i): " << **i << '\n');
|
||||
earliestStart = std::min(earliestStart, (*i)->beginNumber());
|
||||
int slot = vrm_->assignVirt2StackSlot((*i)->reg);
|
||||
cur->overlaps(*i->first)) {
|
||||
DEBUG(std::cerr << "\t\t\tspilling(i): " << *i->first << '\n');
|
||||
earliestStart = std::min(earliestStart, i->first->beginNumber());
|
||||
int slot = vrm_->assignVirt2StackSlot(reg);
|
||||
std::vector<LiveInterval*> newIs =
|
||||
li_->addIntervalsForSpills(**i, *vrm_, slot);
|
||||
li_->addIntervalsForSpills(*i->first, *vrm_, slot);
|
||||
std::copy(newIs.begin(), newIs.end(), std::back_inserter(added));
|
||||
spilled.insert(reg);
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG(std::cerr << "\t\trolling back to: " << earliestStart << '\n');
|
||||
// scan handled in reverse order up to the earliaset start of a
|
||||
|
||||
// Scan handled in reverse order up to the earliest start of a
|
||||
// spilled live interval and undo each one, restoring the state of
|
||||
// unhandled
|
||||
// unhandled.
|
||||
while (!handled_.empty()) {
|
||||
LiveInterval* i = handled_.back();
|
||||
// if this interval starts before t we are done
|
||||
// If this interval starts before t we are done.
|
||||
if (i->beginNumber() < earliestStart)
|
||||
break;
|
||||
DEBUG(std::cerr << "\t\t\tundo changes for: " << *i << '\n');
|
||||
handled_.pop_back();
|
||||
// when undoing a live interval allocation we must know if it
|
||||
// is active or inactive to properly update the PhysRegTracker
|
||||
// and the VirtRegMap
|
||||
|
||||
// When undoing a live interval allocation we must know if it is active or
|
||||
// inactive to properly update the PhysRegTracker and the VirtRegMap.
|
||||
IntervalPtrs::iterator it;
|
||||
if ((it = std::find(active_.begin(), active_.end(), i)) != active_.end()) {
|
||||
if ((it = FindIntervalInVector(active_, i)) != active_.end()) {
|
||||
active_.erase(it);
|
||||
if (MRegisterInfo::isPhysicalRegister(i->reg)) {
|
||||
prt_->delRegUse(i->reg);
|
||||
unhandled_.push(i);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (!spilled.count(i->reg))
|
||||
unhandled_.push(i);
|
||||
prt_->delRegUse(vrm_->getPhys(i->reg));
|
||||
vrm_->clearVirt(i->reg);
|
||||
}
|
||||
}
|
||||
else if ((it = std::find(inactive_.begin(), inactive_.end(), i)) != inactive_.end()) {
|
||||
} else if ((it = FindIntervalInVector(inactive_, i)) != inactive_.end()) {
|
||||
inactive_.erase(it);
|
||||
if (MRegisterInfo::isPhysicalRegister(i->reg))
|
||||
unhandled_.push(i);
|
||||
@ -505,15 +546,16 @@ void RA::assignRegOrStackSlotAtInterval(LiveInterval* cur)
|
||||
// scan the rest and undo each interval that expired after t and
|
||||
// insert it in active (the next iteration of the algorithm will
|
||||
// put it in inactive if required)
|
||||
for (IntervalPtrs::iterator i = handled_.begin(), e = handled_.end();
|
||||
i != e; ++i) {
|
||||
if (!(*i)->expiredAt(earliestStart) && (*i)->expiredAt(cur->beginNumber())){
|
||||
DEBUG(std::cerr << "\t\t\tundo changes for: " << **i << '\n');
|
||||
active_.push_back(*i);
|
||||
if (MRegisterInfo::isPhysicalRegister((*i)->reg))
|
||||
prt_->addRegUse((*i)->reg);
|
||||
for (unsigned i = 0, e = handled_.size(); i != e; ++i) {
|
||||
LiveInterval *HI = handled_[i];
|
||||
if (!HI->expiredAt(earliestStart) &&
|
||||
HI->expiredAt(cur->beginNumber())) {
|
||||
DEBUG(std::cerr << "\t\t\tundo changes for: " << *HI << '\n');
|
||||
active_.push_back(std::make_pair(HI, HI->begin()));
|
||||
if (MRegisterInfo::isPhysicalRegister(HI->reg))
|
||||
prt_->addRegUse(HI->reg);
|
||||
else
|
||||
prt_->addRegUse(vrm_->getPhys((*i)->reg));
|
||||
prt_->addRegUse(vrm_->getPhys(HI->reg));
|
||||
}
|
||||
}
|
||||
|
||||
@ -522,12 +564,14 @@ void RA::assignRegOrStackSlotAtInterval(LiveInterval* cur)
|
||||
unhandled_.push(added[i]);
|
||||
}
|
||||
|
||||
/// getFreePhysReg - return a free physical register for this virtual register
|
||||
/// interval if we have one, otherwise return 0.
|
||||
unsigned RA::getFreePhysReg(LiveInterval* cur)
|
||||
{
|
||||
std::vector<unsigned> inactiveCounts(mri_->getNumRegs(), 0);
|
||||
for (IntervalPtrs::iterator i = inactive_.begin(), e = inactive_.end();
|
||||
i != e; ++i) {
|
||||
unsigned reg = (*i)->reg;
|
||||
unsigned reg = i->first->reg;
|
||||
if (MRegisterInfo::isVirtualRegister(reg))
|
||||
reg = vrm_->getPhys(reg);
|
||||
++inactiveCounts[reg];
|
||||
|
Loading…
Reference in New Issue
Block a user