further compiler cleanup / organization

This commit is contained in:
Joshua Warner 2013-02-13 23:23:07 -07:00
parent a7ab59f1f6
commit 2db0303e2f
11 changed files with 339 additions and 267 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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