mirror of
https://github.com/corda/corda.git
synced 2025-02-14 14:42:32 +00:00
more work on design sketch of new compiler
This commit is contained in:
parent
525f733171
commit
f85510c4c4
304
src/compiler.cpp
304
src/compiler.cpp
@ -16,11 +16,240 @@ using namespace vm;
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
class Context;
|
class Context;
|
||||||
|
class Value;
|
||||||
|
|
||||||
void NO_RETURN abort(Context* c);
|
void NO_RETURN abort(Context*);
|
||||||
|
|
||||||
// scratch
|
// scratch
|
||||||
|
|
||||||
|
class Site {
|
||||||
|
public:
|
||||||
|
Site(): next(0) { }
|
||||||
|
|
||||||
|
virtual ~Site() { }
|
||||||
|
|
||||||
|
virtual unsigned copyCost(Context*, Site*) = 0;
|
||||||
|
|
||||||
|
virtual void copyTo(Context*, unsigned, Site*) = 0;
|
||||||
|
|
||||||
|
virtual void acquire(Context*, unsigned, Value*, Site*) { }
|
||||||
|
|
||||||
|
virtual void asAssemblerOperand(Context*,
|
||||||
|
OperandType* type,
|
||||||
|
Assembler::Operand** operand) = 0;
|
||||||
|
|
||||||
|
Site* next;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ConstantSite: public Site {
|
||||||
|
public:
|
||||||
|
ConstantSite(Promise* value): value(value) { }
|
||||||
|
|
||||||
|
virtual unsigned copyCost(Context*, Site*) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void copyTo(Context* c, unsigned size, Site* dst) {
|
||||||
|
apply(c, Move, size, this, dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual OperandType type(Context*) {
|
||||||
|
return Constant;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Assembler::Operand* asAssemblerOperand(Context*) {
|
||||||
|
return &value;
|
||||||
|
}
|
||||||
|
|
||||||
|
Assembler::Constant value;
|
||||||
|
};
|
||||||
|
|
||||||
|
ConstantSite*
|
||||||
|
constantSite(Context* c, Promise* value)
|
||||||
|
{
|
||||||
|
return new (c->zone->allocate(sizeof(ConstantSite))) ConstantSite(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResolvedPromise*
|
||||||
|
resolved(Context* c, int64_t value)
|
||||||
|
{
|
||||||
|
return new (c->zone->allocate(sizeof(ResolvedPromise)))
|
||||||
|
ResolvedPromise(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstantSite*
|
||||||
|
constantSite(Context* c, int64_t value)
|
||||||
|
{
|
||||||
|
return constantSite(c, resolved(c, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
class AddressSite: public Site {
|
||||||
|
public:
|
||||||
|
AddressSite(Promise* address): address(address) { }
|
||||||
|
|
||||||
|
virtual unsigned copyCost(Context*, Site*) {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void copyTo(Context* c, unsigned size, Site* dst) {
|
||||||
|
apply(c, Move, size, this, dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual OperandType type(Context*) {
|
||||||
|
return Address;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Assembler::Operand* asAssemblerOperand(Context*) {
|
||||||
|
return &address;
|
||||||
|
}
|
||||||
|
|
||||||
|
Assembler::Address address;
|
||||||
|
};
|
||||||
|
|
||||||
|
AddressSite*
|
||||||
|
addressSite(Context* c, Promise* address)
|
||||||
|
{
|
||||||
|
return new (c->zone->allocate(sizeof(AddressSite))) AddressSite(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
acquire(Context* c, int r, unsigned newSize, Value* newValue, Site* newSite)
|
||||||
|
{
|
||||||
|
Value* oldValue = c->registers[r].value;
|
||||||
|
if (oldValue) {
|
||||||
|
for (Site** p = &(oldValue->sites); *p;) {
|
||||||
|
if (c->registers[r].site == *p) {
|
||||||
|
site = *p;
|
||||||
|
*p = (*p)->next;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
p = &((*p)->next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (old->sites == 0 and old->reads) {
|
||||||
|
apply(c, Push, c->registers[r].size, c->registers[r].site);
|
||||||
|
old->sites = ???;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c->registers[r].size = newSize;
|
||||||
|
c->registers[r].value = newValue;
|
||||||
|
c->registers[r].site = newSite;
|
||||||
|
}
|
||||||
|
|
||||||
|
class RegisterSite: public Site {
|
||||||
|
public:
|
||||||
|
RegisterSite(int low, int high): register_(low, high) { }
|
||||||
|
|
||||||
|
virtual unsigned copyCost(Context* c, Site* s) {
|
||||||
|
if (s and
|
||||||
|
(this == s or
|
||||||
|
(s->type(c) == Register
|
||||||
|
and static_cast<RegisterSite*>(s)->register_.low
|
||||||
|
== register_.low
|
||||||
|
and static_cast<RegisterSite*>(s)->register_.high
|
||||||
|
== register_.high)))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void copyTo(Context* c, unsigned size, Site* dst) {
|
||||||
|
apply(c, Move, size, this, dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void acquire(Context* c, unsigned size, Value* v, Site* s) {
|
||||||
|
::acquire(c, register_.low, size, v, s);
|
||||||
|
if (register_.high >= 0) ::acquire(c, register_.high, size, v, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual OperandType type(Context*) {
|
||||||
|
return Register;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Assembler::Operand* asAssemblerOperand(Context*) {
|
||||||
|
return ®ister_;
|
||||||
|
}
|
||||||
|
|
||||||
|
Assembler::Register register_;
|
||||||
|
};
|
||||||
|
|
||||||
|
RegisterSite*
|
||||||
|
registerSite(Context* c, int low, int high = NoRegister)
|
||||||
|
{
|
||||||
|
return new (c->zone->allocate(sizeof(RegisterSite)))
|
||||||
|
RegisterSite(low, high);
|
||||||
|
}
|
||||||
|
|
||||||
|
class MemorySite: public Site {
|
||||||
|
public:
|
||||||
|
RegisterSite(int base, int offset, int index, unsigned scale):
|
||||||
|
value(base, offset, index, scale)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual unsigned copyCost(Context* c, Site* s) {
|
||||||
|
if (s and
|
||||||
|
(this == s or
|
||||||
|
(o->type(c) == Memory
|
||||||
|
and static_cast<MemorySite*>(o)->value.base == value.base
|
||||||
|
and static_cast<MemorySite*>(o)->value.offset == value.offset
|
||||||
|
and static_cast<MemorySite*>(o)->value.index == value.index
|
||||||
|
and static_cast<MemorySite*>(o)->value.scale == value.scale)))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void copyTo(Context* c, unsigned size, Site* dst) {
|
||||||
|
apply(c, Move, size, this, dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual OperandType type(Context*) {
|
||||||
|
return Memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Assembler::Operand* asAssemblerOperand(Context*) {
|
||||||
|
return &value;
|
||||||
|
}
|
||||||
|
|
||||||
|
Assembler::Memory value;
|
||||||
|
};
|
||||||
|
|
||||||
|
MemorySite*
|
||||||
|
memorySite(Context* c, int base, int offset, int index, unsigned scale)
|
||||||
|
{
|
||||||
|
return new (c->zone->allocate(sizeof(MemorySite)))
|
||||||
|
MemorySite(base, offset, index, scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Read {
|
||||||
|
public:
|
||||||
|
Read(unsigned size, Value* value, Site* target):
|
||||||
|
size(size), value(value), target(target), next(0)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
unsigned size;
|
||||||
|
Value* value;
|
||||||
|
Site* target;
|
||||||
|
Read* next;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Write {
|
||||||
|
public:
|
||||||
|
Write(unsigned size, Value* value):
|
||||||
|
size(size), value(value), next(0)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
unsigned size;
|
||||||
|
Value* value;
|
||||||
|
Write* next;
|
||||||
|
};
|
||||||
|
|
||||||
class Value: public Compiler::Operand {
|
class Value: public Compiler::Operand {
|
||||||
public:
|
public:
|
||||||
Value(Site* site):
|
Value(Site* site):
|
||||||
@ -142,9 +371,9 @@ class ReturnEvent: public Event {
|
|||||||
{
|
{
|
||||||
if (value) {
|
if (value) {
|
||||||
addRead(c, value, size, registerSite
|
addRead(c, value, size, registerSite
|
||||||
(c, c->assembler->returnLow(),
|
(c, c->assembler->returnLow(),
|
||||||
size > BytesPerWord ?
|
size > BytesPerWord ?
|
||||||
c->assembler->returnHigh() : NoRegister));
|
c->assembler->returnHigh() : NoRegister));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,30 +479,6 @@ appendBranch(Context* c, UnaryOperation type, Value* address)
|
|||||||
new (c->zone->allocate(sizeof(BranchEvent))) BranchEvent(c, type, address);
|
new (c->zone->allocate(sizeof(BranchEvent))) BranchEvent(c, type, address);
|
||||||
}
|
}
|
||||||
|
|
||||||
class JumpEvent: public Event {
|
|
||||||
public:
|
|
||||||
JumpEvent(Context* c, Value* address):
|
|
||||||
Event(c),
|
|
||||||
address(address)
|
|
||||||
{
|
|
||||||
addRead(c, address, BytesPerWord, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void compile(Context* c) {
|
|
||||||
fprintf(stderr, "JumpEvent.compile\n");
|
|
||||||
|
|
||||||
apply(c, Jump, BytesPerWord, address->source);
|
|
||||||
}
|
|
||||||
|
|
||||||
Value* address;
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
|
||||||
appendJump(Context* c, Value* address)
|
|
||||||
{
|
|
||||||
new (c->zone->allocate(sizeof(JumpEvent))) JumpEvent(c, address);
|
|
||||||
}
|
|
||||||
|
|
||||||
class CombineEvent: public Event {
|
class CombineEvent: public Event {
|
||||||
public:
|
public:
|
||||||
CombineEvent(Context* c, BinaryOperation type, unsigned size, Value* first,
|
CombineEvent(Context* c, BinaryOperation type, unsigned size, Value* first,
|
||||||
@ -370,6 +575,13 @@ appendMemory(Context* c, Value* base, Value* index, Value* result)
|
|||||||
MemoryEvent(c, base, index, result);
|
MemoryEvent(c, base, index, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
addSite(Context* c, int size, Value* v, Site* s)
|
||||||
|
{
|
||||||
|
s->acquire(c, size, v, s);
|
||||||
|
s->next = v->sites;
|
||||||
|
v->sites = s;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
compile(Context* c)
|
compile(Context* c)
|
||||||
@ -390,6 +602,42 @@ compile(Context* c)
|
|||||||
LogicalInstruction* li = c->logicalCode + e->logicalIp;
|
LogicalInstruction* li = c->logicalCode + e->logicalIp;
|
||||||
li->machineOffset = a->length();
|
li->machineOffset = a->length();
|
||||||
|
|
||||||
|
for (Read* r = e->reads; r; r = r->next) {
|
||||||
|
Site* site = 0;
|
||||||
|
unsigned copyCost = Site::MaxCopyCost;
|
||||||
|
for (Site* s = r->value->sites; s; s = s->next) {
|
||||||
|
unsigned c = s->copyCost(c, r->target);
|
||||||
|
if (c < copyCost) {
|
||||||
|
site = s;
|
||||||
|
copyCost = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r->target) {
|
||||||
|
if (copyCost) {
|
||||||
|
addSite(c, r->size, r->value, r->target);
|
||||||
|
|
||||||
|
site->copyTo(c, r->size, r->target);
|
||||||
|
}
|
||||||
|
|
||||||
|
r->value->source = r->target;
|
||||||
|
} else {
|
||||||
|
r->value->source = site;
|
||||||
|
}
|
||||||
|
|
||||||
|
r->value->reads = r->value->reads->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Write* w = e->writes; w; w = w->next) {
|
||||||
|
if (w->value->reads and w->value->reads->target) {
|
||||||
|
w->value->target = w->value->reads->target;
|
||||||
|
} else {
|
||||||
|
w->value->target = freeRegister(c, w->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
addSite(c, w->size, w->value, w->value->target);
|
||||||
|
}
|
||||||
|
|
||||||
e->compile(c);
|
e->compile(c);
|
||||||
|
|
||||||
for (CodePromise* p = e->promises; p; p = p->next) {
|
for (CodePromise* p = e->promises; p; p = p->next) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user