Newer
Older
if (SrcSubReg)
Reg = tri_->getSubReg(Reg, SrcSubReg);
if (DstSubReg)
Reg = tri_->getMatchingSuperReg(Reg, DstSubReg, RC);
if (Reg && allocatableRegs_[Reg] && RC->contains(Reg))
cur->preference = Reg;
}
}
}
}
// 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) {
unsigned Reg = i->first->reg;
assert(TargetRegisterInfo::isVirtualRegister(Reg) &&
"Can only allocate virtual registers!");
const TargetRegisterClass *RegRC = mri_->getRegClass(Reg);
// If this is not in a related reg class to the register we're allocating,
// don't check it.
if (RelatedRegClasses.getLeaderValue(RegRC) == RCLeader &&
cur->overlapsFrom(*i->first, i->second-1)) {
Reg = vrm_->getPhys(Reg);
SpillWeightsToAdd.push_back(std::make_pair(Reg, i->first->weight));
Alkis Evlogimenos
committed
}
// Speculatively check to see if we can get a register right now. If not,
// we know we won't be able to by adding more constraints. If so, we can
// check to see if it is valid. Doing an exhaustive search of the fixed_ list
// is very bad (it contains all callee clobbered registers for any functions
// with a call), so we want to avoid doing that if possible.
unsigned physReg = getFreePhysReg(cur);
Evan Cheng
committed
unsigned BestPhysReg = physReg;
if (physReg) {
// We got a register. However, if it's in the fixed_ list, we might
Chris Lattner
committed
// conflict with it. Check to see if we conflict with it or any of its
// aliases.
SmallSet<unsigned, 8> RegAliases;
for (const unsigned *AS = tri_->getAliasSet(physReg); *AS; ++AS)
Chris Lattner
committed
RegAliases.insert(*AS);
bool ConflictsWithFixed = false;
for (unsigned i = 0, e = fixed_.size(); i != e; ++i) {
IntervalPtr &IP = fixed_[i];
if (physReg == IP.first->reg || RegAliases.count(IP.first->reg)) {
// Okay, this reg is on the fixed list. Check to see if we actually
// conflict.
LiveInterval *I = IP.first;
if (I->endNumber() > StartPosition) {
LiveInterval::iterator II = I->advanceTo(IP.second, StartPosition);
IP.second = II;
if (II != I->begin() && II->start > StartPosition)
--II;
Chris Lattner
committed
if (cur->overlapsFrom(*I, II)) {
ConflictsWithFixed = true;
Chris Lattner
committed
break;
}
}
Chris Lattner
committed
}
// Okay, the register picked by our speculative getFreePhysReg call turned
// out to be in use. Actually add all of the conflicting fixed registers to
// regUse_ so we can do an accurate query.
if (ConflictsWithFixed) {
// For every interval in fixed we overlap with, mark the register as not
// free and update spill weights.
for (unsigned i = 0, e = fixed_.size(); i != e; ++i) {
IntervalPtr &IP = fixed_[i];
LiveInterval *I = IP.first;
const TargetRegisterClass *RegRC = OneClassForEachPhysReg[I->reg];
if (RelatedRegClasses.getLeaderValue(RegRC) == RCLeader &&
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;
SpillWeightsToAdd.push_back(std::make_pair(reg, I->weight));
}
}
}
// Using the newly updated regUse_ object, which includes conflicts in the
// future, see if there are any registers available.
physReg = getFreePhysReg(cur);
}
}
// Restore the physical register tracker, removing information about the
// future.
// If we find a free register, we are done: assign this virtual to
// the free physical register and add this interval to the active
// list.
if (physReg) {
vrm_->assignVirt2Phys(cur->reg, physReg);
active_.push_back(std::make_pair(cur, cur->begin()));
// "Upgrade" the physical register since it has been allocated.
UpgradeRegister(physReg);
if (LiveInterval *NextReloadLI = hasNextReloadInterval(cur)) {
// "Downgrade" physReg to try to keep physReg from being allocated until
// the next reload from the same SS is allocated.
NextReloadLI->preference = physReg;
DowngradeRegister(cur, physReg);
}
DOUT << "no free registers\n";
// Compile the spill weights into an array that is better for scanning.
std::vector<float> SpillWeights(tri_->getNumRegs(), 0.0f);
for (std::vector<std::pair<unsigned, float> >::iterator
I = SpillWeightsToAdd.begin(), E = SpillWeightsToAdd.end(); I != E; ++I)
Evan Cheng
committed
updateSpillWeights(SpillWeights, I->first, I->second, RC);
// 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;
assert(TargetRegisterInfo::isVirtualRegister(reg) &&
"Can only allocate virtual registers!");
reg = vrm_->getPhys(reg);
Evan Cheng
committed
updateSpillWeights(SpillWeights, reg, i->first->weight, RC);
}
DOUT << "\tassigning stack slot at interval "<< *cur << ":\n";
Evan Cheng
committed
unsigned minReg = 0; /*cur->preference*/; // Try the pref register first.
bool Found = false;
std::vector<std::pair<unsigned,float> > RegsWeights;
if (!minReg || SpillWeights[minReg] == HUGE_VALF)
for (TargetRegisterClass::iterator i = RC->allocation_order_begin(*mf_),
e = RC->allocation_order_end(*mf_); i != e; ++i) {
unsigned reg = *i;
float regWeight = SpillWeights[reg];
if (minWeight > regWeight)
Found = true;
RegsWeights.push_back(std::make_pair(reg, regWeight));
Alkis Evlogimenos
committed
}
// If we didn't find a register that is spillable, try aliases?
if (!Found) {
for (TargetRegisterClass::iterator i = RC->allocation_order_begin(*mf_),
e = RC->allocation_order_end(*mf_); i != e; ++i) {
unsigned reg = *i;
// No need to worry about if the alias register size < regsize of RC.
// We are going to spill all registers that alias it anyway.
for (const unsigned* as = tri_->getAliasSet(reg); *as; ++as)
RegsWeights.push_back(std::make_pair(*as, SpillWeights[*as]));
}
}
// Sort all potential spill candidates by weight.
std::sort(RegsWeights.begin(), RegsWeights.end(), WeightCompare());
minReg = RegsWeights[0].first;
minWeight = RegsWeights[0].second;
if (minWeight == HUGE_VALF) {
// All registers must have inf weight. Just grab one!
minReg = BestPhysReg ? BestPhysReg : *RC->allocation_order_begin(*mf_);
if (cur->weight == HUGE_VALF ||
Evan Cheng
committed
li_->getApproximateInstructionCount(*cur) == 0) {
// Spill a physical register around defs and uses.
if (li_->spillPhysRegAroundRegDefsUses(*cur, minReg, *vrm_)) {
// spillPhysRegAroundRegDefsUses may have invalidated iterator stored
// in fixed_. Reset them.
for (unsigned i = 0, e = fixed_.size(); i != e; ++i) {
IntervalPtr &IP = fixed_[i];
LiveInterval *I = IP.first;
if (I->reg == minReg || tri_->isSubRegister(minReg, I->reg))
IP.second = I->advanceTo(I->begin(), StartPosition);
}
DowngradedRegs.clear();
assignRegOrStackSlotAtInterval(cur);
} else {
cerr << "Ran out of registers during register allocation!\n";
exit(1);
}
Evan Cheng
committed
return;
}
}
// Find up to 3 registers to consider as spill candidates.
unsigned LastCandidate = RegsWeights.size() >= 3 ? 3 : 1;
while (LastCandidate > 1) {
if (weightsAreClose(RegsWeights[LastCandidate-1].second, minWeight))
break;
--LastCandidate;
}
DOUT << "\t\tregister(s) with min weight(s): ";
DEBUG(for (unsigned i = 0; i != LastCandidate; ++i)
DOUT << tri_->getName(RegsWeights[i].first)
<< " (" << RegsWeights[i].second << ")\n");
// If the current has the minimum weight, we need to spill it and
// add any added intervals back to unhandled, and restart
// linearscan.
if (cur->weight != HUGE_VALF && cur->weight <= minWeight) {
DOUT << "\t\t\tspilling(c): " << *cur << '\n';
SmallVector<LiveInterval*, 8> spillIs;
std::vector<LiveInterval*> added;
if (!NewSpillFramework) {
added = li_->addIntervalsForSpills(*cur, spillIs, loopInfo, *vrm_);
Lang Hames
committed
} else {
added = spiller_->spill(cur);
}
std::sort(added.begin(), added.end(), LISorter());
Evan Cheng
committed
addStackInterval(cur, ls_, li_, mri_, *vrm_);
if (added.empty())
return; // Early exit if all spills were folded.
// Merge added with unhandled. Note that we have already sorted
// intervals returned by addIntervalsForSpills by their starting
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
// This also update the NextReloadMap. That is, it adds mapping from a
// register defined by a reload from SS to the next reload from SS in the
// same basic block.
MachineBasicBlock *LastReloadMBB = 0;
LiveInterval *LastReload = 0;
int LastReloadSS = VirtRegMap::NO_STACK_SLOT;
for (unsigned i = 0, e = added.size(); i != e; ++i) {
LiveInterval *ReloadLi = added[i];
if (ReloadLi->weight == HUGE_VALF &&
li_->getApproximateInstructionCount(*ReloadLi) == 0) {
unsigned ReloadIdx = ReloadLi->beginNumber();
MachineBasicBlock *ReloadMBB = li_->getMBBFromIndex(ReloadIdx);
int ReloadSS = vrm_->getStackSlot(ReloadLi->reg);
if (LastReloadMBB == ReloadMBB && LastReloadSS == ReloadSS) {
// Last reload of same SS is in the same MBB. We want to try to
// allocate both reloads the same register and make sure the reg
// isn't clobbered in between if at all possible.
assert(LastReload->beginNumber() < ReloadIdx);
NextReloadMap.insert(std::make_pair(LastReload->reg, ReloadLi->reg));
}
LastReloadMBB = ReloadMBB;
LastReload = ReloadLi;
LastReloadSS = ReloadSS;
}
unhandled_.push(ReloadLi);
}
++NumBacktracks;
// Push the current interval back to unhandled since we are going
// to re-run at least this iteration. Since we didn't modify it it
// should go back right in the front of the list
unhandled_.push(cur);
assert(TargetRegisterInfo::isPhysicalRegister(minReg) &&
"did not choose a register to spill?");
// We spill all intervals aliasing the register with
// minimum weight, rollback to the interval with the earliest
// start point and let the linear scan algorithm run again
SmallVector<LiveInterval*, 8> spillIs;
// Determine which intervals have to be spilled.
findIntervalsToSpill(cur, RegsWeights, LastCandidate, spillIs);
// Set of spilled vregs (used later to rollback properly)
SmallSet<unsigned, 8> spilled;
// The earliest start of a Spilled interval indicates up to where
// in handled we need to roll back
Lang Hames
committed
unsigned earliestStart = cur->beginNumber();
Lang Hames
committed
LiveInterval *earliestStartInterval = cur;
// Spill live intervals of virtual regs mapped to the physical register we
// want to clear (and its aliases). We only spill those that overlap with the
// current interval as the rest do not affect its allocation. we also keep
// track of the earliest start of all spilled live intervals since this will
// mark our rollback point.
std::vector<LiveInterval*> added;
while (!spillIs.empty()) {
Lang Hames
committed
bool epicFail = false;
LiveInterval *sli = spillIs.back();
spillIs.pop_back();
DOUT << "\t\t\tspilling(a): " << *sli << '\n';
earliestStart = std::min(earliestStart, sli->beginNumber());
Lang Hames
committed
earliestStartInterval =
(earliestStartInterval->beginNumber() < sli->beginNumber()) ?
earliestStartInterval : sli;
if (earliestStartInterval->beginNumber()!=earliestStart) {
epicFail |= true;
std::cerr << "What the 1 - "
<< "earliestStart = " << earliestStart
<< "earliestStartInterval = " << earliestStartInterval->beginNumber()
<< "\n";
}
std::vector<LiveInterval*> newIs;
if (!NewSpillFramework) {
newIs = li_->addIntervalsForSpills(*sli, spillIs, loopInfo, *vrm_);
} else {
newIs = spiller_->spill(sli);
}
Evan Cheng
committed
addStackInterval(sli, ls_, li_, mri_, *vrm_);
std::copy(newIs.begin(), newIs.end(), std::back_inserter(added));
spilled.insert(sli->reg);
Lang Hames
committed
if (earliestStartInterval->beginNumber()!=earliestStart) {
epicFail |= true;
std::cerr << "What the 2 - "
<< "earliestStart = " << earliestStart
<< "earliestStartInterval = " << earliestStartInterval->beginNumber()
<< "\n";
}
if (epicFail) {
//abort();
}
Lang Hames
committed
earliestStart = earliestStartInterval->beginNumber();
DOUT << "\t\trolling back to: " << earliestStart << '\n';
// Scan handled in reverse order up to the earliest start of a
// spilled live interval and undo each one, restoring the state of
while (!handled_.empty()) {
LiveInterval* i = handled_.back();
// If this interval starts before t we are done.
if (i->beginNumber() < earliestStart)
DOUT << "\t\t\tundo changes for: " << *i << '\n';
// When undoing a live interval allocation we must know if it is active or
// inactive to properly update regUse_ and the VirtRegMap.
if ((it = FindIntervalInVector(active_, i)) != active_.end()) {
assert(!TargetRegisterInfo::isPhysicalRegister(i->reg));
} else if ((it = FindIntervalInVector(inactive_, i)) != inactive_.end()) {
assert(!TargetRegisterInfo::isPhysicalRegister(i->reg));
assert(TargetRegisterInfo::isVirtualRegister(i->reg) &&
"Can only allocate virtual registers!");
vrm_->clearVirt(i->reg);
Evan Cheng
committed
DenseMap<unsigned, unsigned>::iterator ii = DowngradeMap.find(i->reg);
if (ii == DowngradeMap.end())
// It interval has a preference, it must be defined by a copy. Clear the
// preference now since the source interval allocation may have been
// undone as well.
i->preference = 0;
else {
UpgradeRegister(ii->second);
}
// Rewind the iterators in the active, inactive, and fixed lists back to the
// point we reverted to.
RevertVectorIteratorsTo(active_, earliestStart);
RevertVectorIteratorsTo(inactive_, earliestStart);
RevertVectorIteratorsTo(fixed_, earliestStart);
// 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 (unsigned i = 0, e = handled_.size(); i != e; ++i) {
LiveInterval *HI = handled_[i];
if (!HI->expiredAt(earliestStart) &&
HI->expiredAt(cur->beginNumber())) {
DOUT << "\t\t\tundo changes for: " << *HI << '\n';
active_.push_back(std::make_pair(HI, HI->begin()));
assert(!TargetRegisterInfo::isPhysicalRegister(HI->reg));
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
// Merge added with unhandled.
// This also update the NextReloadMap. That is, it adds mapping from a
// register defined by a reload from SS to the next reload from SS in the
// same basic block.
MachineBasicBlock *LastReloadMBB = 0;
LiveInterval *LastReload = 0;
int LastReloadSS = VirtRegMap::NO_STACK_SLOT;
std::sort(added.begin(), added.end(), LISorter());
for (unsigned i = 0, e = added.size(); i != e; ++i) {
LiveInterval *ReloadLi = added[i];
if (ReloadLi->weight == HUGE_VALF &&
li_->getApproximateInstructionCount(*ReloadLi) == 0) {
unsigned ReloadIdx = ReloadLi->beginNumber();
MachineBasicBlock *ReloadMBB = li_->getMBBFromIndex(ReloadIdx);
int ReloadSS = vrm_->getStackSlot(ReloadLi->reg);
if (LastReloadMBB == ReloadMBB && LastReloadSS == ReloadSS) {
// Last reload of same SS is in the same MBB. We want to try to
// allocate both reloads the same register and make sure the reg
// isn't clobbered in between if at all possible.
assert(LastReload->beginNumber() < ReloadIdx);
NextReloadMap.insert(std::make_pair(LastReload->reg, ReloadLi->reg));
}
LastReloadMBB = ReloadMBB;
LastReload = ReloadLi;
LastReloadSS = ReloadSS;
}
unhandled_.push(ReloadLi);
}
}
unsigned RALinScan::getFreePhysReg(const TargetRegisterClass *RC,
unsigned MaxInactiveCount,
SmallVector<unsigned, 256> &inactiveCounts,
bool SkipDGRegs) {
unsigned FreeReg = 0;
unsigned FreeRegInactiveCount = 0;
TargetRegisterClass::iterator I = RC->allocation_order_begin(*mf_);
TargetRegisterClass::iterator E = RC->allocation_order_end(*mf_);
assert(I != E && "No allocatable register in this register class!");
// Scan for the first available register.
for (; I != E; ++I) {
unsigned Reg = *I;
// Ignore "downgraded" registers.
if (SkipDGRegs && DowngradedRegs.count(Reg))
continue;
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
FreeReg = Reg;
if (FreeReg < inactiveCounts.size())
FreeRegInactiveCount = inactiveCounts[FreeReg];
else
FreeRegInactiveCount = 0;
break;
}
}
// If there are no free regs, or if this reg has the max inactive count,
// return this register.
if (FreeReg == 0 || FreeRegInactiveCount == MaxInactiveCount)
return FreeReg;
// Continue scanning the registers, looking for the one with the highest
// inactive count. Alkis found that this reduced register pressure very
// slightly on X86 (in rev 1.94 of this file), though this should probably be
// reevaluated now.
for (; I != E; ++I) {
unsigned Reg = *I;
// Ignore "downgraded" registers.
if (SkipDGRegs && DowngradedRegs.count(Reg))
continue;
if (isRegAvail(Reg) && Reg < inactiveCounts.size() &&
FreeRegInactiveCount < inactiveCounts[Reg]) {
FreeReg = Reg;
FreeRegInactiveCount = inactiveCounts[Reg];
if (FreeRegInactiveCount == MaxInactiveCount)
break; // We found the one with the max inactive count.
}
}
return FreeReg;
/// getFreePhysReg - return a free physical register for this virtual register
/// interval if we have one, otherwise return 0.
Bill Wendling
committed
unsigned RALinScan::getFreePhysReg(LiveInterval *cur) {
SmallVector<unsigned, 256> inactiveCounts;
unsigned MaxInactiveCount = 0;
const TargetRegisterClass *RC = mri_->getRegClass(cur->reg);
const TargetRegisterClass *RCLeader = RelatedRegClasses.getLeaderValue(RC);
for (IntervalPtrs::iterator i = inactive_.begin(), e = inactive_.end();
i != e; ++i) {
unsigned reg = i->first->reg;
assert(TargetRegisterInfo::isVirtualRegister(reg) &&
"Can only allocate virtual registers!");
// If this is not in a related reg class to the register we're allocating,
// don't check it.
const TargetRegisterClass *RegRC = mri_->getRegClass(reg);
if (RelatedRegClasses.getLeaderValue(RegRC) == RCLeader) {
reg = vrm_->getPhys(reg);
if (inactiveCounts.size() <= reg)
inactiveCounts.resize(reg+1);
++inactiveCounts[reg];
MaxInactiveCount = std::max(MaxInactiveCount, inactiveCounts[reg]);
}
}
// If copy coalescer has assigned a "preferred" register, check if it's
// available first.
DOUT << "(preferred: " << tri_->getName(cur->preference) << ") ";
RC->contains(cur->preference))
return cur->preference;
if (!DowngradedRegs.empty()) {
unsigned FreeReg = getFreePhysReg(RC, MaxInactiveCount, inactiveCounts,
true);
if (FreeReg)
return FreeReg;
return getFreePhysReg(RC, MaxInactiveCount, inactiveCounts, false);
Alkis Evlogimenos
committed
}
FunctionPass* llvm::createLinearScanRegisterAllocator() {
Bill Wendling
committed
return new RALinScan();