Bug 1112164 part 6 - RegisterSets: takeAny should take one register and all aliases of it. r=mjrosenb

This commit is contained in:
Nicolas B. Pierron 2015-02-26 12:18:23 +01:00
parent a95d35da9b
commit 9e2d6162c1
4 changed files with 35 additions and 14 deletions

View File

@ -8181,12 +8181,14 @@ StackDecrementForCall(MacroAssembler &masm, uint32_t alignment, const VectorT &a
}
#if defined(JS_CODEGEN_ARM)
// The ARM system ABI also includes d15 in the non volatile float registers.
// The ARM system ABI also includes d15 & s31 in the non volatile float registers.
// Also exclude lr (a.k.a. r14) as we preserve it manually)
static const RegisterSet NonVolatileRegs =
RegisterSet(GeneralRegisterSet(Registers::NonVolatileMask &
~(uint32_t(1) << Registers::lr)),
FloatRegisterSet(FloatRegisters::NonVolatileMask | (1ULL << FloatRegisters::d15)));
FloatRegisterSet(FloatRegisters::NonVolatileMask
| (1ULL << FloatRegisters::d15)
| (1ULL << FloatRegisters::s31)));
#else
static const RegisterSet NonVolatileRegs =
RegisterSet(GeneralRegisterSet(Registers::NonVolatileMask),

View File

@ -17,11 +17,11 @@ BacktrackingAllocator::init()
{
RegisterSet remainingRegisters(allRegisters_);
while (!remainingRegisters.empty(/* float = */ false)) {
AnyRegister reg = AnyRegister(remainingRegisters.takeGeneral());
AnyRegister reg = AnyRegister(remainingRegisters.takeUnaliasedGeneral());
registers[reg.code()].allocatable = true;
}
while (!remainingRegisters.empty(/* float = */ true)) {
AnyRegister reg = AnyRegister(remainingRegisters.takeFloat());
AnyRegister reg = AnyRegister(remainingRegisters.takeUnaliasedFloat());
registers[reg.code()].allocatable = true;
}

View File

@ -998,7 +998,7 @@ LinearScanAllocator::findBestFreeRegister(CodePosition *freeUntil)
for (RegisterSet regs(allRegisters_); !regs.empty(needFloat); ) {
// If the requested register is a FP, we may need to look at
// all of the float32 and float64 registers.
AnyRegister reg = regs.takeAny(needFloat);
AnyRegister reg = regs.takeUnaliasedAny(needFloat);
freeUntilPos[reg.code()] = CodePosition::MAX;
}
for (IntervalIterator i(active.begin()); i != active.end(); i++) {
@ -1126,7 +1126,7 @@ LinearScanAllocator::findBestBlockedRegister(CodePosition *nextUsed)
CodePosition nextUsePos[AnyRegister::Total];
bool needFloat = vregs[current->vreg()].isFloatReg();
for (RegisterSet regs(allRegisters_); !regs.empty(needFloat); ) {
AnyRegister reg = regs.takeAny(needFloat);
AnyRegister reg = regs.takeUnaliasedAny(needFloat);
nextUsePos[reg.code()] = CodePosition::MAX;
}
for (IntervalIterator i(active.begin()); i != active.end(); i++) {

View File

@ -425,7 +425,7 @@ class TypedRegisterSet
for (uint32_t a = 0; a < reg.numAliased(); a++) {
T tmp;
reg.aliased(a, &tmp);
bits_ &= ~(SetType(1) << tmp.code());
takeUnchecked(tmp);
}
}
void take(ValueOperand value) {
@ -488,12 +488,19 @@ class TypedRegisterSet
T takeAny() {
MOZ_ASSERT(!empty());
T reg = getAny();
take(reg);
takeAllAliasedUnchecked(reg);
return reg;
}
T takeUnaliasedAny() {
// This variant is used by LinearScan for iterating over all registers.
MOZ_ASSERT(!empty());
T reg = getAny();
takeUnchecked(reg);
return reg;
}
T takeAnyExcluding(T preclude) {
T reg = getAnyExcluding(preclude);
take(reg);
takeAllAliasedUnchecked(reg);
return reg;
}
ValueOperand takeAnyValue() {
@ -509,15 +516,20 @@ class TypedRegisterSet
#endif
}
T takeFirst() {
// This function is used to implement a forward register set iterator.
MOZ_ASSERT(!empty());
T reg = getFirst();
take(reg);
// The iterator is used by PushRegsInMask which might be called with
// AllAlllocatableRegister mask. To avoid saving more than needed we
// should take aliased registers too.
takeAllAliasedUnchecked(reg);
return reg;
}
T takeLast() {
// This function is used to implement a backward register set iterator.
MOZ_ASSERT(!empty());
T reg = getLast();
take(reg);
takeAllAliasedUnchecked(reg);
return reg;
}
void clear() {
@ -646,9 +658,15 @@ class RegisterSet {
FloatRegister takeFloat() {
return fpu_.takeAny();
}
FloatRegister takeUnaliasedFloat() {
return fpu_.takeUnaliasedAny();
}
Register takeGeneral() {
return gpr_.takeAny();
}
Register takeUnaliasedGeneral() {
return gpr_.takeUnaliasedAny();
}
ValueOperand takeValueOperand() {
#if defined(JS_NUNBOX32)
return ValueOperand(takeGeneral(), takeGeneral());
@ -670,10 +688,11 @@ class RegisterSet {
else
gpr_.takeAllAliasedUnchecked(reg.gpr());
}
AnyRegister takeAny(bool isFloat) {
// This function is used by LinearScan to find a free register.
AnyRegister takeUnaliasedAny(bool isFloat) {
if (isFloat)
return AnyRegister(takeFloat());
return AnyRegister(takeGeneral());
return AnyRegister(takeUnaliasedFloat());
return AnyRegister(takeUnaliasedGeneral());
}
void clear() {
gpr_.clear();