begin splitting up compiler.cpp

This commit is contained in:
Joshua Warner 2013-02-13 12:11:47 -07:00 committed by Joshua Warner
parent ef5e534e1e
commit 740886d58e
7 changed files with 487 additions and 361 deletions

View File

@ -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

View File

@ -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

View 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

View 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

View 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

View 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

View 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