<< " multiblock=" << Var->isMultiblockLife() << " "
<< " weight=" << Var->getWeight() << " ";
Var->dump(this);
+ if (Variable *Pref = Var->getPreferredRegister()) {
+ Str << " pref=";
+ Pref->dump(this);
+ if (Var->getRegisterOverlap())
+ Str << ",overlap";
+ Str << " ";
+ }
Str << " LIVE=" << Var->getLiveRange() << "\n";
}
}
// 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;
}
}
for (SizeT i = 0; i < RegMask.size(); ++i) {
if (RegMask[i]) {
Str << Func->getTarget()->getRegName(i, IceType_i32)
- << "(U=" << RegUses[i] << ",F=" << Free[i] << ") ";
+ << "(U=" << RegUses[i] << ",F=" << Free[i]
+ << ",P=" << PrecoloredUnhandled[i] << ") ";
}
}
Str << "\n";
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);
}
if (Variable *Var = llvm::dyn_cast<Variable>(From)) {
// We need a new physical register for the operand if:
- // Mem is not allowed and Var->getRegNum() is unknown, or
+ // Mem is not allowed and Var isn't guaranteed a physical
+ // register, or
// RegNum is required and Var->getRegNum() doesn't match.
- if ((!(Allowed & Legal_Mem) && !Var->hasReg()) ||
+ bool WillHaveRegister =
+ (Var->hasReg() || Var->getWeight() == RegWeight::Inf);
+ if ((!(Allowed & Legal_Mem) && !WillHaveRegister) ||
(RegNum != Variable::NoRegister && RegNum != Var->getRegNum())) {
Variable *Reg = copyToReg(From, RegNum);
if (RegNum == Variable::NoRegister) {