aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/RegAllocLinearScan.cpp
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2010-09-01 21:04:27 +0000
committerJim Grosbach <grosbach@apple.com>2010-09-01 21:04:27 +0000
commit067a648599a99dc5a499e0241a85436fe6037c5a (patch)
tree8de118c42ff95679fa93cedf1453740c70ae6912 /lib/CodeGen/RegAllocLinearScan.cpp
parent6a94cbb72eaecb311b974f97d0b887f0acc77c58 (diff)
The register allocator shouldn't consider allocating reserved registers.
r112728 did this for fast regalloc. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@112741 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/RegAllocLinearScan.cpp')
-rw-r--r--lib/CodeGen/RegAllocLinearScan.cpp35
1 files changed, 30 insertions, 5 deletions
diff --git a/lib/CodeGen/RegAllocLinearScan.cpp b/lib/CodeGen/RegAllocLinearScan.cpp
index 6a303f6124..a667f97a4e 100644
--- a/lib/CodeGen/RegAllocLinearScan.cpp
+++ b/lib/CodeGen/RegAllocLinearScan.cpp
@@ -125,6 +125,7 @@ namespace {
const TargetRegisterInfo* tri_;
const TargetInstrInfo* tii_;
BitVector allocatableRegs_;
+ BitVector reservedRegs_;
LiveIntervals* li_;
LiveStacks* ls_;
MachineLoopInfo *loopInfo;
@@ -464,6 +465,7 @@ bool RALinScan::runOnMachineFunction(MachineFunction &fn) {
tri_ = tm_->getRegisterInfo();
tii_ = tm_->getInstrInfo();
allocatableRegs_ = tri_->getAllocatableSet(fn);
+ reservedRegs_ = tri_->getReservedRegs(fn);
li_ = &getAnalysis<LiveIntervals>();
ls_ = &getAnalysis<LiveStacks>();
loopInfo = &getAnalysis<MachineLoopInfo>();
@@ -949,8 +951,14 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur) {
const TargetRegisterClass *RC = mri_->getRegClass(cur->reg);
if (cur->empty()) {
unsigned physReg = vrm_->getRegAllocPref(cur->reg);
- if (!physReg)
- physReg = *RC->allocation_order_begin(*mf_);
+ if (!physReg) {
+ TargetRegisterClass::iterator aoe = RC->allocation_order_end(*mf_);
+ TargetRegisterClass::iterator i = RC->allocation_order_begin(*mf_);
+ while (reservedRegs_.test(*i) && i != aoe)
+ ++i;
+ assert(i != aoe && "All registers reserved?!");
+ physReg = *i;
+ }
DEBUG(dbgs() << tri_->getName(physReg) << '\n');
// Note the register is not really in use.
vrm_->assignVirt2Phys(cur->reg, physReg);
@@ -1133,8 +1141,9 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur) {
e = RC->allocation_order_end(*mf_); i != e; ++i) {
unsigned reg = *i;
float regWeight = SpillWeights[reg];
- // Skip recently allocated registers.
- if (minWeight > regWeight && !isRecentlyUsed(reg))
+ // Skip recently allocated registers and reserved registers.
+ if (minWeight > regWeight && !isRecentlyUsed(reg) &&
+ !reservedRegs_.test(reg))
Found = true;
RegsWeights.push_back(std::make_pair(reg, regWeight));
}
@@ -1144,6 +1153,8 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur) {
for (TargetRegisterClass::iterator i = RC->allocation_order_begin(*mf_),
e = RC->allocation_order_end(*mf_); i != e; ++i) {
unsigned reg = *i;
+ if (reservedRegs_.test(reg))
+ continue;
// 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)
@@ -1157,7 +1168,15 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur) {
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 (BestPhysReg == 0) {
+ TargetRegisterClass::iterator aoe = RC->allocation_order_end(*mf_);
+ TargetRegisterClass::iterator i = RC->allocation_order_begin(*mf_);
+ while (reservedRegs_.test(*i) && i != aoe)
+ ++i;
+ assert(i != aoe && "All registers reserved?!");
+ minReg = *i;
+ } else
+ minReg = BestPhysReg;
if (cur->weight == HUGE_VALF ||
li_->getApproximateInstructionCount(*cur) == 0) {
// Spill a physical register around defs and uses.
@@ -1414,6 +1433,9 @@ unsigned RALinScan::getFreePhysReg(LiveInterval* cur,
// Ignore "downgraded" registers.
if (SkipDGRegs && DowngradedRegs.count(Reg))
continue;
+ // Skip reserved registers.
+ if (reservedRegs_.test(Reg))
+ continue;
// Skip recently allocated registers.
if (isRegAvail(Reg) && !isRecentlyUsed(Reg)) {
FreeReg = Reg;
@@ -1442,6 +1464,9 @@ unsigned RALinScan::getFreePhysReg(LiveInterval* cur,
// Ignore "downgraded" registers.
if (SkipDGRegs && DowngradedRegs.count(Reg))
continue;
+ // Skip reserved registers.
+ if (reservedRegs_.test(Reg))
+ continue;
if (isRegAvail(Reg) && Reg < inactiveCounts.size() &&
FreeRegInactiveCount < inactiveCounts[Reg] && !isRecentlyUsed(Reg)) {
FreeReg = Reg;