mirror of
https://github.com/corda/corda.git
synced 2025-01-04 04:04:27 +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/promise.cpp \
|
||||
$(src)/codegen/compiler/frame.cpp \
|
||||
$(src)/codegen/compiler/ir.cpp \
|
||||
$(src)/codegen/registers.cpp \
|
||||
$(src)/codegen/targets.cpp
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "codegen/compiler/event.h"
|
||||
#include "codegen/compiler/promise.h"
|
||||
#include "codegen/compiler/frame.h"
|
||||
#include "codegen/compiler/ir.h"
|
||||
|
||||
using namespace vm;
|
||||
|
||||
@ -45,14 +46,6 @@ const unsigned StealRegisterReserveCount = 2;
|
||||
// compare instruction:
|
||||
const unsigned ResolveRegisterReserveCount = (TargetBytesPerWord == 8 ? 2 : 4);
|
||||
|
||||
class Stack;
|
||||
class PushEvent;
|
||||
class Read;
|
||||
class MultiRead;
|
||||
class StubRead;
|
||||
class Block;
|
||||
class Snapshot;
|
||||
|
||||
void
|
||||
apply(Context* c, lir::UnaryOperation op,
|
||||
unsigned s1Size, Site* s1Low, Site* s1High);
|
||||
@ -68,57 +61,6 @@ apply(Context* c, lir::TernaryOperation op,
|
||||
unsigned s2Size, Site* s2Low, Site* s2High,
|
||||
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 {
|
||||
public:
|
||||
@ -128,106 +70,6 @@ class ConstantPoolNode {
|
||||
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*
|
||||
live(Context* c UNUSED, Value* v)
|
||||
{
|
||||
@ -321,7 +163,7 @@ popRead(Context* c, Event* e UNUSED, Value* v)
|
||||
if (r) {
|
||||
deadBuddy(c, v, r);
|
||||
} else {
|
||||
clearSites(c, v);
|
||||
v->clearSites(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1140,11 +982,11 @@ removeBuddy(Context* c, Value* v)
|
||||
assert(c, p->buddy);
|
||||
|
||||
if (not live(c, next)) {
|
||||
clearSites(c, next);
|
||||
next->clearSites(c);
|
||||
}
|
||||
|
||||
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();
|
||||
// fprintf(stderr, "next read %p for %p from %p\n", v->reads, v, p->read);
|
||||
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));
|
||||
}
|
||||
|
||||
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
|
||||
append(Context* c, Event* e)
|
||||
{
|
||||
@ -1898,11 +1679,11 @@ resetFrame(Context* c, Event* e)
|
||||
{
|
||||
for (FrameIterator it(c, e->stackBefore, e->localsBefore); it.hasMore();) {
|
||||
FrameIterator::Element el = it.next(c);
|
||||
clearSites(c, el.value);
|
||||
el.value->clearSites(c);
|
||||
}
|
||||
|
||||
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
|
||||
compile(Context* c, uintptr_t stackOverflowHandler, unsigned stackLimitOffset)
|
||||
{
|
||||
@ -2110,8 +1862,8 @@ compile(Context* c, uintptr_t stackOverflowHandler, unsigned stackLimitOffset)
|
||||
fprintf(stderr,
|
||||
" -- compile %s at %d with %d preds %d succs %d stack\n",
|
||||
e->name(), e->logicalInstruction->index,
|
||||
countPredecessors(e->predecessors),
|
||||
countSuccessors(e->successors),
|
||||
e->predecessors->countPredecessors(),
|
||||
e->successors->countSuccessors(),
|
||||
e->stackBefore ? e->stackBefore->index + 1 : 0);
|
||||
}
|
||||
|
||||
@ -2125,7 +1877,7 @@ compile(Context* c, uintptr_t stackOverflowHandler, unsigned stackLimitOffset)
|
||||
}
|
||||
|
||||
if (e->predecessors) {
|
||||
visit(c, lastPredecessor(e->predecessors));
|
||||
visit(c, e->predecessors->lastPredecessor());
|
||||
|
||||
Event* first = e->predecessors->predecessor;
|
||||
if (e->predecessors->nextPredecessor) {
|
||||
@ -2191,7 +1943,7 @@ compile(Context* c, uintptr_t stackOverflowHandler, unsigned stackLimitOffset)
|
||||
|
||||
a->endEvent();
|
||||
|
||||
LogicalInstruction* nextInstruction = next(c, e->logicalInstruction);
|
||||
LogicalInstruction* nextInstruction = e->logicalInstruction->next(c);
|
||||
if (e->next == 0
|
||||
or (e->next->logicalInstruction != e->logicalInstruction
|
||||
and (e->next->logicalInstruction != nextInstruction
|
||||
@ -2433,9 +2185,7 @@ class MyCompiler: public Compiler {
|
||||
|
||||
memset(c.locals, 0, sizeof(Local) * localFootprint);
|
||||
|
||||
c.logicalCode[-1] = new
|
||||
(c.zone->allocate(sizeof(LogicalInstruction)))
|
||||
LogicalInstruction(-1, c.stack, c.locals);
|
||||
c.logicalCode[-1] = new(c.zone) LogicalInstruction(-1, c.stack, c.locals);
|
||||
}
|
||||
|
||||
virtual void visitLogicalIp(unsigned logicalIp) {
|
||||
@ -2494,9 +2244,7 @@ class MyCompiler: public Compiler {
|
||||
p->localsAfter = c.locals;
|
||||
}
|
||||
|
||||
c.logicalCode[logicalIp] = new
|
||||
(c.zone->allocate(sizeof(LogicalInstruction)))
|
||||
LogicalInstruction(logicalIp, c.stack, c.locals);
|
||||
c.logicalCode[logicalIp] = new(c.zone) LogicalInstruction(logicalIp, c.stack, c.locals);
|
||||
|
||||
bool startSubroutine = c.subroutine != 0;
|
||||
if (startSubroutine) {
|
||||
@ -2525,7 +2273,7 @@ class MyCompiler: public Compiler {
|
||||
}
|
||||
|
||||
virtual Promise* machineIp(unsigned logicalIp) {
|
||||
return new(c.zone) IpPromise(&c, logicalIp);
|
||||
return ipPromise(&c, logicalIp);
|
||||
}
|
||||
|
||||
virtual Promise* poolAppend(intptr_t value) {
|
||||
@ -2533,7 +2281,7 @@ class MyCompiler: public Compiler {
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
@ -54,6 +54,18 @@ unsigned count(Cell<T>* c) {
|
||||
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 {
|
||||
public:
|
||||
Context(vm::System* system, Assembler* assembler, vm::Zone* zone,
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "codegen/compiler/value.h"
|
||||
#include "codegen/compiler/promise.h"
|
||||
#include "codegen/compiler/frame.h"
|
||||
#include "codegen/compiler/ir.h"
|
||||
|
||||
namespace avian {
|
||||
namespace codegen {
|
||||
@ -148,6 +149,32 @@ bool Event::isUnreachable() {
|
||||
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* nextSuccessor, ForkState* forkState)
|
||||
{
|
||||
@ -1605,6 +1632,67 @@ appendFrameSite(Context* c, Value* value, int 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 codegen
|
||||
} // namespace avian
|
||||
|
@ -97,6 +97,10 @@ class Link {
|
||||
junctionState(0)
|
||||
{ }
|
||||
|
||||
unsigned countPredecessors();
|
||||
Link* lastPredecessor();
|
||||
unsigned countSuccessors();
|
||||
|
||||
Event* predecessor;
|
||||
Link* nextPredecessor;
|
||||
Event* successor;
|
||||
@ -154,6 +158,12 @@ appendBoundsCheck(Context* c, Value* object, unsigned lengthOffset,
|
||||
void
|
||||
appendFrameSite(Context* c, Value* value, int index);
|
||||
|
||||
void
|
||||
appendSaveLocals(Context* c);
|
||||
|
||||
void
|
||||
appendDummy(Context* c);
|
||||
|
||||
} // namespace compiler
|
||||
} // namespace codegen
|
||||
} // 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
|
||||
details. */
|
||||
|
||||
#include "target.h"
|
||||
|
||||
#include "codegen/compiler/context.h"
|
||||
#include "codegen/compiler/promise.h"
|
||||
#include "codegen/compiler/ir.h"
|
||||
|
||||
namespace avian {
|
||||
namespace codegen {
|
||||
@ -51,6 +54,63 @@ Promise* resolvedPromise(Context* c, int64_t 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 codegen
|
||||
} // namespace avian
|
||||
|
@ -39,6 +39,10 @@ Promise* combinedPromise(Context* c, Promise* low, Promise* high);
|
||||
|
||||
Promise* resolvedPromise(Context* c, int64_t value);
|
||||
|
||||
Promise* ipPromise(Context* c, int logicalIp);
|
||||
|
||||
Promise* poolPromise(Context* c, int key);
|
||||
|
||||
} // namespace compiler
|
||||
} // namespace codegen
|
||||
} // 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
|
||||
bool Value::hasBuddy(Context* c, Value* b) {
|
||||
|
@ -60,6 +60,7 @@ class Value: public Compiler::Operand {
|
||||
|
||||
bool uniqueSite(Context* c, Site* s);
|
||||
|
||||
void clearSites(Context* c);
|
||||
|
||||
#ifndef NDEBUG
|
||||
bool hasBuddy(Context* c, Value* b);
|
||||
|
Loading…
Reference in New Issue
Block a user