mirror of
https://github.com/corda/corda.git
synced 2025-01-03 19:54:13 +00:00
remove lingering 32-count limits on registers, refactor iteration, improve constants, ...
This commit is contained in:
parent
a749ba7adc
commit
01de3d9d5c
@ -45,7 +45,7 @@ class OperandMask {
|
||||
{
|
||||
}
|
||||
|
||||
OperandMask() : typeMask(~0), lowRegisterMask(RegisterMask::Any), highRegisterMask(RegisterMask::Any)
|
||||
OperandMask() : typeMask(~0), lowRegisterMask(AnyRegisterMask), highRegisterMask(AnyRegisterMask)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
1
makefile
1
makefile
@ -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
|
||||
|
@ -1,6 +1,5 @@
|
||||
add_library (avian_codegen
|
||||
compiler.cpp
|
||||
registers.cpp
|
||||
runtime.cpp
|
||||
targets.cpp
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user