Index: src/IceRegAlloc.cpp |
diff --git a/src/IceRegAlloc.cpp b/src/IceRegAlloc.cpp |
index 3a4c178311747a5eda63ba2ed0aefb3b77f45b65..69353a1df9bb20ff8dd3ee86cd8ed9b6f5ccc1db 100644 |
--- a/src/IceRegAlloc.cpp |
+++ b/src/IceRegAlloc.cpp |
@@ -68,6 +68,7 @@ void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull) { |
TimerMarker T(IDscan, Func->getContext()); |
assert(RegMaskFull.any()); // Sanity check |
Unhandled.clear(); |
+ UnhandledPrecolored.clear(); |
Handled.clear(); |
Inactive.clear(); |
Active.clear(); |
@@ -97,10 +98,12 @@ void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull) { |
// it was never referenced. |
if (Var->getLiveRange().isEmpty()) |
continue; |
- Unhandled.insert(LiveRangeWrapper(Var)); |
+ LiveRangeWrapper R(Var); |
+ Unhandled.insert(R); |
if (Var->hasReg()) { |
Var->setRegNumTmp(Var->getRegNum()); |
Var->setLiveRangeInfiniteWeight(); |
+ UnhandledPrecolored.insert(R); |
} |
} |
} |
@@ -145,6 +148,9 @@ void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull) { |
Active.push_back(Cur); |
assert(RegUses[RegNum] >= 0); |
++RegUses[RegNum]; |
+ assert(!UnhandledPrecolored.empty()); |
+ assert(UnhandledPrecolored.begin()->Var == Cur.Var); |
+ UnhandledPrecolored.erase(UnhandledPrecolored.begin()); |
continue; |
} |
@@ -306,19 +312,25 @@ void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull) { |
} |
} |
- // Remove registers from the Free[] list where an Unhandled range |
- // overlaps with the current range and is precolored. |
- // Cur.endsBefore(Item) is an early exit check that turns a |
- // guaranteed O(N^2) algorithm into expected linear complexity. |
- llvm::SmallBitVector PrecoloredUnhandled(RegMask.size()); |
- // Note: PrecoloredUnhandled is only used for dumping. |
- for (const LiveRangeWrapper &Item : Unhandled) { |
+ std::vector<RegWeight> Weights(RegMask.size()); |
+ |
+ // Remove registers from the Free[] list where an Unhandled |
+ // precolored range overlaps with the current range, and set those |
+ // registers to infinite weight so that they aren't candidates for |
+ // eviction. Cur.endsBefore(Item) is an early exit check that |
+ // turns a guaranteed O(N^2) algorithm into expected linear |
+ // complexity. |
+ llvm::SmallBitVector PrecoloredUnhandledMask(RegMask.size()); |
+ // Note: PrecoloredUnhandledMask is only used for dumping. |
+ for (const LiveRangeWrapper &Item : UnhandledPrecolored) { |
+ assert(Item.Var->hasReg()); |
if (Cur.endsBefore(Item)) |
break; |
- if (Item.Var->hasReg() && Item.overlaps(Cur)) { |
+ if (Item.overlaps(Cur)) { |
int32_t ItemReg = Item.Var->getRegNum(); // Note: not getRegNumTmp() |
+ Weights[ItemReg].setWeight(RegWeight::Inf); |
Free[ItemReg] = false; |
- PrecoloredUnhandled[ItemReg] = true; |
+ PrecoloredUnhandledMask[ItemReg] = true; |
// Disable AllowOverlap if the preferred register is one of |
// these precolored unhandled overlapping ranges. |
if (AllowOverlap && ItemReg == PreferReg) { |
@@ -334,7 +346,7 @@ void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull) { |
if (RegMask[i]) { |
Str << Func->getTarget()->getRegName(i, IceType_i32) |
<< "(U=" << RegUses[i] << ",F=" << Free[i] |
- << ",P=" << PrecoloredUnhandled[i] << ") "; |
+ << ",P=" << PrecoloredUnhandledMask[i] << ") "; |
} |
} |
Str << "\n"; |
@@ -369,7 +381,6 @@ void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull) { |
} else { |
// Fallback: there are no free registers, so we look for the |
// lowest-weight register and see if Cur has higher weight. |
- std::vector<RegWeight> Weights(RegMask.size()); |
// Check Active ranges. |
for (const LiveRangeWrapper &Item : Active) { |
assert(Item.overlaps(Cur)); |
@@ -384,18 +395,6 @@ void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull) { |
if (Item.overlaps(Cur)) |
Weights[RegNum].addWeight(Item.range().getWeight()); |
} |
- // Check Unhandled ranges that overlap Cur and are precolored. |
- // Cur.endsBefore(*I) is an early exit check that turns a |
- // guaranteed O(N^2) algorithm into expected linear complexity. |
- for (const LiveRangeWrapper &Item : Unhandled) { |
- if (Cur.endsBefore(Item)) |
- break; |
- int32_t RegNum = Item.Var->getRegNumTmp(); |
- if (RegNum < 0) |
- continue; |
- if (Item.overlaps(Cur)) |
- Weights[RegNum].setWeight(RegWeight::Inf); |
- } |
// All the weights are now calculated. Find the register with |
// smallest weight. |