remove lingering 32-count limits on registers, refactor iteration, improve constants, ...

This commit is contained in:
Joshua Warner 2014-12-09 10:45:35 -07:00
parent a749ba7adc
commit 01de3d9d5c
11 changed files with 104 additions and 106 deletions

View File

@ -45,7 +45,7 @@ class OperandMask {
{
}
OperandMask() : typeMask(~0), lowRegisterMask(RegisterMask::Any), highRegisterMask(RegisterMask::Any)
OperandMask() : typeMask(~0), lowRegisterMask(AnyRegisterMask), highRegisterMask(AnyRegisterMask)
{
}

View File

@ -53,7 +53,7 @@ class Assembler {
public:
class Client {
public:
virtual Register acquireTemporary(RegisterMask mask = RegisterMask::Any) = 0;
virtual Register acquireTemporary(RegisterMask mask = AnyRegisterMask) = 0;
virtual void releaseTemporary(Register r) = 0;
virtual void save(Register r) = 0;

View File

@ -61,11 +61,27 @@ constexpr Register NoRegister;
class RegisterMask {
private:
uint64_t mask;
static constexpr unsigned maskStart(uint64_t mask, unsigned offset = 64) {
return mask == 0 ? (offset & 63) : maskStart(mask << 1, offset - 1);
}
static constexpr unsigned maskLimit(uint64_t mask, unsigned offset = 0) {
return mask == 0 ? offset : maskLimit(mask >> 1, offset + 1);
}
public:
constexpr RegisterMask(uint64_t mask) : mask(mask) {}
constexpr RegisterMask() : mask(0) {}
constexpr RegisterMask(Register reg) : mask(static_cast<uint64_t>(1) << reg.index()) {}
constexpr unsigned begin() const {
return maskStart(mask);
}
constexpr unsigned end() const {
return maskLimit(mask);
}
constexpr RegisterMask operator &(RegisterMask o) const {
return RegisterMask(mask & o.mask);
}
@ -102,36 +118,79 @@ public:
constexpr explicit operator bool() const {
return mask != 0;
}
static RegisterMask Any;
static RegisterMask None;
};
constexpr RegisterMask AnyRegisterMask(~static_cast<uint64_t>(0));
constexpr RegisterMask NoneRegisterMask(0);
constexpr RegisterMask Register::operator | (Register o) const {
return RegisterMask(*this) | o;
}
class RegisterIterator;
class BoundedRegisterMask : public RegisterMask {
public:
uint8_t start;
uint8_t limit;
static unsigned maskStart(RegisterMask mask);
static unsigned maskLimit(RegisterMask mask);
inline BoundedRegisterMask(RegisterMask mask)
: RegisterMask(mask), start(maskStart(mask)), limit(maskLimit(mask))
BoundedRegisterMask(RegisterMask mask)
: RegisterMask(mask), start(mask.begin()), limit(mask.end())
{
}
RegisterIterator begin() const;
RegisterIterator end() const;
};
class RegisterIterator {
public:
int index;
int direction;
int limit;
const RegisterMask mask;
RegisterIterator(int index, int direction, int limit, RegisterMask mask)
: index(index), direction(direction), limit(limit), mask(mask)
{
}
bool operator !=(const RegisterIterator& o) const {
return index != o.index;
}
Register operator *() {
return Register(index);
}
void operator ++ () {
if(index != limit) {
index += direction;
}
while(index != limit && !mask.contains(Register(index))) {
index += direction;
}
}
};
inline RegisterIterator BoundedRegisterMask::begin() const {
// We use reverse iteration... for some reason.
return RegisterIterator(limit - 1, -1, start - 1, *this);
}
inline RegisterIterator BoundedRegisterMask::end() const {
// We use reverse iteration... for some reason.
return RegisterIterator(start - 1, -1, start - 1, *this);
}
class RegisterFile {
public:
BoundedRegisterMask allRegisters;
BoundedRegisterMask generalRegisters;
BoundedRegisterMask floatRegisters;
inline RegisterFile(RegisterMask generalRegisterMask, RegisterMask floatRegisterMask)
RegisterFile(RegisterMask generalRegisterMask, RegisterMask floatRegisterMask)
: allRegisters(generalRegisterMask | floatRegisterMask),
generalRegisters(generalRegisterMask),
floatRegisters(floatRegisterMask)
@ -139,31 +198,6 @@ class RegisterFile {
}
};
class RegisterIterator {
public:
int index;
const BoundedRegisterMask& mask;
inline RegisterIterator(const BoundedRegisterMask& mask)
: index(mask.start), mask(mask)
{
}
inline bool hasNext()
{
return index < mask.limit;
}
inline Register next()
{
int r = index;
do {
index++;
} while (index < mask.limit && !(mask.contains(Register(index))));
return Register(r);
}
};
} // namespace codegen
} // namespace avian

View File

@ -1223,7 +1223,6 @@ compiler-sources = \
$(src)/codegen/compiler.cpp \
$(wildcard $(src)/codegen/compiler/*.cpp) \
$(src)/debug-util.cpp \
$(src)/codegen/registers.cpp \
$(src)/codegen/runtime.cpp \
$(src)/codegen/targets.cpp \
$(src)/util/fixed-allocator.cpp

View File

@ -1,6 +1,5 @@
add_library (avian_codegen
compiler.cpp
registers.cpp
runtime.cpp
targets.cpp

View File

@ -53,19 +53,15 @@ Context::Context(vm::System* system,
- regFile->generalRegisters.start),
targetInfo(arch->targetInfo())
{
for (unsigned i = regFile->generalRegisters.start;
i < regFile->generalRegisters.limit;
++i) {
new (registerResources + i) RegisterResource(arch->reserved(Register(i)));
for (Register i : regFile->generalRegisters) {
new (registerResources + i.index()) RegisterResource(arch->reserved(i));
if (registerResources[i].reserved) {
if (registerResources[i.index()].reserved) {
--availableGeneralRegisterCount;
}
}
for (unsigned i = regFile->floatRegisters.start;
i < regFile->floatRegisters.limit;
++i) {
new (registerResources + i) RegisterResource(arch->reserved(Register(i)));
for (Register i : regFile->floatRegisters) {
new (registerResources + i.index()) RegisterResource(arch->reserved(i));
}
}

View File

@ -95,9 +95,7 @@ Register pickRegisterTarget(Context* c,
*cost = Target::Impossible;
if (mask & c->regFile->generalRegisters) {
for (Register i = Register(c->regFile->generalRegisters.limit - 1);
i.index() >= c->regFile->generalRegisters.start;
i = Register(i.index() - 1)) {
for (Register i : c->regFile->generalRegisters) {
if (pickRegisterTarget(c, i, v, mask, &target, cost, costCalculator)) {
return i;
}
@ -105,9 +103,7 @@ Register pickRegisterTarget(Context* c,
}
if (mask & c->regFile->floatRegisters) {
for (Register i = Register(c->regFile->floatRegisters.start);
i.index() < c->regFile->floatRegisters.limit;
i = Register(i.index() + 1)) {
for (Register i : c->regFile->floatRegisters) {
if (pickRegisterTarget(c, i, v, mask, &target, cost, costCalculator)) {
return i;
}
@ -235,7 +231,7 @@ Target pickTarget(Context* c,
Value* value = read->value;
RegisterMask registerMask
= (isFloatValue(value) ? RegisterMask::Any : (RegisterMask)c->regFile->generalRegisters);
= (isFloatValue(value) ? AnyRegisterMask : (RegisterMask)c->regFile->generalRegisters);
SiteMask mask(~0, registerMask, AnyFrameIndex);
read->intersect(&mask);

View File

@ -1,37 +0,0 @@
/* Copyright (c) 2008-2014, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
#include <avian/codegen/registers.h>
namespace avian {
namespace codegen {
unsigned BoundedRegisterMask::maskStart(RegisterMask mask)
{
for (int i = 0; i <= 31; ++i) {
if (mask.contains(Register(i)))
return i;
}
return 32;
}
unsigned BoundedRegisterMask::maskLimit(RegisterMask mask)
{
for (int i = 31; i >= 0; --i) {
if (mask.contains(Register(i)))
return i + 1;
}
return 0;
}
RegisterMask RegisterMask::Any(~static_cast<uint64_t>(0));
} // namespace codegen
} // namespace avian

View File

@ -397,7 +397,7 @@ class MyArchitecture : public Architecture {
bool* thunk)
{
aMask.typeMask = lir::Operand::RegisterPairMask | lir::Operand::ConstantMask;
aMask.setLowHighRegisterMasks(~static_cast<uint64_t>(0), ~static_cast<uint64_t>(0));
aMask.setLowHighRegisterMasks(AnyRegisterMask, AnyRegisterMask);
*thunk = false;
}
@ -506,7 +506,7 @@ class MyArchitecture : public Architecture {
const OperandMask& dstMask)
{
srcMask.typeMask = ~0;
srcMask.setLowHighRegisterMasks(~static_cast<uint64_t>(0), ~static_cast<uint64_t>(0));
srcMask.setLowHighRegisterMasks(AnyRegisterMask, AnyRegisterMask);
tmpMask.typeMask = 0;
tmpMask.setLowHighRegisterMasks(0, 0);
@ -520,7 +520,7 @@ class MyArchitecture : public Architecture {
&& dstMask.lowRegisterMask & FPR_MASK) {
srcMask.typeMask = tmpMask.typeMask = lir::Operand::RegisterPairMask
| lir::Operand::MemoryMask;
tmpMask.setLowHighRegisterMasks(~static_cast<uint64_t>(0), ~static_cast<uint64_t>(0));
tmpMask.setLowHighRegisterMasks(AnyRegisterMask, AnyRegisterMask);
}
}

View File

@ -596,7 +596,7 @@ class MyArchitecture : public Architecture {
case lir::Move:
aMask.typeMask = ~0;
aMask.setLowHighRegisterMasks(~static_cast<uint64_t>(0), ~static_cast<uint64_t>(0));
aMask.setLowHighRegisterMasks(AnyRegisterMask, AnyRegisterMask);
if (TargetBytesPerWord == 4) {
if (aSize == 4 and bSize == 8) {
@ -697,7 +697,7 @@ class MyArchitecture : public Architecture {
const OperandMask& dstMask)
{
srcMask.typeMask = ~0;
srcMask.setLowHighRegisterMasks(~static_cast<uint64_t>(0), ~static_cast<uint64_t>(0));
srcMask.setLowHighRegisterMasks(AnyRegisterMask, AnyRegisterMask);
tmpMask.typeMask = 0;
tmpMask.setLowHighRegisterMasks(0, 0);

View File

@ -23,14 +23,25 @@ TEST(RegisterIterator)
assertEqual<unsigned>(0, regs.start);
assertEqual<unsigned>(7, regs.limit);
RegisterIterator it(regs);
assertTrue(it.hasNext());
assertEqual<unsigned>(0, it.next().index());
assertTrue(it.hasNext());
assertEqual<unsigned>(2, it.next().index());
assertTrue(it.hasNext());
assertEqual<unsigned>(4, it.next().index());
assertTrue(it.hasNext());
assertEqual<unsigned>(6, it.next().index());
assertFalse(it.hasNext());
for(int i = 0; i < 64; i++) {
assertEqual<unsigned>(i, BoundedRegisterMask(static_cast<uint64_t>(1) << i).start);
assertEqual<unsigned>(i + 1, BoundedRegisterMask(static_cast<uint64_t>(1) << i).limit);
}
auto it = regs.begin();
auto end = regs.end();
assertTrue(it != end);
assertEqual<unsigned>(6, (*it).index());
++it;
assertTrue(it != end);
assertEqual<unsigned>(4, (*it).index());
++it;
assertTrue(it != end);
assertEqual<unsigned>(2, (*it).index());
++it;
assertTrue(it != end);
assertEqual<unsigned>(0, (*it).index());
++it;
assertFalse(it != end);
}