mirror of
https://github.com/corda/corda.git
synced 2025-01-06 05:04:20 +00:00
further compiler cleanup / organization
This commit is contained in:
parent
a7ab59f1f6
commit
2db0303e2f
1
makefile
1
makefile
@ -962,6 +962,7 @@ ifeq ($(process),compile)
|
|||||||
$(src)/codegen/compiler/event.cpp \
|
$(src)/codegen/compiler/event.cpp \
|
||||||
$(src)/codegen/compiler/promise.cpp \
|
$(src)/codegen/compiler/promise.cpp \
|
||||||
$(src)/codegen/compiler/frame.cpp \
|
$(src)/codegen/compiler/frame.cpp \
|
||||||
|
$(src)/codegen/compiler/ir.cpp \
|
||||||
$(src)/codegen/registers.cpp \
|
$(src)/codegen/registers.cpp \
|
||||||
$(src)/codegen/targets.cpp
|
$(src)/codegen/targets.cpp
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "codegen/compiler/event.h"
|
#include "codegen/compiler/event.h"
|
||||||
#include "codegen/compiler/promise.h"
|
#include "codegen/compiler/promise.h"
|
||||||
#include "codegen/compiler/frame.h"
|
#include "codegen/compiler/frame.h"
|
||||||
|
#include "codegen/compiler/ir.h"
|
||||||
|
|
||||||
using namespace vm;
|
using namespace vm;
|
||||||
|
|
||||||
@ -45,14 +46,6 @@ const unsigned StealRegisterReserveCount = 2;
|
|||||||
// compare instruction:
|
// compare instruction:
|
||||||
const unsigned ResolveRegisterReserveCount = (TargetBytesPerWord == 8 ? 2 : 4);
|
const unsigned ResolveRegisterReserveCount = (TargetBytesPerWord == 8 ? 2 : 4);
|
||||||
|
|
||||||
class Stack;
|
|
||||||
class PushEvent;
|
|
||||||
class Read;
|
|
||||||
class MultiRead;
|
|
||||||
class StubRead;
|
|
||||||
class Block;
|
|
||||||
class Snapshot;
|
|
||||||
|
|
||||||
void
|
void
|
||||||
apply(Context* c, lir::UnaryOperation op,
|
apply(Context* c, lir::UnaryOperation op,
|
||||||
unsigned s1Size, Site* s1Low, Site* s1High);
|
unsigned s1Size, Site* s1Low, Site* s1High);
|
||||||
@ -68,57 +61,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);
|
||||||
|
|
||||||
class ForkElement {
|
|
||||||
public:
|
|
||||||
Value* value;
|
|
||||||
MultiRead* read;
|
|
||||||
bool local;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ForkState: public Compiler::State {
|
|
||||||
public:
|
|
||||||
ForkState(Stack* stack, Local* locals, Cell<Value>* saved, Event* predecessor,
|
|
||||||
unsigned logicalIp):
|
|
||||||
stack(stack),
|
|
||||||
locals(locals),
|
|
||||||
saved(saved),
|
|
||||||
predecessor(predecessor),
|
|
||||||
logicalIp(logicalIp),
|
|
||||||
readCount(0)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
Stack* stack;
|
|
||||||
Local* locals;
|
|
||||||
Cell<Value>* saved;
|
|
||||||
Event* predecessor;
|
|
||||||
unsigned logicalIp;
|
|
||||||
unsigned readCount;
|
|
||||||
ForkElement elements[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
class MySubroutine: public Compiler::Subroutine {
|
|
||||||
public:
|
|
||||||
MySubroutine(): forkState(0) { }
|
|
||||||
|
|
||||||
ForkState* forkState;
|
|
||||||
};
|
|
||||||
|
|
||||||
class LogicalInstruction {
|
|
||||||
public:
|
|
||||||
LogicalInstruction(int index, Stack* stack, Local* locals):
|
|
||||||
firstEvent(0), lastEvent(0), immediatePredecessor(0), stack(stack),
|
|
||||||
locals(locals), machineOffset(0), subroutine(0), index(index)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
Event* firstEvent;
|
|
||||||
Event* lastEvent;
|
|
||||||
LogicalInstruction* immediatePredecessor;
|
|
||||||
Stack* stack;
|
|
||||||
Local* locals;
|
|
||||||
Promise* machineOffset;
|
|
||||||
MySubroutine* subroutine;
|
|
||||||
int index;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ConstantPoolNode {
|
class ConstantPoolNode {
|
||||||
public:
|
public:
|
||||||
@ -128,106 +70,6 @@ class ConstantPoolNode {
|
|||||||
ConstantPoolNode* next;
|
ConstantPoolNode* next;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PoolPromise: public Promise {
|
|
||||||
public:
|
|
||||||
PoolPromise(Context* c, int key): c(c), key(key) { }
|
|
||||||
|
|
||||||
virtual int64_t value() {
|
|
||||||
if (resolved()) {
|
|
||||||
return reinterpret_cast<int64_t>
|
|
||||||
(c->machineCode + pad(c->machineCodeSize, TargetBytesPerWord)
|
|
||||||
+ (key * TargetBytesPerWord));
|
|
||||||
}
|
|
||||||
|
|
||||||
abort(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool resolved() {
|
|
||||||
return c->machineCode != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Context* c;
|
|
||||||
int key;
|
|
||||||
};
|
|
||||||
|
|
||||||
unsigned
|
|
||||||
machineOffset(Context* c, int logicalIp)
|
|
||||||
{
|
|
||||||
return c->logicalCode[logicalIp]->machineOffset->value();
|
|
||||||
}
|
|
||||||
|
|
||||||
class IpPromise: public Promise {
|
|
||||||
public:
|
|
||||||
IpPromise(Context* c, int logicalIp):
|
|
||||||
c(c),
|
|
||||||
logicalIp(logicalIp)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
virtual int64_t value() {
|
|
||||||
if (resolved()) {
|
|
||||||
return reinterpret_cast<intptr_t>
|
|
||||||
(c->machineCode + machineOffset(c, logicalIp));
|
|
||||||
}
|
|
||||||
|
|
||||||
abort(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool resolved() {
|
|
||||||
return c->machineCode != 0
|
|
||||||
and c->logicalCode[logicalIp]->machineOffset->resolved();
|
|
||||||
}
|
|
||||||
|
|
||||||
Context* c;
|
|
||||||
int logicalIp;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
Cell<T>* reverseDestroy(Cell<T>* cell) {
|
|
||||||
Cell<T>* previous = 0;
|
|
||||||
while (cell) {
|
|
||||||
Cell<T>* next = cell->next;
|
|
||||||
cell->next = previous;
|
|
||||||
previous = cell;
|
|
||||||
cell = next;
|
|
||||||
}
|
|
||||||
return previous;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned
|
|
||||||
countPredecessors(Link* link)
|
|
||||||
{
|
|
||||||
unsigned c = 0;
|
|
||||||
for (; link; link = link->nextPredecessor) ++ c;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
Link*
|
|
||||||
lastPredecessor(Link* link)
|
|
||||||
{
|
|
||||||
while (link->nextPredecessor) link = link->nextPredecessor;
|
|
||||||
return link;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned
|
|
||||||
countSuccessors(Link* link)
|
|
||||||
{
|
|
||||||
unsigned c = 0;
|
|
||||||
for (; link; link = link->nextSuccessor) ++ c;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
clearSites(Context* c, Value* v)
|
|
||||||
{
|
|
||||||
if (DebugSites) {
|
|
||||||
fprintf(stderr, "clear sites for %p\n", v);
|
|
||||||
}
|
|
||||||
for (SiteIterator it(c, v); it.hasMore();) {
|
|
||||||
it.next();
|
|
||||||
it.remove(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Read*
|
Read*
|
||||||
live(Context* c UNUSED, Value* v)
|
live(Context* c UNUSED, Value* v)
|
||||||
{
|
{
|
||||||
@ -321,7 +163,7 @@ popRead(Context* c, Event* e UNUSED, Value* v)
|
|||||||
if (r) {
|
if (r) {
|
||||||
deadBuddy(c, v, r);
|
deadBuddy(c, v, r);
|
||||||
} else {
|
} else {
|
||||||
clearSites(c, v);
|
v->clearSites(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1140,11 +982,11 @@ removeBuddy(Context* c, Value* v)
|
|||||||
assert(c, p->buddy);
|
assert(c, p->buddy);
|
||||||
|
|
||||||
if (not live(c, next)) {
|
if (not live(c, next)) {
|
||||||
clearSites(c, next);
|
next->clearSites(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (not live(c, v)) {
|
if (not live(c, v)) {
|
||||||
clearSites(c, v);
|
v->clearSites(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1437,7 +1279,7 @@ visit(Context* c, Link* link)
|
|||||||
v->reads = p->read->nextTarget();
|
v->reads = p->read->nextTarget();
|
||||||
// fprintf(stderr, "next read %p for %p from %p\n", v->reads, v, p->read);
|
// fprintf(stderr, "next read %p for %p from %p\n", v->reads, v, p->read);
|
||||||
if (not live(c, v)) {
|
if (not live(c, v)) {
|
||||||
clearSites(c, v);
|
v->clearSites(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1492,67 +1334,6 @@ appendBuddy(Context* c, Value* original, Value* buddy)
|
|||||||
append(c, new(c->zone) BuddyEvent(c, original, buddy));
|
append(c, new(c->zone) BuddyEvent(c, original, buddy));
|
||||||
}
|
}
|
||||||
|
|
||||||
class SaveLocalsEvent: public Event {
|
|
||||||
public:
|
|
||||||
SaveLocalsEvent(Context* c):
|
|
||||||
Event(c)
|
|
||||||
{
|
|
||||||
saveLocals(c, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual const char* name() {
|
|
||||||
return "SaveLocalsEvent";
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void compile(Context* c) {
|
|
||||||
for (Read* r = reads; r; r = r->eventNext) {
|
|
||||||
popRead(c, this, r->value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
|
||||||
appendSaveLocals(Context* c)
|
|
||||||
{
|
|
||||||
append(c, new(c->zone) SaveLocalsEvent(c));
|
|
||||||
}
|
|
||||||
|
|
||||||
class DummyEvent: public Event {
|
|
||||||
public:
|
|
||||||
DummyEvent(Context* c, Local* locals):
|
|
||||||
Event(c),
|
|
||||||
locals_(locals)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
virtual const char* name() {
|
|
||||||
return "DummyEvent";
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void compile(Context*) { }
|
|
||||||
|
|
||||||
virtual Local* locals() {
|
|
||||||
return locals_;
|
|
||||||
}
|
|
||||||
|
|
||||||
Local* locals_;
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
|
||||||
appendDummy(Context* c)
|
|
||||||
{
|
|
||||||
Stack* stack = c->stack;
|
|
||||||
Local* locals = c->locals;
|
|
||||||
LogicalInstruction* i = c->logicalCode[c->logicalIp];
|
|
||||||
|
|
||||||
c->stack = i->stack;
|
|
||||||
c->locals = i->locals;
|
|
||||||
|
|
||||||
append(c, new(c->zone) DummyEvent(c, locals));
|
|
||||||
|
|
||||||
c->stack = stack;
|
|
||||||
c->locals = locals;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
append(Context* c, Event* e)
|
append(Context* c, Event* e)
|
||||||
{
|
{
|
||||||
@ -1898,11 +1679,11 @@ resetFrame(Context* c, Event* e)
|
|||||||
{
|
{
|
||||||
for (FrameIterator it(c, e->stackBefore, e->localsBefore); it.hasMore();) {
|
for (FrameIterator it(c, e->stackBefore, e->localsBefore); it.hasMore();) {
|
||||||
FrameIterator::Element el = it.next(c);
|
FrameIterator::Element el = it.next(c);
|
||||||
clearSites(c, el.value);
|
el.value->clearSites(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (c->acquiredResources) {
|
while (c->acquiredResources) {
|
||||||
clearSites(c, c->acquiredResources->value);
|
c->acquiredResources->value->clearSites(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2058,35 +1839,6 @@ updateJunctionReads(Context* c, JunctionState* state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LogicalInstruction*
|
|
||||||
next(Context* c, LogicalInstruction* i)
|
|
||||||
{
|
|
||||||
for (unsigned n = i->index + 1; n < c->logicalCodeLength; ++n) {
|
|
||||||
i = c->logicalCode[n];
|
|
||||||
if (i) return i;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
class Block {
|
|
||||||
public:
|
|
||||||
Block(Event* head):
|
|
||||||
head(head), nextBlock(0), nextInstruction(0), assemblerBlock(0), start(0)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
Event* head;
|
|
||||||
Block* nextBlock;
|
|
||||||
LogicalInstruction* nextInstruction;
|
|
||||||
Assembler::Block* assemblerBlock;
|
|
||||||
unsigned start;
|
|
||||||
};
|
|
||||||
|
|
||||||
Block*
|
|
||||||
block(Context* c, Event* head)
|
|
||||||
{
|
|
||||||
return new(c->zone) Block(head);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
compile(Context* c, uintptr_t stackOverflowHandler, unsigned stackLimitOffset)
|
compile(Context* c, uintptr_t stackOverflowHandler, unsigned stackLimitOffset)
|
||||||
{
|
{
|
||||||
@ -2110,8 +1862,8 @@ compile(Context* c, uintptr_t stackOverflowHandler, unsigned stackLimitOffset)
|
|||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
" -- compile %s at %d with %d preds %d succs %d stack\n",
|
" -- compile %s at %d with %d preds %d succs %d stack\n",
|
||||||
e->name(), e->logicalInstruction->index,
|
e->name(), e->logicalInstruction->index,
|
||||||
countPredecessors(e->predecessors),
|
e->predecessors->countPredecessors(),
|
||||||
countSuccessors(e->successors),
|
e->successors->countSuccessors(),
|
||||||
e->stackBefore ? e->stackBefore->index + 1 : 0);
|
e->stackBefore ? e->stackBefore->index + 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2125,7 +1877,7 @@ compile(Context* c, uintptr_t stackOverflowHandler, unsigned stackLimitOffset)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (e->predecessors) {
|
if (e->predecessors) {
|
||||||
visit(c, lastPredecessor(e->predecessors));
|
visit(c, e->predecessors->lastPredecessor());
|
||||||
|
|
||||||
Event* first = e->predecessors->predecessor;
|
Event* first = e->predecessors->predecessor;
|
||||||
if (e->predecessors->nextPredecessor) {
|
if (e->predecessors->nextPredecessor) {
|
||||||
@ -2191,7 +1943,7 @@ compile(Context* c, uintptr_t stackOverflowHandler, unsigned stackLimitOffset)
|
|||||||
|
|
||||||
a->endEvent();
|
a->endEvent();
|
||||||
|
|
||||||
LogicalInstruction* nextInstruction = next(c, e->logicalInstruction);
|
LogicalInstruction* nextInstruction = e->logicalInstruction->next(c);
|
||||||
if (e->next == 0
|
if (e->next == 0
|
||||||
or (e->next->logicalInstruction != e->logicalInstruction
|
or (e->next->logicalInstruction != e->logicalInstruction
|
||||||
and (e->next->logicalInstruction != nextInstruction
|
and (e->next->logicalInstruction != nextInstruction
|
||||||
@ -2433,9 +2185,7 @@ class MyCompiler: public Compiler {
|
|||||||
|
|
||||||
memset(c.locals, 0, sizeof(Local) * localFootprint);
|
memset(c.locals, 0, sizeof(Local) * localFootprint);
|
||||||
|
|
||||||
c.logicalCode[-1] = new
|
c.logicalCode[-1] = new(c.zone) LogicalInstruction(-1, c.stack, c.locals);
|
||||||
(c.zone->allocate(sizeof(LogicalInstruction)))
|
|
||||||
LogicalInstruction(-1, c.stack, c.locals);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void visitLogicalIp(unsigned logicalIp) {
|
virtual void visitLogicalIp(unsigned logicalIp) {
|
||||||
@ -2494,9 +2244,7 @@ class MyCompiler: public Compiler {
|
|||||||
p->localsAfter = c.locals;
|
p->localsAfter = c.locals;
|
||||||
}
|
}
|
||||||
|
|
||||||
c.logicalCode[logicalIp] = new
|
c.logicalCode[logicalIp] = new(c.zone) LogicalInstruction(logicalIp, c.stack, c.locals);
|
||||||
(c.zone->allocate(sizeof(LogicalInstruction)))
|
|
||||||
LogicalInstruction(logicalIp, c.stack, c.locals);
|
|
||||||
|
|
||||||
bool startSubroutine = c.subroutine != 0;
|
bool startSubroutine = c.subroutine != 0;
|
||||||
if (startSubroutine) {
|
if (startSubroutine) {
|
||||||
@ -2525,7 +2273,7 @@ class MyCompiler: public Compiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual Promise* machineIp(unsigned logicalIp) {
|
virtual Promise* machineIp(unsigned logicalIp) {
|
||||||
return new(c.zone) IpPromise(&c, logicalIp);
|
return ipPromise(&c, logicalIp);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Promise* poolAppend(intptr_t value) {
|
virtual Promise* poolAppend(intptr_t value) {
|
||||||
@ -2533,7 +2281,7 @@ class MyCompiler: public Compiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual Promise* poolAppendPromise(Promise* value) {
|
virtual Promise* poolAppendPromise(Promise* value) {
|
||||||
Promise* p = new(c.zone) PoolPromise(&c, c.constantCount);
|
Promise* p = poolPromise(&c, c.constantCount);
|
||||||
|
|
||||||
ConstantPoolNode* constant = new (c.zone) ConstantPoolNode(value);
|
ConstantPoolNode* constant = new (c.zone) ConstantPoolNode(value);
|
||||||
|
|
||||||
|
@ -54,6 +54,18 @@ unsigned count(Cell<T>* c) {
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
Cell<T>* reverseDestroy(Cell<T>* cell) {
|
||||||
|
Cell<T>* previous = 0;
|
||||||
|
while (cell) {
|
||||||
|
Cell<T>* next = cell->next;
|
||||||
|
cell->next = previous;
|
||||||
|
previous = cell;
|
||||||
|
cell = next;
|
||||||
|
}
|
||||||
|
return previous;
|
||||||
|
}
|
||||||
|
|
||||||
class Context {
|
class Context {
|
||||||
public:
|
public:
|
||||||
Context(vm::System* system, Assembler* assembler, vm::Zone* zone,
|
Context(vm::System* system, Assembler* assembler, vm::Zone* zone,
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "codegen/compiler/value.h"
|
#include "codegen/compiler/value.h"
|
||||||
#include "codegen/compiler/promise.h"
|
#include "codegen/compiler/promise.h"
|
||||||
#include "codegen/compiler/frame.h"
|
#include "codegen/compiler/frame.h"
|
||||||
|
#include "codegen/compiler/ir.h"
|
||||||
|
|
||||||
namespace avian {
|
namespace avian {
|
||||||
namespace codegen {
|
namespace codegen {
|
||||||
@ -148,6 +149,32 @@ bool Event::isUnreachable() {
|
|||||||
return this->predecessors != 0;
|
return this->predecessors != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned Link::countPredecessors() {
|
||||||
|
Link* link = this;
|
||||||
|
unsigned c = 0;
|
||||||
|
for (; link; link = link->nextPredecessor) {
|
||||||
|
++ c;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
Link* Link::lastPredecessor() {
|
||||||
|
Link* link = this;
|
||||||
|
while (link->nextPredecessor) {
|
||||||
|
link = link->nextPredecessor;
|
||||||
|
}
|
||||||
|
return link;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned Link::countSuccessors() {
|
||||||
|
Link* link = this;
|
||||||
|
unsigned c = 0;
|
||||||
|
for (; link; link = link->nextSuccessor) {
|
||||||
|
++ c;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
Link* link(Context* c, Event* predecessor, Link* nextPredecessor, Event* successor,
|
Link* link(Context* c, Event* predecessor, Link* nextPredecessor, Event* successor,
|
||||||
Link* nextSuccessor, ForkState* forkState)
|
Link* nextSuccessor, ForkState* forkState)
|
||||||
{
|
{
|
||||||
@ -1605,6 +1632,67 @@ appendFrameSite(Context* c, Value* value, int index)
|
|||||||
append(c, new(c->zone) FrameSiteEvent(c, value, index));
|
append(c, new(c->zone) FrameSiteEvent(c, value, index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SaveLocalsEvent: public Event {
|
||||||
|
public:
|
||||||
|
SaveLocalsEvent(Context* c):
|
||||||
|
Event(c)
|
||||||
|
{
|
||||||
|
saveLocals(c, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const char* name() {
|
||||||
|
return "SaveLocalsEvent";
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void compile(Context* c) {
|
||||||
|
for (Read* r = reads; r; r = r->eventNext) {
|
||||||
|
popRead(c, this, r->value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
appendSaveLocals(Context* c)
|
||||||
|
{
|
||||||
|
append(c, new(c->zone) SaveLocalsEvent(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
class DummyEvent: public Event {
|
||||||
|
public:
|
||||||
|
DummyEvent(Context* c, Local* locals):
|
||||||
|
Event(c),
|
||||||
|
locals_(locals)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual const char* name() {
|
||||||
|
return "DummyEvent";
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void compile(Context*) { }
|
||||||
|
|
||||||
|
virtual Local* locals() {
|
||||||
|
return locals_;
|
||||||
|
}
|
||||||
|
|
||||||
|
Local* locals_;
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
appendDummy(Context* c)
|
||||||
|
{
|
||||||
|
Stack* stack = c->stack;
|
||||||
|
Local* locals = c->locals;
|
||||||
|
LogicalInstruction* i = c->logicalCode[c->logicalIp];
|
||||||
|
|
||||||
|
c->stack = i->stack;
|
||||||
|
c->locals = i->locals;
|
||||||
|
|
||||||
|
append(c, new(c->zone) DummyEvent(c, locals));
|
||||||
|
|
||||||
|
c->stack = stack;
|
||||||
|
c->locals = locals;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace compiler
|
} // namespace compiler
|
||||||
} // namespace codegen
|
} // namespace codegen
|
||||||
} // namespace avian
|
} // namespace avian
|
||||||
|
@ -97,6 +97,10 @@ class Link {
|
|||||||
junctionState(0)
|
junctionState(0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
unsigned countPredecessors();
|
||||||
|
Link* lastPredecessor();
|
||||||
|
unsigned countSuccessors();
|
||||||
|
|
||||||
Event* predecessor;
|
Event* predecessor;
|
||||||
Link* nextPredecessor;
|
Link* nextPredecessor;
|
||||||
Event* successor;
|
Event* successor;
|
||||||
@ -154,6 +158,12 @@ appendBoundsCheck(Context* c, Value* object, unsigned lengthOffset,
|
|||||||
void
|
void
|
||||||
appendFrameSite(Context* c, Value* value, int index);
|
appendFrameSite(Context* c, Value* value, int index);
|
||||||
|
|
||||||
|
void
|
||||||
|
appendSaveLocals(Context* c);
|
||||||
|
|
||||||
|
void
|
||||||
|
appendDummy(Context* c);
|
||||||
|
|
||||||
} // namespace compiler
|
} // namespace compiler
|
||||||
} // namespace codegen
|
} // namespace codegen
|
||||||
} // namespace avian
|
} // namespace avian
|
||||||
|
48
src/codegen/compiler/ir.cpp
Normal file
48
src/codegen/compiler/ir.cpp
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/* 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/ir.h"
|
||||||
|
|
||||||
|
namespace avian {
|
||||||
|
namespace codegen {
|
||||||
|
namespace compiler {
|
||||||
|
|
||||||
|
LogicalInstruction::LogicalInstruction(int index, Stack* stack, Local* locals):
|
||||||
|
firstEvent(0), lastEvent(0), immediatePredecessor(0), stack(stack),
|
||||||
|
locals(locals), machineOffset(0), subroutine(0), index(index)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
LogicalInstruction* LogicalInstruction::next(Context* c) {
|
||||||
|
LogicalInstruction* i = this;
|
||||||
|
for (unsigned n = i->index + 1; n < c->logicalCodeLength; ++n) {
|
||||||
|
i = c->logicalCode[n];
|
||||||
|
if (i) return i;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
machineOffset(Context* c, int logicalIp)
|
||||||
|
{
|
||||||
|
return c->logicalCode[logicalIp]->machineOffset->value();
|
||||||
|
}
|
||||||
|
|
||||||
|
Block::Block(Event* head):
|
||||||
|
head(head), nextBlock(0), nextInstruction(0), assemblerBlock(0), start(0)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
Block* block(Context* c, Event* head) {
|
||||||
|
return new(c->zone) Block(head);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace compiler
|
||||||
|
} // namespace codegen
|
||||||
|
} // namespace avian
|
90
src/codegen/compiler/ir.h
Normal file
90
src/codegen/compiler/ir.h
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/* 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_IR_H
|
||||||
|
#define AVIAN_CODEGEN_COMPILER_IR_H
|
||||||
|
|
||||||
|
namespace avian {
|
||||||
|
namespace codegen {
|
||||||
|
namespace compiler {
|
||||||
|
|
||||||
|
class MultiRead;
|
||||||
|
|
||||||
|
class ForkElement {
|
||||||
|
public:
|
||||||
|
Value* value;
|
||||||
|
MultiRead* read;
|
||||||
|
bool local;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ForkState: public Compiler::State {
|
||||||
|
public:
|
||||||
|
ForkState(Stack* stack, Local* locals, Cell<Value>* saved, Event* predecessor,
|
||||||
|
unsigned logicalIp):
|
||||||
|
stack(stack),
|
||||||
|
locals(locals),
|
||||||
|
saved(saved),
|
||||||
|
predecessor(predecessor),
|
||||||
|
logicalIp(logicalIp),
|
||||||
|
readCount(0)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
Stack* stack;
|
||||||
|
Local* locals;
|
||||||
|
Cell<Value>* saved;
|
||||||
|
Event* predecessor;
|
||||||
|
unsigned logicalIp;
|
||||||
|
unsigned readCount;
|
||||||
|
ForkElement elements[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
class LogicalInstruction {
|
||||||
|
public:
|
||||||
|
LogicalInstruction(int index, Stack* stack, Local* locals);
|
||||||
|
|
||||||
|
LogicalInstruction* next(Context* c);
|
||||||
|
|
||||||
|
Event* firstEvent;
|
||||||
|
Event* lastEvent;
|
||||||
|
LogicalInstruction* immediatePredecessor;
|
||||||
|
Stack* stack;
|
||||||
|
Local* locals;
|
||||||
|
Promise* machineOffset;
|
||||||
|
MySubroutine* subroutine;
|
||||||
|
int index;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MySubroutine: public Compiler::Subroutine {
|
||||||
|
public:
|
||||||
|
MySubroutine(): forkState(0) { }
|
||||||
|
|
||||||
|
ForkState* forkState;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Block {
|
||||||
|
public:
|
||||||
|
Block(Event* head);
|
||||||
|
|
||||||
|
Event* head;
|
||||||
|
Block* nextBlock;
|
||||||
|
LogicalInstruction* nextInstruction;
|
||||||
|
Assembler::Block* assemblerBlock;
|
||||||
|
unsigned start;
|
||||||
|
};
|
||||||
|
|
||||||
|
Block* block(Context* c, Event* head);
|
||||||
|
|
||||||
|
unsigned machineOffset(Context* c, int logicalIp);
|
||||||
|
|
||||||
|
} // namespace compiler
|
||||||
|
} // namespace codegen
|
||||||
|
} // namespace avian
|
||||||
|
|
||||||
|
#endif // AVIAN_CODEGEN_COMPILER_IR_H
|
@ -8,8 +8,11 @@
|
|||||||
There is NO WARRANTY for this software. See license.txt for
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
details. */
|
details. */
|
||||||
|
|
||||||
|
#include "target.h"
|
||||||
|
|
||||||
#include "codegen/compiler/context.h"
|
#include "codegen/compiler/context.h"
|
||||||
#include "codegen/compiler/promise.h"
|
#include "codegen/compiler/promise.h"
|
||||||
|
#include "codegen/compiler/ir.h"
|
||||||
|
|
||||||
namespace avian {
|
namespace avian {
|
||||||
namespace codegen {
|
namespace codegen {
|
||||||
@ -51,6 +54,63 @@ Promise* resolvedPromise(Context* c, int64_t value) {
|
|||||||
return new (c->zone) ResolvedPromise(value);
|
return new (c->zone) ResolvedPromise(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class IpPromise: public Promise {
|
||||||
|
public:
|
||||||
|
IpPromise(Context* c, int logicalIp):
|
||||||
|
c(c),
|
||||||
|
logicalIp(logicalIp)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual int64_t value() {
|
||||||
|
if (resolved()) {
|
||||||
|
return reinterpret_cast<intptr_t>
|
||||||
|
(c->machineCode + machineOffset(c, logicalIp));
|
||||||
|
}
|
||||||
|
|
||||||
|
abort(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool resolved() {
|
||||||
|
return c->machineCode != 0
|
||||||
|
and c->logicalCode[logicalIp]->machineOffset->resolved();
|
||||||
|
}
|
||||||
|
|
||||||
|
Context* c;
|
||||||
|
int logicalIp;
|
||||||
|
};
|
||||||
|
|
||||||
|
Promise* ipPromise(Context* c, int logicalIp) {
|
||||||
|
return new (c->zone) IpPromise(c, logicalIp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class PoolPromise: public Promise {
|
||||||
|
public:
|
||||||
|
PoolPromise(Context* c, int key): c(c), key(key) { }
|
||||||
|
|
||||||
|
virtual int64_t value() {
|
||||||
|
if (resolved()) {
|
||||||
|
return reinterpret_cast<int64_t>
|
||||||
|
(c->machineCode + vm::pad(c->machineCodeSize, vm::TargetBytesPerWord)
|
||||||
|
+ (key * vm::TargetBytesPerWord));
|
||||||
|
}
|
||||||
|
|
||||||
|
abort(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool resolved() {
|
||||||
|
return c->machineCode != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Context* c;
|
||||||
|
int key;
|
||||||
|
};
|
||||||
|
|
||||||
|
Promise* poolPromise(Context* c, int key) {
|
||||||
|
return new(c->zone) PoolPromise(c, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace compiler
|
} // namespace compiler
|
||||||
} // namespace codegen
|
} // namespace codegen
|
||||||
} // namespace avian
|
} // namespace avian
|
||||||
|
@ -39,6 +39,10 @@ Promise* combinedPromise(Context* c, Promise* low, Promise* high);
|
|||||||
|
|
||||||
Promise* resolvedPromise(Context* c, int64_t value);
|
Promise* resolvedPromise(Context* c, int64_t value);
|
||||||
|
|
||||||
|
Promise* ipPromise(Context* c, int logicalIp);
|
||||||
|
|
||||||
|
Promise* poolPromise(Context* c, int key);
|
||||||
|
|
||||||
} // namespace compiler
|
} // namespace compiler
|
||||||
} // namespace codegen
|
} // namespace codegen
|
||||||
} // namespace avian
|
} // namespace avian
|
||||||
|
@ -123,6 +123,16 @@ bool Value::uniqueSite(Context* c, Site* s) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Value::clearSites(Context* c) {
|
||||||
|
if (DebugSites) {
|
||||||
|
fprintf(stderr, "clear sites for %p\n", this);
|
||||||
|
}
|
||||||
|
for (SiteIterator it(c, this); it.hasMore();) {
|
||||||
|
it.next();
|
||||||
|
it.remove(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
bool Value::hasBuddy(Context* c, Value* b) {
|
bool Value::hasBuddy(Context* c, Value* b) {
|
||||||
|
@ -60,6 +60,7 @@ class Value: public Compiler::Operand {
|
|||||||
|
|
||||||
bool uniqueSite(Context* c, Site* s);
|
bool uniqueSite(Context* c, Site* s);
|
||||||
|
|
||||||
|
void clearSites(Context* c);
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
bool hasBuddy(Context* c, Value* b);
|
bool hasBuddy(Context* c, Value* b);
|
||||||
|
Loading…
Reference in New Issue
Block a user