Index: src/IceRegAlloc.cpp |
diff --git a/src/IceRegAlloc.cpp b/src/IceRegAlloc.cpp |
index f610d9668b6dc8711c642aaad2737c730207e880..099f3fd84963b21949630a329c16024e6d5fbbab 100644 |
--- a/src/IceRegAlloc.cpp |
+++ b/src/IceRegAlloc.cpp |
@@ -205,12 +205,14 @@ void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull) { |
// overlaps with the current range and is precolored. |
// Cur.endsBefore(*I) is an early exit check that turns a |
// guaranteed O(N^2) algorithm into expected linear complexity. |
+ llvm::SmallBitVector PrecoloredUnhandled(RegMask.size()); |
for (OrderedRanges::const_iterator I = Unhandled.begin(), |
E = Unhandled.end(); |
I != E && !Cur.endsBefore(*I); ++I) { |
LiveRangeWrapper Item = *I; |
if (Item.Var->hasReg() && Item.overlaps(Cur)) { |
Free[Item.Var->getRegNum()] = false; // Note: getRegNum not getRegNumTmp |
+ PrecoloredUnhandled[Item.Var->getRegNum()] = true; |
} |
} |
@@ -228,8 +230,11 @@ void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull) { |
Variable *Prefer = Cur.Var->getPreferredRegister(); |
int32_t PreferReg = Prefer && Prefer->hasRegTmp() ? Prefer->getRegNumTmp() |
: Variable::NoRegister; |
+ bool AllowedToOverlap = Cur.Var->getRegisterOverlap() && |
+ PreferReg != Variable::NoRegister && |
+ !PrecoloredUnhandled[PreferReg]; |
if (PreferReg != Variable::NoRegister && |
- (Cur.Var->getRegisterOverlap() || Free[PreferReg])) { |
+ (AllowedToOverlap || Free[PreferReg])) { |
// First choice: a preferred register that is either free or is |
// allowed to overlap with its linked variable. |
Cur.Var->setRegNumTmp(PreferReg); |