std::auto_ptr<VirtRegMap> vrm_;
std::auto_ptr<Spiller> spiller_;
- typedef std::vector<float> SpillWeights;
- SpillWeights spillWeights_;
-
public:
virtual const char* getPassName() const {
return "Linear Scan Register Allocator";
/// ones to the active list.
void processInactiveIntervals(unsigned CurPoint);
- /// updateSpillWeights - updates the spill weights of the
- /// specifed physical register and its weight.
- void updateSpillWeights(unsigned reg, SpillWeights::value_type weight);
-
/// assignRegOrStackSlotAtInterval - assign a register if one
/// is available, or spill.
void assignRegOrStackSlotAtInterval(LiveInterval* cur);
tm_ = &fn.getTarget();
mri_ = tm_->getRegisterInfo();
li_ = &getAnalysis<LiveIntervals>();
+
if (!prt_.get()) prt_.reset(new PhysRegTracker(*mri_));
vrm_.reset(new VirtRegMap(*mf_));
if (!spiller_.get()) spiller_.reset(createSpiller());
return true;
}
+/// initIntervalSets - initialize the interval sets.
+///
+void RA::initIntervalSets()
+{
+ assert(unhandled_.empty() && fixed_.empty() &&
+ active_.empty() && inactive_.empty() &&
+ "interval sets should be empty on initialization");
+
+ for (LiveIntervals::iterator i = li_->begin(), e = li_->end(); i != e; ++i) {
+ if (MRegisterInfo::isPhysicalRegister(i->second.reg))
+ fixed_.push_back(std::make_pair(&i->second, i->second.begin()));
+ else
+ unhandled_.push(&i->second);
+ }
+}
+
void RA::linearScan()
{
// linear scan algorithm
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(std::make_pair(cur, cur->begin()));
- handled_.push_back(cur);
- } else {
- // otherwise we are allocating a virtual register. try to find a free
- // physical register or spill an interval (possibly this one) in order to
- // assign it one.
- assignRegOrStackSlotAtInterval(cur);
- }
+ assert(MRegisterInfo::isVirtualRegister(cur->reg) &&
+ "Can only allocate virtual registers!");
+
+ // Allocating a virtual register. try to find a free
+ // physical register or spill an interval (possibly this one) in order to
+ // assign it one.
+ assignRegOrStackSlotAtInterval(cur);
DEBUG(printIntervals("active", active_.begin(), active_.end()));
DEBUG(printIntervals("inactive", inactive_.begin(), inactive_.end()));
i = active_.rbegin(); i != active_.rend(); ) {
unsigned reg = i->first->reg;
DEBUG(std::cerr << "\tinterval " << *i->first << " expired\n");
- if (MRegisterInfo::isVirtualRegister(reg))
- reg = vrm_->getPhys(reg);
+ assert(MRegisterInfo::isVirtualRegister(reg) &&
+ "Can only allocate virtual registers!");
+ reg = vrm_->getPhys(reg);
prt_->delRegUse(reg);
i = IntervalPtrs::reverse_iterator(active_.erase(i.base()-1));
}
DEBUG(std::cerr << *vrm_);
}
-/// initIntervalSets - initialize the interval sets.
-///
-void RA::initIntervalSets()
-{
- assert(unhandled_.empty() && fixed_.empty() &&
- active_.empty() && inactive_.empty() &&
- "interval sets should be empty on initialization");
-
- 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(std::make_pair(&i->second, i->second.begin()));
- }
-}
-
/// processActiveIntervals - expire old intervals and move non-overlapping ones
/// to the inactive list.
void RA::processActiveIntervals(unsigned CurPoint)
if (IntervalPos == Interval->end()) { // Remove expired intervals.
DEBUG(std::cerr << "\t\tinterval " << *Interval << " expired\n");
- if (MRegisterInfo::isVirtualRegister(reg))
- reg = vrm_->getPhys(reg);
+ assert(MRegisterInfo::isVirtualRegister(reg) &&
+ "Can only allocate virtual registers!");
+ reg = vrm_->getPhys(reg);
prt_->delRegUse(reg);
// Pop off the end of the list.
} 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);
+ assert(MRegisterInfo::isVirtualRegister(reg) &&
+ "Can only allocate virtual registers!");
+ reg = vrm_->getPhys(reg);
prt_->delRegUse(reg);
// add to inactive.
inactive_.push_back(std::make_pair(Interval, IntervalPos));
} 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);
+ assert(MRegisterInfo::isVirtualRegister(reg) &&
+ "Can only allocate virtual registers!");
+ reg = vrm_->getPhys(reg);
prt_->addRegUse(reg);
// add to active
active_.push_back(std::make_pair(Interval, IntervalPos));
/// 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;
- for (const unsigned* as = mri_->getAliasSet(reg); *as; ++as)
- spillWeights_[*as] += weight;
+static void updateSpillWeights(std::vector<float> &Weights,
+ unsigned reg, float weight,
+ const MRegisterInfo *MRI) {
+ Weights[reg] += weight;
+ for (const unsigned* as = MRI->getAliasSet(reg); *as; ++as)
+ Weights[*as] += weight;
}
static RA::IntervalPtrs::iterator FindIntervalInVector(RA::IntervalPtrs &IP,
PhysRegTracker backupPrt = *prt_;
- spillWeights_.assign(mri_->getNumRegs(), 0.0);
+ std::vector<float> SpillWeights;
+ SpillWeights.assign(mri_->getNumRegs(), 0.0);
unsigned StartPosition = cur->beginNumber();
- // for each interval in active update spill weights
+ // for each interval in active, update spill weights.
for (IntervalPtrs::const_iterator i = active_.begin(), e = active_.end();
i != e; ++i) {
unsigned reg = i->first->reg;
- if (MRegisterInfo::isVirtualRegister(reg))
- reg = vrm_->getPhys(reg);
- updateSpillWeights(reg, i->first->weight);
+ assert(MRegisterInfo::isVirtualRegister(reg) &&
+ "Can only allocate virtual registers!");
+ reg = vrm_->getPhys(reg);
+ updateSpillWeights(SpillWeights, reg, i->first->weight, mri_);
}
// for every interval in inactive we overlap with, mark the
e = inactive_.end(); i != e; ++i) {
if (cur->overlapsFrom(*i->first, i->second-1)) {
unsigned reg = i->first->reg;
- if (MRegisterInfo::isVirtualRegister(reg))
- reg = vrm_->getPhys(reg);
+ assert(MRegisterInfo::isVirtualRegister(reg) &&
+ "Can only allocate virtual registers!");
+ reg = vrm_->getPhys(reg);
prt_->addRegUse(reg);
- updateSpillWeights(reg, i->first->weight);
+ updateSpillWeights(SpillWeights, reg, i->first->weight, mri_);
}
}
for (unsigned i = 0, e = fixed_.size(); i != e; ++i) {
IntervalPtr &IP = fixed_[i];
LiveInterval *I = IP.first;
- LiveInterval::iterator II = I->advanceTo(IP.second, StartPosition);
- IP.second = II;
- if (cur->overlapsFrom(*I, II)) {
- unsigned reg = I->reg;
- prt_->addRegUse(reg);
- updateSpillWeights(reg, I->weight);
+ if (I->endNumber() > StartPosition) {
+ LiveInterval::iterator II = I->advanceTo(IP.second, StartPosition);
+ IP.second = II;
+ if (II != I->begin() && II->start > StartPosition)
+ --II;
+ if (cur->overlapsFrom(*I, II)) {
+ unsigned reg = I->reg;
+ prt_->addRegUse(reg);
+ updateSpillWeights(SpillWeights, reg, I->weight, mri_);
+ }
}
}
DEBUG(std::cerr << "\tassigning stack slot at interval "<< *cur << ":\n");
- float minWeight = HUGE_VAL;
+ float minWeight = float(HUGE_VAL);
unsigned minReg = 0;
const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg);
- for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_);
- i != rc->allocation_order_end(*mf_); ++i) {
+ for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_),
+ e = rc->allocation_order_end(*mf_); i != e; ++i) {
unsigned reg = *i;
- if (minWeight > spillWeights_[reg]) {
- minWeight = spillWeights_[reg];
+ if (minWeight > SpillWeights[reg]) {
+ minWeight = SpillWeights[reg];
minReg = reg;
}
}
// mark our rollback point.
for (IntervalPtrs::iterator i = active_.begin(); i != active_.end(); ++i) {
unsigned reg = i->first->reg;
- if (MRegisterInfo::isVirtualRegister(reg) &&
+ if (//MRegisterInfo::isVirtualRegister(reg) &&
toSpill[vrm_->getPhys(reg)] &&
cur->overlapsFrom(*i->first, i->second)) {
DEBUG(std::cerr << "\t\t\tspilling(a): " << *i->first << '\n');
}
for (IntervalPtrs::iterator i = inactive_.begin(); i != inactive_.end(); ++i){
unsigned reg = i->first->reg;
- if (MRegisterInfo::isVirtualRegister(reg) &&
+ if (//MRegisterInfo::isVirtualRegister(reg) &&
toSpill[vrm_->getPhys(reg)] &&
cur->overlapsFrom(*i->first, i->second-1)) {
DEBUG(std::cerr << "\t\t\tspilling(i): " << *i->first << '\n');
if ((it = FindIntervalInVector(active_, i)) != active_.end()) {
active_.erase(it);
if (MRegisterInfo::isPhysicalRegister(i->reg)) {
+ assert(0 && "daksjlfd");
prt_->delRegUse(i->reg);
unhandled_.push(i);
} else {
}
} else if ((it = FindIntervalInVector(inactive_, i)) != inactive_.end()) {
inactive_.erase(it);
- if (MRegisterInfo::isPhysicalRegister(i->reg))
+ if (MRegisterInfo::isPhysicalRegister(i->reg)) {
+ assert(0 && "daksjlfd");
unhandled_.push(i);
- else {
+ } else {
if (!spilled.count(i->reg))
unhandled_.push(i);
vrm_->clearVirt(i->reg);
}
- }
- else {
- if (MRegisterInfo::isVirtualRegister(i->reg))
- vrm_->clearVirt(i->reg);
+ } else {
+ assert(MRegisterInfo::isVirtualRegister(i->reg) &&
+ "Can only allocate virtual registers!");
+ vrm_->clearVirt(i->reg);
unhandled_.push(i);
}
}
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))
+ if (MRegisterInfo::isPhysicalRegister(HI->reg)) {
+ assert(0 &&"sdflkajsdf");
prt_->addRegUse(HI->reg);
- else
+ } else
prt_->addRegUse(vrm_->getPhys(HI->reg));
}
}
for (IntervalPtrs::iterator i = inactive_.begin(), e = inactive_.end();
i != e; ++i) {
unsigned reg = i->first->reg;
- if (MRegisterInfo::isVirtualRegister(reg))
- reg = vrm_->getPhys(reg);
+ assert(MRegisterInfo::isVirtualRegister(reg) &&
+ "Can only allocate virtual registers!");
+ reg = vrm_->getPhys(reg);
++inactiveCounts[reg];
}
const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg);
unsigned freeReg = 0;
- for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_);
- i != rc->allocation_order_end(*mf_); ++i) {
+ for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_),
+ e = rc->allocation_order_end(*mf_); i != e; ++i) {
unsigned reg = *i;
if (prt_->isRegAvail(reg) &&
(!freeReg || inactiveCounts[freeReg] < inactiveCounts[reg]))