mirror of
https://github.com/corda/corda.git
synced 2025-01-31 16:35:43 +00:00
begin splitting up compiler.cpp
This commit is contained in:
parent
ef5e534e1e
commit
740886d58e
4
makefile
4
makefile
@ -923,7 +923,7 @@ generated-code = \
|
|||||||
$(build)/type-name-initializations.cpp \
|
$(build)/type-name-initializations.cpp \
|
||||||
$(build)/type-maps.cpp
|
$(build)/type-maps.cpp
|
||||||
|
|
||||||
vm-depends := $(generated-code) $(wildcard $(src)/*.h) $(wildcard $(src)/codegen/*.h)
|
vm-depends := $(generated-code) $(wildcard $(src)/*.h) $(wildcard $(src)/codegen/*.h) $(wildcard $(src)/codegen/compiler/*.h)
|
||||||
|
|
||||||
vm-sources = \
|
vm-sources = \
|
||||||
$(src)/$(system).cpp \
|
$(src)/$(system).cpp \
|
||||||
@ -954,6 +954,8 @@ ifeq ($(process),compile)
|
|||||||
vm-sources += \
|
vm-sources += \
|
||||||
$(src)/codegen/compiler.cpp \
|
$(src)/codegen/compiler.cpp \
|
||||||
$(src)/codegen/regalloc.cpp \
|
$(src)/codegen/regalloc.cpp \
|
||||||
|
$(src)/codegen/compiler/context.cpp \
|
||||||
|
$(src)/codegen/compiler/resource.cpp \
|
||||||
$(src)/codegen/registers.cpp \
|
$(src)/codegen/registers.cpp \
|
||||||
$(src)/codegen/targets.cpp
|
$(src)/codegen/targets.cpp
|
||||||
|
|
||||||
|
@ -16,12 +16,15 @@
|
|||||||
#include "codegen/assembler.h"
|
#include "codegen/assembler.h"
|
||||||
#include "codegen/regalloc.h"
|
#include "codegen/regalloc.h"
|
||||||
|
|
||||||
|
#include "codegen/compiler/context.h"
|
||||||
|
#include "codegen/compiler/resource.h"
|
||||||
|
#include "codegen/compiler/value.h"
|
||||||
|
|
||||||
using namespace vm;
|
using namespace vm;
|
||||||
using namespace avian::codegen;
|
|
||||||
|
|
||||||
namespace {
|
namespace avian {
|
||||||
|
namespace codegen {
|
||||||
namespace local {
|
namespace compiler {
|
||||||
|
|
||||||
const bool DebugAppend = false;
|
const bool DebugAppend = false;
|
||||||
const bool DebugCompile = false;
|
const bool DebugCompile = false;
|
||||||
@ -33,9 +36,6 @@ const bool DebugSites = false;
|
|||||||
const bool DebugMoves = false;
|
const bool DebugMoves = false;
|
||||||
const bool DebugBuddies = false;
|
const bool DebugBuddies = false;
|
||||||
|
|
||||||
const int AnyFrameIndex = -2;
|
|
||||||
const int NoFrameIndex = -1;
|
|
||||||
|
|
||||||
const unsigned StealRegisterReserveCount = 2;
|
const unsigned StealRegisterReserveCount = 2;
|
||||||
|
|
||||||
// this should be equal to the largest number of registers used by a
|
// this should be equal to the largest number of registers used by a
|
||||||
@ -48,8 +48,6 @@ const unsigned ConstantCopyCost = 3;
|
|||||||
const unsigned MemoryCopyCost = 4;
|
const unsigned MemoryCopyCost = 4;
|
||||||
const unsigned CopyPenalty = 10;
|
const unsigned CopyPenalty = 10;
|
||||||
|
|
||||||
class Context;
|
|
||||||
class Value;
|
|
||||||
class Stack;
|
class Stack;
|
||||||
class Site;
|
class Site;
|
||||||
class ConstantSite;
|
class ConstantSite;
|
||||||
@ -79,8 +77,6 @@ apply(Context* c, lir::TernaryOperation op,
|
|||||||
unsigned s2Size, Site* s2Low, Site* s2High,
|
unsigned s2Size, Site* s2Low, Site* s2High,
|
||||||
unsigned s3Size, Site* s3Low, Site* s3High);
|
unsigned s3Size, Site* s3Low, Site* s3High);
|
||||||
|
|
||||||
inline Aborter* getAborter(Context* c);
|
|
||||||
|
|
||||||
class Cell {
|
class Cell {
|
||||||
public:
|
public:
|
||||||
Cell(Cell* next, void* value): next(next), value(value) { }
|
Cell(Cell* next, void* value): next(next), value(value) { }
|
||||||
@ -221,58 +217,6 @@ class LogicalInstruction {
|
|||||||
int index;
|
int index;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Resource {
|
|
||||||
public:
|
|
||||||
Resource(bool reserved = false):
|
|
||||||
value(0), site(0), previousAcquired(0), nextAcquired(0), freezeCount(0),
|
|
||||||
referenceCount(0), reserved(reserved)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
virtual void freeze(Context*, Value*) = 0;
|
|
||||||
|
|
||||||
virtual void thaw(Context*, Value*) = 0;
|
|
||||||
|
|
||||||
virtual unsigned toString(Context*, char*, unsigned) = 0;
|
|
||||||
|
|
||||||
Value* value;
|
|
||||||
Site* site;
|
|
||||||
Resource* previousAcquired;
|
|
||||||
Resource* nextAcquired;
|
|
||||||
uint8_t freezeCount;
|
|
||||||
uint8_t referenceCount;
|
|
||||||
bool reserved;
|
|
||||||
};
|
|
||||||
|
|
||||||
class RegisterResource: public Resource {
|
|
||||||
public:
|
|
||||||
RegisterResource(bool reserved):
|
|
||||||
Resource(reserved)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
virtual void freeze(Context*, Value*);
|
|
||||||
|
|
||||||
virtual void thaw(Context*, Value*);
|
|
||||||
|
|
||||||
virtual unsigned toString(Context* c, char* buffer, unsigned bufferSize) {
|
|
||||||
return vm::snprintf(buffer, bufferSize, "register %d", index(c));
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual unsigned index(Context*);
|
|
||||||
};
|
|
||||||
|
|
||||||
class FrameResource: public Resource {
|
|
||||||
public:
|
|
||||||
virtual void freeze(Context*, Value*);
|
|
||||||
|
|
||||||
virtual void thaw(Context*, Value*);
|
|
||||||
|
|
||||||
virtual unsigned toString(Context* c, char* buffer, unsigned bufferSize) {
|
|
||||||
return vm::snprintf(buffer, bufferSize, "frame %d", index(c));
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual unsigned index(Context*);
|
|
||||||
};
|
|
||||||
|
|
||||||
class ConstantPoolNode {
|
class ConstantPoolNode {
|
||||||
public:
|
public:
|
||||||
ConstantPoolNode(Promise* promise): promise(promise), next(0) { }
|
ConstantPoolNode(Promise* promise): promise(promise), next(0) { }
|
||||||
@ -321,124 +265,6 @@ intersect(const SiteMask& a, const SiteMask& b)
|
|||||||
intersectFrameIndexes(a.frameIndex, b.frameIndex));
|
intersectFrameIndexes(a.frameIndex, b.frameIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
class Value: public Compiler::Operand {
|
|
||||||
public:
|
|
||||||
Value(Site* site, Site* target, lir::ValueType type):
|
|
||||||
reads(0), lastRead(0), sites(site), source(0), target(target), buddy(this),
|
|
||||||
nextWord(this), home(NoFrameIndex), type(type), wordIndex(0)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
Read* reads;
|
|
||||||
Read* lastRead;
|
|
||||||
Site* sites;
|
|
||||||
Site* source;
|
|
||||||
Site* target;
|
|
||||||
Value* buddy;
|
|
||||||
Value* nextWord;
|
|
||||||
int16_t home;
|
|
||||||
lir::ValueType type;
|
|
||||||
uint8_t wordIndex;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Context {
|
|
||||||
public:
|
|
||||||
Context(System* system, Assembler* assembler, Zone* zone,
|
|
||||||
Compiler::Client* client):
|
|
||||||
system(system),
|
|
||||||
assembler(assembler),
|
|
||||||
arch(assembler->arch()),
|
|
||||||
zone(zone),
|
|
||||||
client(client),
|
|
||||||
stack(0),
|
|
||||||
locals(0),
|
|
||||||
saved(0),
|
|
||||||
predecessor(0),
|
|
||||||
logicalCode(0),
|
|
||||||
regFile(arch->registerFile()),
|
|
||||||
regAlloc(system, arch->registerFile()),
|
|
||||||
registerResources
|
|
||||||
(static_cast<RegisterResource*>
|
|
||||||
(zone->allocate(sizeof(RegisterResource) * regFile->allRegisters.limit))),
|
|
||||||
frameResources(0),
|
|
||||||
acquiredResources(0),
|
|
||||||
firstConstant(0),
|
|
||||||
lastConstant(0),
|
|
||||||
machineCode(0),
|
|
||||||
firstEvent(0),
|
|
||||||
lastEvent(0),
|
|
||||||
forkState(0),
|
|
||||||
subroutine(0),
|
|
||||||
firstBlock(0),
|
|
||||||
logicalIp(-1),
|
|
||||||
constantCount(0),
|
|
||||||
logicalCodeLength(0),
|
|
||||||
parameterFootprint(0),
|
|
||||||
localFootprint(0),
|
|
||||||
machineCodeSize(0),
|
|
||||||
alignedFrameSize(0),
|
|
||||||
availableGeneralRegisterCount(regFile->generalRegisters.limit - regFile->generalRegisters.start)
|
|
||||||
{
|
|
||||||
for (unsigned i = regFile->generalRegisters.start; i < regFile->generalRegisters.limit; ++i) {
|
|
||||||
new (registerResources + i) RegisterResource(arch->reserved(i));
|
|
||||||
|
|
||||||
if (registerResources[i].reserved) {
|
|
||||||
-- availableGeneralRegisterCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (unsigned i = regFile->floatRegisters.start; i < regFile->floatRegisters.limit; ++i) {
|
|
||||||
new (registerResources + i) RegisterResource(arch->reserved(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
System* system;
|
|
||||||
Assembler* assembler;
|
|
||||||
Assembler::Architecture* arch;
|
|
||||||
Zone* zone;
|
|
||||||
Compiler::Client* client;
|
|
||||||
Stack* stack;
|
|
||||||
Local* locals;
|
|
||||||
Cell* saved;
|
|
||||||
Event* predecessor;
|
|
||||||
LogicalInstruction** logicalCode;
|
|
||||||
const RegisterFile* regFile;
|
|
||||||
regalloc::RegisterAllocator regAlloc;
|
|
||||||
RegisterResource* registerResources;
|
|
||||||
FrameResource* frameResources;
|
|
||||||
Resource* acquiredResources;
|
|
||||||
ConstantPoolNode* firstConstant;
|
|
||||||
ConstantPoolNode* lastConstant;
|
|
||||||
uint8_t* machineCode;
|
|
||||||
Event* firstEvent;
|
|
||||||
Event* lastEvent;
|
|
||||||
ForkState* forkState;
|
|
||||||
MySubroutine* subroutine;
|
|
||||||
Block* firstBlock;
|
|
||||||
int logicalIp;
|
|
||||||
unsigned constantCount;
|
|
||||||
unsigned logicalCodeLength;
|
|
||||||
unsigned parameterFootprint;
|
|
||||||
unsigned localFootprint;
|
|
||||||
unsigned machineCodeSize;
|
|
||||||
unsigned alignedFrameSize;
|
|
||||||
unsigned availableGeneralRegisterCount;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline Aborter* getAborter(Context* c) {
|
|
||||||
return c->system;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned
|
|
||||||
RegisterResource::index(Context* c)
|
|
||||||
{
|
|
||||||
return this - c->registerResources;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned
|
|
||||||
FrameResource::index(Context* c)
|
|
||||||
{
|
|
||||||
return this - c->frameResources;
|
|
||||||
}
|
|
||||||
|
|
||||||
class PoolPromise: public Promise {
|
class PoolPromise: public Promise {
|
||||||
public:
|
public:
|
||||||
PoolPromise(Context* c, int key): c(c), key(key) { }
|
PoolPromise(Context* c, int key): c(c), key(key) { }
|
||||||
@ -1093,135 +919,6 @@ addBuddy(Value* original, Value* buddy)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
decrementAvailableGeneralRegisterCount(Context* c)
|
|
||||||
{
|
|
||||||
assert(c, c->availableGeneralRegisterCount);
|
|
||||||
-- c->availableGeneralRegisterCount;
|
|
||||||
|
|
||||||
if (DebugResources) {
|
|
||||||
fprintf(stderr, "%d registers available\n",
|
|
||||||
c->availableGeneralRegisterCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
incrementAvailableGeneralRegisterCount(Context* c)
|
|
||||||
{
|
|
||||||
++ c->availableGeneralRegisterCount;
|
|
||||||
|
|
||||||
if (DebugResources) {
|
|
||||||
fprintf(stderr, "%d registers available\n",
|
|
||||||
c->availableGeneralRegisterCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
increment(Context* c, RegisterResource* r)
|
|
||||||
{
|
|
||||||
if (not r->reserved) {
|
|
||||||
if (DebugResources) {
|
|
||||||
char buffer[256]; r->toString(c, buffer, 256);
|
|
||||||
fprintf(stderr, "increment %s to %d\n", buffer, r->referenceCount + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
++ r->referenceCount;
|
|
||||||
|
|
||||||
if (r->referenceCount == 1
|
|
||||||
and ((1 << r->index(c)) & c->regFile->generalRegisters.mask))
|
|
||||||
{
|
|
||||||
decrementAvailableGeneralRegisterCount(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
decrement(Context* c, RegisterResource* r)
|
|
||||||
{
|
|
||||||
if (not r->reserved) {
|
|
||||||
if (DebugResources) {
|
|
||||||
char buffer[256]; r->toString(c, buffer, 256);
|
|
||||||
fprintf(stderr, "decrement %s to %d\n", buffer, r->referenceCount - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(c, r->referenceCount > 0);
|
|
||||||
|
|
||||||
-- r->referenceCount;
|
|
||||||
|
|
||||||
if (r->referenceCount == 0
|
|
||||||
and ((1 << r->index(c)) & c->regFile->generalRegisters.mask))
|
|
||||||
{
|
|
||||||
incrementAvailableGeneralRegisterCount(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
freezeResource(Context* c, Resource* r, Value* v)
|
|
||||||
{
|
|
||||||
if (DebugResources) {
|
|
||||||
char buffer[256]; r->toString(c, buffer, 256);
|
|
||||||
fprintf(stderr, "%p freeze %s to %d\n", v, buffer, r->freezeCount + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
++ r->freezeCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
RegisterResource::freeze(Context* c, Value* v)
|
|
||||||
{
|
|
||||||
if (not reserved) {
|
|
||||||
freezeResource(c, this, v);
|
|
||||||
|
|
||||||
if (freezeCount == 1
|
|
||||||
and ((1 << index(c)) & c->regFile->generalRegisters.mask))
|
|
||||||
{
|
|
||||||
decrementAvailableGeneralRegisterCount(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
FrameResource::freeze(Context* c, Value* v)
|
|
||||||
{
|
|
||||||
freezeResource(c, this, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
thawResource(Context* c, Resource* r, Value* v)
|
|
||||||
{
|
|
||||||
if (not r->reserved) {
|
|
||||||
if (DebugResources) {
|
|
||||||
char buffer[256]; r->toString(c, buffer, 256);
|
|
||||||
fprintf(stderr, "%p thaw %s to %d\n", v, buffer, r->freezeCount - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(c, r->freezeCount);
|
|
||||||
|
|
||||||
-- r->freezeCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
RegisterResource::thaw(Context* c, Value* v)
|
|
||||||
{
|
|
||||||
if (not reserved) {
|
|
||||||
thawResource(c, this, v);
|
|
||||||
|
|
||||||
if (freezeCount == 0
|
|
||||||
and ((1 << index(c)) & c->regFile->generalRegisters.mask))
|
|
||||||
{
|
|
||||||
incrementAvailableGeneralRegisterCount(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
FrameResource::thaw(Context* c, Value* v)
|
|
||||||
{
|
|
||||||
thawResource(c, this, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
class Target {
|
class Target {
|
||||||
public:
|
public:
|
||||||
static const unsigned MinimumRegisterCost = 0;
|
static const unsigned MinimumRegisterCost = 0;
|
||||||
@ -1796,7 +1493,7 @@ class RegisterSite: public Site {
|
|||||||
}
|
}
|
||||||
|
|
||||||
RegisterResource* resource = c->registerResources + target.index;
|
RegisterResource* resource = c->registerResources + target.index;
|
||||||
local::acquire(c, resource, v, this);
|
compiler::acquire(c, resource, v, this);
|
||||||
|
|
||||||
number = target.index;
|
number = target.index;
|
||||||
}
|
}
|
||||||
@ -1804,7 +1501,7 @@ class RegisterSite: public Site {
|
|||||||
virtual void release(Context* c, Value* v) {
|
virtual void release(Context* c, Value* v) {
|
||||||
assert(c, number != lir::NoRegister);
|
assert(c, number != lir::NoRegister);
|
||||||
|
|
||||||
local::release(c, c->registerResources + number, v, this);
|
compiler::release(c, c->registerResources + number, v, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void freeze(Context* c, Value* v) {
|
virtual void freeze(Context* c, Value* v) {
|
||||||
@ -2020,9 +1717,9 @@ class MemorySite: public Site {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void acquire(Context* c, Value* v) {
|
virtual void acquire(Context* c, Value* v) {
|
||||||
increment(c, c->registerResources + base);
|
c->registerResources[base].increment(c);
|
||||||
if (index != lir::NoRegister) {
|
if (index != lir::NoRegister) {
|
||||||
increment(c, c->registerResources + index);
|
c->registerResources[index].increment(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (base == c->arch->stack()) {
|
if (base == c->arch->stack()) {
|
||||||
@ -2030,7 +1727,7 @@ class MemorySite: public Site {
|
|||||||
assert
|
assert
|
||||||
(c, not c->frameResources[offsetToFrameIndex(c, offset)].reserved);
|
(c, not c->frameResources[offsetToFrameIndex(c, offset)].reserved);
|
||||||
|
|
||||||
local::acquire
|
compiler::acquire
|
||||||
(c, c->frameResources + offsetToFrameIndex(c, offset), v, this);
|
(c, c->frameResources + offsetToFrameIndex(c, offset), v, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2043,13 +1740,13 @@ class MemorySite: public Site {
|
|||||||
assert
|
assert
|
||||||
(c, not c->frameResources[offsetToFrameIndex(c, offset)].reserved);
|
(c, not c->frameResources[offsetToFrameIndex(c, offset)].reserved);
|
||||||
|
|
||||||
local::release
|
compiler::release
|
||||||
(c, c->frameResources + offsetToFrameIndex(c, offset), v, this);
|
(c, c->frameResources + offsetToFrameIndex(c, offset), v, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
decrement(c, c->registerResources + base);
|
c->registerResources[base].decrement(c);
|
||||||
if (index != lir::NoRegister) {
|
if (index != lir::NoRegister) {
|
||||||
decrement(c, c->registerResources + index);
|
c->registerResources[index].decrement(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
acquired = false;
|
acquired = false;
|
||||||
@ -2059,9 +1756,9 @@ class MemorySite: public Site {
|
|||||||
if (base == c->arch->stack()) {
|
if (base == c->arch->stack()) {
|
||||||
c->frameResources[offsetToFrameIndex(c, offset)].freeze(c, v);
|
c->frameResources[offsetToFrameIndex(c, offset)].freeze(c, v);
|
||||||
} else {
|
} else {
|
||||||
increment(c, c->registerResources + base);
|
c->registerResources[base].increment(c);
|
||||||
if (index != lir::NoRegister) {
|
if (index != lir::NoRegister) {
|
||||||
increment(c, c->registerResources + index);
|
c->registerResources[index].increment(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2070,9 +1767,9 @@ class MemorySite: public Site {
|
|||||||
if (base == c->arch->stack()) {
|
if (base == c->arch->stack()) {
|
||||||
c->frameResources[offsetToFrameIndex(c, offset)].thaw(c, v);
|
c->frameResources[offsetToFrameIndex(c, offset)].thaw(c, v);
|
||||||
} else {
|
} else {
|
||||||
decrement(c, c->registerResources + base);
|
c->registerResources[base].decrement(c);
|
||||||
if (index != lir::NoRegister) {
|
if (index != lir::NoRegister) {
|
||||||
decrement(c, c->registerResources + index);
|
c->registerResources[index].decrement(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2245,7 +1942,7 @@ class SingleRead: public Read {
|
|||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual bool intersect(SiteMask* mask, unsigned) {
|
virtual bool intersect(SiteMask* mask, unsigned) {
|
||||||
*mask = local::intersect(*mask, this->mask);
|
*mask = compiler::intersect(*mask, this->mask);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -3082,11 +2779,11 @@ saveLocals(Context* c, Event* e)
|
|||||||
if (local->value) {
|
if (local->value) {
|
||||||
if (DebugReads) {
|
if (DebugReads) {
|
||||||
fprintf(stderr, "local save read %p at %d of %d\n",
|
fprintf(stderr, "local save read %p at %d of %d\n",
|
||||||
local->value, local::frameIndex(c, li), totalFrameSize(c));
|
local->value, compiler::frameIndex(c, li), totalFrameSize(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
addRead(c, e, local->value, SiteMask
|
addRead(c, e, local->value, SiteMask
|
||||||
(1 << lir::MemoryOperand, 0, local::frameIndex(c, li)));
|
(1 << lir::MemoryOperand, 0, compiler::frameIndex(c, li)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3266,7 +2963,7 @@ class CallEvent: public Event {
|
|||||||
|
|
||||||
while (stack) {
|
while (stack) {
|
||||||
if (stack->value) {
|
if (stack->value) {
|
||||||
unsigned logicalIndex = local::frameIndex
|
unsigned logicalIndex = compiler::frameIndex
|
||||||
(c, stack->index + c->localFootprint);
|
(c, stack->index + c->localFootprint);
|
||||||
|
|
||||||
if (DebugReads) {
|
if (DebugReads) {
|
||||||
@ -4376,13 +4073,13 @@ appendCombine(Context* c, lir::TernaryOperation type,
|
|||||||
unsigned stackSize = ceilingDivide(secondSize, TargetBytesPerWord)
|
unsigned stackSize = ceilingDivide(secondSize, TargetBytesPerWord)
|
||||||
+ ceilingDivide(firstSize, TargetBytesPerWord);
|
+ ceilingDivide(firstSize, TargetBytesPerWord);
|
||||||
|
|
||||||
local::push(c, ceilingDivide(secondSize, TargetBytesPerWord), second);
|
compiler::push(c, ceilingDivide(secondSize, TargetBytesPerWord), second);
|
||||||
local::push(c, ceilingDivide(firstSize, TargetBytesPerWord), first);
|
compiler::push(c, ceilingDivide(firstSize, TargetBytesPerWord), first);
|
||||||
|
|
||||||
if (threadParameter) {
|
if (threadParameter) {
|
||||||
++ stackSize;
|
++ stackSize;
|
||||||
|
|
||||||
local::push(c, 1, register_(c, c->arch->thread()));
|
compiler::push(c, 1, register_(c, c->arch->thread()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Stack* argumentStack = c->stack;
|
Stack* argumentStack = c->stack;
|
||||||
@ -4499,7 +4196,7 @@ appendTranslate(Context* c, lir::BinaryOperation type, unsigned firstSize,
|
|||||||
if (thunk) {
|
if (thunk) {
|
||||||
Stack* oldStack = c->stack;
|
Stack* oldStack = c->stack;
|
||||||
|
|
||||||
local::push(c, ceilingDivide(firstSize, TargetBytesPerWord), first);
|
compiler::push(c, ceilingDivide(firstSize, TargetBytesPerWord), first);
|
||||||
|
|
||||||
Stack* argumentStack = c->stack;
|
Stack* argumentStack = c->stack;
|
||||||
c->stack = oldStack;
|
c->stack = oldStack;
|
||||||
@ -4848,8 +4545,8 @@ appendBranch(Context* c, lir::TernaryOperation type, unsigned size, Value* first
|
|||||||
|
|
||||||
assert(c, not threadParameter);
|
assert(c, not threadParameter);
|
||||||
|
|
||||||
local::push(c, ceilingDivide(size, TargetBytesPerWord), second);
|
compiler::push(c, ceilingDivide(size, TargetBytesPerWord), second);
|
||||||
local::push(c, ceilingDivide(size, TargetBytesPerWord), first);
|
compiler::push(c, ceilingDivide(size, TargetBytesPerWord), first);
|
||||||
|
|
||||||
Stack* argumentStack = c->stack;
|
Stack* argumentStack = c->stack;
|
||||||
c->stack = oldStack;
|
c->stack = oldStack;
|
||||||
@ -5209,7 +4906,7 @@ append(Context* c, Event* e)
|
|||||||
e->logicalInstruction->index);
|
e->logicalInstruction->index);
|
||||||
}
|
}
|
||||||
|
|
||||||
Link* link = local::link
|
Link* link = compiler::link
|
||||||
(c, p, e->predecessors, e, p->successors, c->forkState);
|
(c, p, e->predecessors, e, p->successors, c->forkState);
|
||||||
e->predecessors = link;
|
e->predecessors = link;
|
||||||
p->successors = link;
|
p->successors = link;
|
||||||
@ -5840,7 +5537,7 @@ compile(Context* c, uintptr_t stackOverflowHandler, unsigned stackLimitOffset)
|
|||||||
block->assemblerBlock = a->endBlock(e->next != 0);
|
block->assemblerBlock = a->endBlock(e->next != 0);
|
||||||
|
|
||||||
if (e->next) {
|
if (e->next) {
|
||||||
block = local::block(c, e->next);
|
block = compiler::block(c, e->next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5969,12 +5666,12 @@ class Client: public Assembler::Client {
|
|||||||
int r = pickRegisterTarget(c, 0, mask, &cost);
|
int r = pickRegisterTarget(c, 0, mask, &cost);
|
||||||
expect(c, cost < Target::Impossible);
|
expect(c, cost < Target::Impossible);
|
||||||
save(r);
|
save(r);
|
||||||
increment(c, c->registerResources + r);
|
c->registerResources[r].increment(c);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void releaseTemporary(int r) {
|
virtual void releaseTemporary(int r) {
|
||||||
decrement(c, c->registerResources + r);
|
c->registerResources[r].decrement(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void save(int r) {
|
virtual void save(int r) {
|
||||||
@ -6002,13 +5699,13 @@ class MyCompiler: public Compiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual State* saveState() {
|
virtual State* saveState() {
|
||||||
State* s = local::saveState(&c);
|
State* s = compiler::saveState(&c);
|
||||||
restoreState(s);
|
restoreState(s);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void restoreState(State* state) {
|
virtual void restoreState(State* state) {
|
||||||
local::restoreState(&c, static_cast<ForkState*>(state));
|
compiler::restoreState(&c, static_cast<ForkState*>(state));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Subroutine* startSubroutine() {
|
virtual Subroutine* startSubroutine() {
|
||||||
@ -6018,7 +5715,7 @@ class MyCompiler: public Compiler {
|
|||||||
virtual void returnFromSubroutine(Subroutine* subroutine, Operand* address) {
|
virtual void returnFromSubroutine(Subroutine* subroutine, Operand* address) {
|
||||||
appendSaveLocals(&c);
|
appendSaveLocals(&c);
|
||||||
appendJump(&c, lir::Jump, static_cast<Value*>(address), false, true);
|
appendJump(&c, lir::Jump, static_cast<Value*>(address), false, true);
|
||||||
static_cast<MySubroutine*>(subroutine)->forkState = local::saveState(&c);
|
static_cast<MySubroutine*>(subroutine)->forkState = compiler::saveState(&c);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void linkSubroutine(Subroutine* subroutine) {
|
virtual void linkSubroutine(Subroutine* subroutine) {
|
||||||
@ -6085,7 +5782,7 @@ class MyCompiler: public Compiler {
|
|||||||
p->stackAfter = c.stack;
|
p->stackAfter = c.stack;
|
||||||
p->localsAfter = c.locals;
|
p->localsAfter = c.locals;
|
||||||
|
|
||||||
Link* link = local::link
|
Link* link = compiler::link
|
||||||
(&c, p, e->predecessors, e, p->successors, c.forkState);
|
(&c, p, e->predecessors, e, p->successors, c.forkState);
|
||||||
e->predecessors = link;
|
e->predecessors = link;
|
||||||
p->successors = link;
|
p->successors = link;
|
||||||
@ -6181,12 +5878,12 @@ class MyCompiler: public Compiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual Operand* promiseConstant(Promise* value, Compiler::OperandType type) {
|
virtual Operand* promiseConstant(Promise* value, Compiler::OperandType type) {
|
||||||
return local::value
|
return compiler::value
|
||||||
(&c, valueType(&c, type), local::constantSite(&c, value));
|
(&c, valueType(&c, type), compiler::constantSite(&c, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Operand* address(Promise* address) {
|
virtual Operand* address(Promise* address) {
|
||||||
return value(&c, lir::ValueGeneral, local::addressSite(&c, address));
|
return value(&c, lir::ValueGeneral, compiler::addressSite(&c, address));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Operand* memory(Operand* base,
|
virtual Operand* memory(Operand* base,
|
||||||
@ -6204,7 +5901,7 @@ class MyCompiler: public Compiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual Operand* register_(int number) {
|
virtual Operand* register_(int number) {
|
||||||
return local::register_(&c, number);
|
return compiler::register_(&c, number);
|
||||||
}
|
}
|
||||||
|
|
||||||
Promise* machineIp() {
|
Promise* machineIp() {
|
||||||
@ -6215,14 +5912,14 @@ class MyCompiler: public Compiler {
|
|||||||
assert(&c, footprint == 1);
|
assert(&c, footprint == 1);
|
||||||
|
|
||||||
Value* v = value(&c, lir::ValueGeneral);
|
Value* v = value(&c, lir::ValueGeneral);
|
||||||
Stack* s = local::stack(&c, v, c.stack);
|
Stack* s = compiler::stack(&c, v, c.stack);
|
||||||
|
|
||||||
v->home = frameIndex(&c, s->index + c.localFootprint);
|
v->home = frameIndex(&c, s->index + c.localFootprint);
|
||||||
c.stack = s;
|
c.stack = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void push(unsigned footprint, Operand* value) {
|
virtual void push(unsigned footprint, Operand* value) {
|
||||||
local::push(&c, footprint, static_cast<Value*>(value));
|
compiler::push(&c, footprint, static_cast<Value*>(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void save(unsigned footprint, Operand* value) {
|
virtual void save(unsigned footprint, Operand* value) {
|
||||||
@ -6236,7 +5933,7 @@ class MyCompiler: public Compiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual Operand* pop(unsigned footprint) {
|
virtual Operand* pop(unsigned footprint) {
|
||||||
return local::pop(&c, footprint);
|
return compiler::pop(&c, footprint);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void pushed() {
|
virtual void pushed() {
|
||||||
@ -6245,7 +5942,7 @@ class MyCompiler: public Compiler {
|
|||||||
(&c, v, frameIndex
|
(&c, v, frameIndex
|
||||||
(&c, (c.stack ? c.stack->index : 0) + c.localFootprint));
|
(&c, (c.stack ? c.stack->index : 0) + c.localFootprint));
|
||||||
|
|
||||||
Stack* s = local::stack(&c, v, c.stack);
|
Stack* s = compiler::stack(&c, v, c.stack);
|
||||||
v->home = frameIndex(&c, s->index + c.localFootprint);
|
v->home = frameIndex(&c, s->index + c.localFootprint);
|
||||||
c.stack = s;
|
c.stack = s;
|
||||||
}
|
}
|
||||||
@ -6340,7 +6037,7 @@ class MyCompiler: public Compiler {
|
|||||||
|
|
||||||
Stack* argumentStack = c.stack;
|
Stack* argumentStack = c.stack;
|
||||||
for (int i = index - 1; i >= 0; --i) {
|
for (int i = index - 1; i >= 0; --i) {
|
||||||
argumentStack = local::stack
|
argumentStack = compiler::stack
|
||||||
(&c, RUNTIME_ARRAY_BODY(arguments)[i], argumentStack);
|
(&c, RUNTIME_ARRAY_BODY(arguments)[i], argumentStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6431,11 +6128,11 @@ class MyCompiler: public Compiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void storeLocal(unsigned footprint, Operand* src, unsigned index) {
|
virtual void storeLocal(unsigned footprint, Operand* src, unsigned index) {
|
||||||
local::storeLocal(&c, footprint, static_cast<Value*>(src), index, true);
|
compiler::storeLocal(&c, footprint, static_cast<Value*>(src), index, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Operand* loadLocal(unsigned footprint, unsigned index) {
|
virtual Operand* loadLocal(unsigned footprint, unsigned index) {
|
||||||
return local::loadLocal(&c, footprint, index);
|
return compiler::loadLocal(&c, footprint, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void saveLocals() {
|
virtual void saveLocals() {
|
||||||
@ -6872,7 +6569,7 @@ class MyCompiler: public Compiler {
|
|||||||
virtual void compile(uintptr_t stackOverflowHandler,
|
virtual void compile(uintptr_t stackOverflowHandler,
|
||||||
unsigned stackLimitOffset)
|
unsigned stackLimitOffset)
|
||||||
{
|
{
|
||||||
local::compile(&c, stackOverflowHandler, stackLimitOffset);
|
compiler::compile(&c, stackOverflowHandler, stackLimitOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual unsigned resolve(uint8_t* dst) {
|
virtual unsigned resolve(uint8_t* dst) {
|
||||||
@ -6934,21 +6631,16 @@ class MyCompiler: public Compiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Context c;
|
Context c;
|
||||||
local::Client client;
|
compiler::Client client;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace local
|
} // namespace compiler
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
namespace avian {
|
|
||||||
namespace codegen {
|
|
||||||
|
|
||||||
Compiler*
|
Compiler*
|
||||||
makeCompiler(System* system, Assembler* assembler, Zone* zone,
|
makeCompiler(System* system, Assembler* assembler, Zone* zone,
|
||||||
Compiler::Client* client)
|
Compiler::Client* client)
|
||||||
{
|
{
|
||||||
return new(zone) local::MyCompiler(system, assembler, zone, client);
|
return new(zone) compiler::MyCompiler(system, assembler, zone, client);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace codegen
|
} // namespace codegen
|
||||||
|
68
src/codegen/compiler/context.cpp
Normal file
68
src/codegen/compiler/context.cpp
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/* Copyright (c) 2008-2012, 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 "codegen/compiler/context.h"
|
||||||
|
#include "codegen/compiler/resource.h"
|
||||||
|
|
||||||
|
namespace avian {
|
||||||
|
namespace codegen {
|
||||||
|
namespace compiler {
|
||||||
|
|
||||||
|
Context::Context(vm::System* system, Assembler* assembler, vm::Zone* zone,
|
||||||
|
Compiler::Client* client):
|
||||||
|
system(system),
|
||||||
|
assembler(assembler),
|
||||||
|
arch(assembler->arch()),
|
||||||
|
zone(zone),
|
||||||
|
client(client),
|
||||||
|
stack(0),
|
||||||
|
locals(0),
|
||||||
|
saved(0),
|
||||||
|
predecessor(0),
|
||||||
|
logicalCode(0),
|
||||||
|
regFile(arch->registerFile()),
|
||||||
|
regAlloc(system, arch->registerFile()),
|
||||||
|
registerResources
|
||||||
|
(static_cast<RegisterResource*>
|
||||||
|
(zone->allocate(sizeof(RegisterResource) * regFile->allRegisters.limit))),
|
||||||
|
frameResources(0),
|
||||||
|
acquiredResources(0),
|
||||||
|
firstConstant(0),
|
||||||
|
lastConstant(0),
|
||||||
|
machineCode(0),
|
||||||
|
firstEvent(0),
|
||||||
|
lastEvent(0),
|
||||||
|
forkState(0),
|
||||||
|
subroutine(0),
|
||||||
|
firstBlock(0),
|
||||||
|
logicalIp(-1),
|
||||||
|
constantCount(0),
|
||||||
|
logicalCodeLength(0),
|
||||||
|
parameterFootprint(0),
|
||||||
|
localFootprint(0),
|
||||||
|
machineCodeSize(0),
|
||||||
|
alignedFrameSize(0),
|
||||||
|
availableGeneralRegisterCount(regFile->generalRegisters.limit - regFile->generalRegisters.start)
|
||||||
|
{
|
||||||
|
for (unsigned i = regFile->generalRegisters.start; i < regFile->generalRegisters.limit; ++i) {
|
||||||
|
new (registerResources + i) RegisterResource(arch->reserved(i));
|
||||||
|
|
||||||
|
if (registerResources[i].reserved) {
|
||||||
|
-- availableGeneralRegisterCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (unsigned i = regFile->floatRegisters.start; i < regFile->floatRegisters.limit; ++i) {
|
||||||
|
new (registerResources + i) RegisterResource(arch->reserved(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace compiler
|
||||||
|
} // namespace codegen
|
||||||
|
} // namespace avian
|
84
src/codegen/compiler/context.h
Normal file
84
src/codegen/compiler/context.h
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
/* Copyright (c) 2008-2012, 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. */
|
||||||
|
|
||||||
|
#ifndef AVIAN_CODEGEN_COMPILER_CONTEXT_H
|
||||||
|
#define AVIAN_CODEGEN_COMPILER_CONTEXT_H
|
||||||
|
|
||||||
|
#include "codegen/assembler.h"
|
||||||
|
#include "codegen/regalloc.h"
|
||||||
|
#include "codegen/compiler.h"
|
||||||
|
|
||||||
|
namespace avian {
|
||||||
|
namespace codegen {
|
||||||
|
namespace compiler {
|
||||||
|
|
||||||
|
class Stack;
|
||||||
|
class Local;
|
||||||
|
class Cell;
|
||||||
|
class Event;
|
||||||
|
class LogicalInstruction;
|
||||||
|
|
||||||
|
class Resource;
|
||||||
|
class RegisterResource;
|
||||||
|
class FrameResource;
|
||||||
|
|
||||||
|
class ConstantPoolNode;
|
||||||
|
|
||||||
|
class ForkState;
|
||||||
|
class MySubroutine;
|
||||||
|
class Block;
|
||||||
|
|
||||||
|
class Context {
|
||||||
|
public:
|
||||||
|
Context(vm::System* system, Assembler* assembler, vm::Zone* zone,
|
||||||
|
Compiler::Client* client);
|
||||||
|
|
||||||
|
vm::System* system;
|
||||||
|
Assembler* assembler;
|
||||||
|
Assembler::Architecture* arch;
|
||||||
|
vm::Zone* zone;
|
||||||
|
Compiler::Client* client;
|
||||||
|
Stack* stack;
|
||||||
|
Local* locals;
|
||||||
|
Cell* saved;
|
||||||
|
Event* predecessor;
|
||||||
|
LogicalInstruction** logicalCode;
|
||||||
|
const RegisterFile* regFile;
|
||||||
|
regalloc::RegisterAllocator regAlloc;
|
||||||
|
RegisterResource* registerResources;
|
||||||
|
FrameResource* frameResources;
|
||||||
|
Resource* acquiredResources;
|
||||||
|
ConstantPoolNode* firstConstant;
|
||||||
|
ConstantPoolNode* lastConstant;
|
||||||
|
uint8_t* machineCode;
|
||||||
|
Event* firstEvent;
|
||||||
|
Event* lastEvent;
|
||||||
|
ForkState* forkState;
|
||||||
|
MySubroutine* subroutine;
|
||||||
|
Block* firstBlock;
|
||||||
|
int logicalIp;
|
||||||
|
unsigned constantCount;
|
||||||
|
unsigned logicalCodeLength;
|
||||||
|
unsigned parameterFootprint;
|
||||||
|
unsigned localFootprint;
|
||||||
|
unsigned machineCodeSize;
|
||||||
|
unsigned alignedFrameSize;
|
||||||
|
unsigned availableGeneralRegisterCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline Aborter* getAborter(Context* c) {
|
||||||
|
return c->system;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace compiler
|
||||||
|
} // namespace codegen
|
||||||
|
} // namespace avian
|
||||||
|
|
||||||
|
#endif // AVIAN_CODEGEN_COMPILER_CONTEXT_H
|
152
src/codegen/compiler/resource.cpp
Normal file
152
src/codegen/compiler/resource.cpp
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
/* Copyright (c) 2008-2012, 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 "codegen/compiler/context.h"
|
||||||
|
#include "codegen/compiler/resource.h"
|
||||||
|
|
||||||
|
namespace avian {
|
||||||
|
namespace codegen {
|
||||||
|
namespace compiler {
|
||||||
|
|
||||||
|
const bool DebugResources = false;
|
||||||
|
|
||||||
|
void decrementAvailableGeneralRegisterCount(Context* c) {
|
||||||
|
assert(c, c->availableGeneralRegisterCount);
|
||||||
|
-- c->availableGeneralRegisterCount;
|
||||||
|
|
||||||
|
if (DebugResources) {
|
||||||
|
fprintf(stderr, "%d registers available\n",
|
||||||
|
c->availableGeneralRegisterCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void incrementAvailableGeneralRegisterCount(Context* c) {
|
||||||
|
++ c->availableGeneralRegisterCount;
|
||||||
|
|
||||||
|
if (DebugResources) {
|
||||||
|
fprintf(stderr, "%d registers available\n",
|
||||||
|
c->availableGeneralRegisterCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void freezeResource(Context* c, Resource* r, Value* v) {
|
||||||
|
if (DebugResources) {
|
||||||
|
char buffer[256]; r->toString(c, buffer, 256);
|
||||||
|
fprintf(stderr, "%p freeze %s to %d\n", v, buffer, r->freezeCount + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
++ r->freezeCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void thawResource(Context* c, Resource* r, Value* v) {
|
||||||
|
if (not r->reserved) {
|
||||||
|
if (DebugResources) {
|
||||||
|
char buffer[256]; r->toString(c, buffer, 256);
|
||||||
|
fprintf(stderr, "%p thaw %s to %d\n", v, buffer, r->freezeCount - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(c, r->freezeCount);
|
||||||
|
|
||||||
|
-- r->freezeCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void RegisterResource::freeze(Context* c, Value* v) {
|
||||||
|
if (not reserved) {
|
||||||
|
freezeResource(c, this, v);
|
||||||
|
|
||||||
|
if (freezeCount == 1
|
||||||
|
and ((1 << index(c)) & c->regFile->generalRegisters.mask))
|
||||||
|
{
|
||||||
|
decrementAvailableGeneralRegisterCount(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterResource::thaw(Context* c, Value* v) {
|
||||||
|
if (not reserved) {
|
||||||
|
thawResource(c, this, v);
|
||||||
|
|
||||||
|
if (freezeCount == 0
|
||||||
|
and ((1 << index(c)) & c->regFile->generalRegisters.mask))
|
||||||
|
{
|
||||||
|
incrementAvailableGeneralRegisterCount(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned RegisterResource::toString(Context* c, char* buffer, unsigned bufferSize) {
|
||||||
|
return vm::snprintf(buffer, bufferSize, "register %d", index(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned RegisterResource::index(Context* c) {
|
||||||
|
return this - c->registerResources;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterResource::increment(Context* c) {
|
||||||
|
if (not this->reserved) {
|
||||||
|
if (DebugResources) {
|
||||||
|
char buffer[256]; this->toString(c, buffer, 256);
|
||||||
|
fprintf(stderr, "increment %s to %d\n", buffer, this->referenceCount + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
++ this->referenceCount;
|
||||||
|
|
||||||
|
if (this->referenceCount == 1
|
||||||
|
and ((1 << this->index(c)) & c->regFile->generalRegisters.mask))
|
||||||
|
{
|
||||||
|
decrementAvailableGeneralRegisterCount(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterResource::decrement(Context* c) {
|
||||||
|
if (not this->reserved) {
|
||||||
|
if (DebugResources) {
|
||||||
|
char buffer[256]; this->toString(c, buffer, 256);
|
||||||
|
fprintf(stderr, "decrement %s to %d\n", buffer, this->referenceCount - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(c, this->referenceCount > 0);
|
||||||
|
|
||||||
|
-- this->referenceCount;
|
||||||
|
|
||||||
|
if (this->referenceCount == 0
|
||||||
|
and ((1 << this->index(c)) & c->regFile->generalRegisters.mask))
|
||||||
|
{
|
||||||
|
incrementAvailableGeneralRegisterCount(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void FrameResource::freeze(Context* c, Value* v) {
|
||||||
|
freezeResource(c, this, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FrameResource::thaw(Context* c, Value* v) {
|
||||||
|
thawResource(c, this, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned FrameResource::toString(Context* c, char* buffer, unsigned bufferSize) {
|
||||||
|
return vm::snprintf(buffer, bufferSize, "frame %d", index(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned FrameResource::index(Context* c) {
|
||||||
|
return this - c->frameResources;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace compiler
|
||||||
|
} // namespace codegen
|
||||||
|
} // namespace avian
|
79
src/codegen/compiler/resource.h
Normal file
79
src/codegen/compiler/resource.h
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
/* Copyright (c) 2008-2012, 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. */
|
||||||
|
|
||||||
|
#ifndef AVIAN_CODEGEN_COMPILER_RESOURCE_H
|
||||||
|
#define AVIAN_CODEGEN_COMPILER_RESOURCE_H
|
||||||
|
|
||||||
|
#include "codegen/compiler/context.h"
|
||||||
|
|
||||||
|
namespace avian {
|
||||||
|
namespace codegen {
|
||||||
|
namespace compiler {
|
||||||
|
|
||||||
|
class Value;
|
||||||
|
class Site;
|
||||||
|
|
||||||
|
class Resource {
|
||||||
|
public:
|
||||||
|
Resource(bool reserved = false):
|
||||||
|
value(0), site(0), previousAcquired(0), nextAcquired(0), freezeCount(0),
|
||||||
|
referenceCount(0), reserved(reserved)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual void freeze(Context*, Value*) = 0;
|
||||||
|
|
||||||
|
virtual void thaw(Context*, Value*) = 0;
|
||||||
|
|
||||||
|
virtual unsigned toString(Context*, char*, unsigned) = 0;
|
||||||
|
|
||||||
|
Value* value;
|
||||||
|
Site* site;
|
||||||
|
Resource* previousAcquired;
|
||||||
|
Resource* nextAcquired;
|
||||||
|
uint8_t freezeCount;
|
||||||
|
uint8_t referenceCount;
|
||||||
|
bool reserved;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RegisterResource: public Resource {
|
||||||
|
public:
|
||||||
|
RegisterResource(bool reserved):
|
||||||
|
Resource(reserved)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual void freeze(Context*, Value*);
|
||||||
|
|
||||||
|
virtual void thaw(Context*, Value*);
|
||||||
|
|
||||||
|
virtual unsigned toString(Context* c, char* buffer, unsigned bufferSize);
|
||||||
|
|
||||||
|
virtual unsigned index(Context*);
|
||||||
|
|
||||||
|
void increment(Context*);
|
||||||
|
|
||||||
|
void decrement(Context*);
|
||||||
|
};
|
||||||
|
|
||||||
|
class FrameResource: public Resource {
|
||||||
|
public:
|
||||||
|
virtual void freeze(Context*, Value*);
|
||||||
|
|
||||||
|
virtual void thaw(Context*, Value*);
|
||||||
|
|
||||||
|
virtual unsigned toString(Context* c, char* buffer, unsigned bufferSize);
|
||||||
|
|
||||||
|
virtual unsigned index(Context*);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace compiler
|
||||||
|
} // namespace codegen
|
||||||
|
} // namespace avian
|
||||||
|
|
||||||
|
#endif // AVIAN_CODEGEN_COMPILER_RESOURCE_H
|
49
src/codegen/compiler/value.h
Normal file
49
src/codegen/compiler/value.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/* Copyright (c) 2008-2012, 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. */
|
||||||
|
|
||||||
|
#ifndef AVIAN_CODEGEN_COMPILER_VALUE_H
|
||||||
|
#define AVIAN_CODEGEN_COMPILER_VALUE_H
|
||||||
|
|
||||||
|
#include "codegen/lir.h"
|
||||||
|
|
||||||
|
namespace avian {
|
||||||
|
namespace codegen {
|
||||||
|
namespace compiler {
|
||||||
|
|
||||||
|
class Read;
|
||||||
|
class Site;
|
||||||
|
|
||||||
|
const int AnyFrameIndex = -2;
|
||||||
|
const int NoFrameIndex = -1;
|
||||||
|
|
||||||
|
class Value: public Compiler::Operand {
|
||||||
|
public:
|
||||||
|
Value(Site* site, Site* target, lir::ValueType type):
|
||||||
|
reads(0), lastRead(0), sites(site), source(0), target(target), buddy(this),
|
||||||
|
nextWord(this), home(NoFrameIndex), type(type), wordIndex(0)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
Read* reads;
|
||||||
|
Read* lastRead;
|
||||||
|
Site* sites;
|
||||||
|
Site* source;
|
||||||
|
Site* target;
|
||||||
|
Value* buddy;
|
||||||
|
Value* nextWord;
|
||||||
|
int16_t home;
|
||||||
|
lir::ValueType type;
|
||||||
|
uint8_t wordIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace compiler
|
||||||
|
} // namespace codegen
|
||||||
|
} // namespace avian
|
||||||
|
|
||||||
|
#endif // AVIAN_CODEGEN_COMPILER_VALUE_H
|
Loading…
x
Reference in New Issue
Block a user