mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-01 13:57:32 +00:00
Bug 1112164 part 6 - RegisterSets: takeAny should take one register and all aliases of it. r=mjrosenb
This commit is contained in:
parent
a95d35da9b
commit
9e2d6162c1
@ -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),
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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++) {
|
||||||
|
@ -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();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user