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) #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) // Also exclude lr (a.k.a. r14) as we preserve it manually)
static const RegisterSet NonVolatileRegs = static const RegisterSet NonVolatileRegs =
RegisterSet(GeneralRegisterSet(Registers::NonVolatileMask & RegisterSet(GeneralRegisterSet(Registers::NonVolatileMask &
~(uint32_t(1) << Registers::lr)), ~(uint32_t(1) << Registers::lr)),
FloatRegisterSet(FloatRegisters::NonVolatileMask | (1ULL << FloatRegisters::d15))); FloatRegisterSet(FloatRegisters::NonVolatileMask
| (1ULL << FloatRegisters::d15)
| (1ULL << FloatRegisters::s31)));
#else #else
static const RegisterSet NonVolatileRegs = static const RegisterSet NonVolatileRegs =
RegisterSet(GeneralRegisterSet(Registers::NonVolatileMask), RegisterSet(GeneralRegisterSet(Registers::NonVolatileMask),

View File

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

View File

@ -998,7 +998,7 @@ LinearScanAllocator::findBestFreeRegister(CodePosition *freeUntil)
for (RegisterSet regs(allRegisters_); !regs.empty(needFloat); ) { for (RegisterSet regs(allRegisters_); !regs.empty(needFloat); ) {
// If the requested register is a FP, we may need to look at // If the requested register is a FP, we may need to look at
// all of the float32 and float64 registers. // all of the float32 and float64 registers.
AnyRegister reg = regs.takeAny(needFloat); AnyRegister reg = regs.takeUnaliasedAny(needFloat);
freeUntilPos[reg.code()] = CodePosition::MAX; freeUntilPos[reg.code()] = CodePosition::MAX;
} }
for (IntervalIterator i(active.begin()); i != active.end(); i++) { for (IntervalIterator i(active.begin()); i != active.end(); i++) {
@ -1126,7 +1126,7 @@ LinearScanAllocator::findBestBlockedRegister(CodePosition *nextUsed)
CodePosition nextUsePos[AnyRegister::Total]; CodePosition nextUsePos[AnyRegister::Total];
bool needFloat = vregs[current->vreg()].isFloatReg(); bool needFloat = vregs[current->vreg()].isFloatReg();
for (RegisterSet regs(allRegisters_); !regs.empty(needFloat); ) { for (RegisterSet regs(allRegisters_); !regs.empty(needFloat); ) {
AnyRegister reg = regs.takeAny(needFloat); AnyRegister reg = regs.takeUnaliasedAny(needFloat);
nextUsePos[reg.code()] = CodePosition::MAX; nextUsePos[reg.code()] = CodePosition::MAX;
} }
for (IntervalIterator i(active.begin()); i != active.end(); i++) { 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++) { for (uint32_t a = 0; a < reg.numAliased(); a++) {
T tmp; T tmp;
reg.aliased(a, &tmp); reg.aliased(a, &tmp);
bits_ &= ~(SetType(1) << tmp.code()); takeUnchecked(tmp);
} }
} }
void take(ValueOperand value) { void take(ValueOperand value) {
@ -488,12 +488,19 @@ class TypedRegisterSet
T takeAny() { T takeAny() {
MOZ_ASSERT(!empty()); MOZ_ASSERT(!empty());
T reg = getAny(); 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; return reg;
} }
T takeAnyExcluding(T preclude) { T takeAnyExcluding(T preclude) {
T reg = getAnyExcluding(preclude); T reg = getAnyExcluding(preclude);
take(reg); takeAllAliasedUnchecked(reg);
return reg; return reg;
} }
ValueOperand takeAnyValue() { ValueOperand takeAnyValue() {
@ -509,15 +516,20 @@ class TypedRegisterSet
#endif #endif
} }
T takeFirst() { T takeFirst() {
// This function is used to implement a forward register set iterator.
MOZ_ASSERT(!empty()); MOZ_ASSERT(!empty());
T reg = getFirst(); 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; return reg;
} }
T takeLast() { T takeLast() {
// This function is used to implement a backward register set iterator.
MOZ_ASSERT(!empty()); MOZ_ASSERT(!empty());
T reg = getLast(); T reg = getLast();
take(reg); takeAllAliasedUnchecked(reg);
return reg; return reg;
} }
void clear() { void clear() {
@ -646,9 +658,15 @@ class RegisterSet {
FloatRegister takeFloat() { FloatRegister takeFloat() {
return fpu_.takeAny(); return fpu_.takeAny();
} }
FloatRegister takeUnaliasedFloat() {
return fpu_.takeUnaliasedAny();
}
Register takeGeneral() { Register takeGeneral() {
return gpr_.takeAny(); return gpr_.takeAny();
} }
Register takeUnaliasedGeneral() {
return gpr_.takeUnaliasedAny();
}
ValueOperand takeValueOperand() { ValueOperand takeValueOperand() {
#if defined(JS_NUNBOX32) #if defined(JS_NUNBOX32)
return ValueOperand(takeGeneral(), takeGeneral()); return ValueOperand(takeGeneral(), takeGeneral());
@ -670,10 +688,11 @@ class RegisterSet {
else else
gpr_.takeAllAliasedUnchecked(reg.gpr()); 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) if (isFloat)
return AnyRegister(takeFloat()); return AnyRegister(takeUnaliasedFloat());
return AnyRegister(takeGeneral()); return AnyRegister(takeUnaliasedGeneral());
} }
void clear() { void clear() {
gpr_.clear(); gpr_.clear();